{
  "schemaVersion": "2.0.0",
  "package": {
    "name": "fintech-algorithms",
    "version": "0.13.2",
    "homepage": "https://docs.thefintechbuilder.com",
    "license": "MIT",
    "type": "module",
    "engines": {
      "node": ">=22.12"
    },
    "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": 717,
    "domains": 19,
    "families": 90,
    "verified": 623,
    "withExample": 717,
    "withDiagram": 717,
    "withApiContract": 717
  },
  "archetypes": [
    {
      "name": "series-transform",
      "topicCount": 137,
      "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": 24,
      "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": 543,
      "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": "D00",
      "name": "Financial Mathematics, Statistics, and Data Foundations",
      "slug": "foundations",
      "topicCount": 120,
      "families": [
        {
          "id": "D00-F01",
          "name": "Mathematical Language and Quantitative Reasoning",
          "topicCount": 10
        },
        {
          "id": "D00-F02",
          "name": "Financial Arithmetic, Time Value, and Returns",
          "topicCount": 10
        },
        {
          "id": "D00-F03",
          "name": "Data, Variables, Samples, and Measurement",
          "topicCount": 10
        },
        {
          "id": "D00-F04",
          "name": "Location, Ranking, and Exploratory Summaries",
          "topicCount": 10
        },
        {
          "id": "D00-F05",
          "name": "Dispersion, Shape, and Robust Statistics",
          "topicCount": 10
        },
        {
          "id": "D00-F06",
          "name": "Probability and Random Variables",
          "topicCount": 10
        },
        {
          "id": "D00-F07",
          "name": "Probability Distributions and Simulation Basics",
          "topicCount": 10
        },
        {
          "id": "D00-F08",
          "name": "Sampling, Estimation, and Statistical Inference",
          "topicCount": 10
        },
        {
          "id": "D00-F09",
          "name": "Dependence, Regression, and Model Foundations",
          "topicCount": 10
        },
        {
          "id": "D00-F10",
          "name": "Financial Time-Series Foundations",
          "topicCount": 10
        },
        {
          "id": "D00-F11",
          "name": "Financial Risk and Performance Statistics",
          "topicCount": 10
        },
        {
          "id": "D00-F12",
          "name": "Statistical Computing and Reproducibility",
          "topicCount": 10
        }
      ]
    },
    {
      "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": 52,
      "families": [
        {
          "id": "D06-F01",
          "name": "Candle Foundations",
          "topicCount": 5
        },
        {
          "id": "D06-F02",
          "name": "Single-Candle Patterns",
          "topicCount": 13
        },
        {
          "id": "D06-F03",
          "name": "Two-Candle Patterns",
          "topicCount": 12
        },
        {
          "id": "D06-F04",
          "name": "Multi-Candle Patterns",
          "topicCount": 13
        },
        {
          "id": "D06-F05",
          "name": "Candlestick Scanning and Context",
          "topicCount": 9
        }
      ]
    },
    {
      "id": "D07",
      "name": "Technical Indicators",
      "slug": "technical-indicators",
      "topicCount": 137,
      "families": [
        {
          "id": "D07-F01",
          "name": "Trend Smoothing",
          "topicCount": 24
        },
        {
          "id": "D07-F02",
          "name": "Trend Systems",
          "topicCount": 19
        },
        {
          "id": "D07-F03",
          "name": "Momentum",
          "topicCount": 30
        },
        {
          "id": "D07-F04",
          "name": "Volatility and Channels",
          "topicCount": 6
        },
        {
          "id": "D07-F05",
          "name": "Volume Indicators",
          "topicCount": 21
        },
        {
          "id": "D07-F06",
          "name": "Range and Volatility Indicators",
          "topicCount": 12
        },
        {
          "id": "D07-F07",
          "name": "Bands, Envelopes, and Squeezes",
          "topicCount": 13
        },
        {
          "id": "D07-F08",
          "name": "Price Transforms",
          "topicCount": 8
        },
        {
          "id": "D07-F09",
          "name": "Rolling Statistical Indicators",
          "topicCount": 4
        }
      ]
    },
    {
      "id": "D08",
      "name": "Geometric Chart Patterns",
      "slug": "geometric-chart-patterns",
      "topicCount": 64,
      "families": [
        {
          "id": "D08-F01",
          "name": "Pivots and Levels",
          "topicCount": 13
        },
        {
          "id": "D08-F02",
          "name": "Reversal Structures",
          "topicCount": 6
        },
        {
          "id": "D08-F03",
          "name": "Continuation Structures",
          "topicCount": 6
        },
        {
          "id": "D08-F04",
          "name": "Pattern Matching",
          "topicCount": 4
        },
        {
          "id": "D08-F05",
          "name": "Indicator Divergence Detection",
          "topicCount": 8
        },
        {
          "id": "D08-F06",
          "name": "Level Confluence and Zone Scoring",
          "topicCount": 9
        },
        {
          "id": "D08-F07",
          "name": "Market Structure, Breakouts, and Regimes",
          "topicCount": 18
        }
      ]
    },
    {
      "id": "D09",
      "name": "Statistical Time Series",
      "slug": "statistical-time-series",
      "topicCount": 37,
      "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": "D09-F06",
          "name": "Hilbert and Ehlers Cycle Analytics",
          "topicCount": 8
        }
      ]
    },
    {
      "id": "D10",
      "name": "Volatility and Covariance",
      "slug": "volatility-and-covariance",
      "topicCount": 22,
      "families": [
        {
          "id": "D10-F01",
          "name": "Historical Estimators",
          "topicCount": 5
        },
        {
          "id": "D10-F02",
          "name": "Realized Measures",
          "topicCount": 5
        },
        {
          "id": "D10-F03",
          "name": "Conditional Volatility",
          "topicCount": 6
        },
        {
          "id": "D10-F04",
          "name": "Covariance Estimation",
          "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": "D14",
      "name": "Portfolio Construction",
      "slug": "portfolio-construction",
      "topicCount": 20,
      "families": [
        {
          "id": "D14-F01",
          "name": "Mean-Risk Optimization",
          "topicCount": 5
        },
        {
          "id": "D14-F02",
          "name": "Risk Allocation",
          "topicCount": 5
        },
        {
          "id": "D14-F03",
          "name": "Bayesian and Robust Allocation",
          "topicCount": 5
        },
        {
          "id": "D14-F04",
          "name": "Practical Constraints",
          "topicCount": 5
        }
      ]
    },
    {
      "id": "D18",
      "name": "Fundamental Analysis and Valuation",
      "slug": "fundamental-analysis-and-valuation",
      "topicCount": 52,
      "families": [
        {
          "id": "D18-F01",
          "name": "Statement Ratios",
          "topicCount": 6
        },
        {
          "id": "D18-F02",
          "name": "Intrinsic Valuation",
          "topicCount": 5
        },
        {
          "id": "D18-F03",
          "name": "Relative Valuation",
          "topicCount": 5
        },
        {
          "id": "D18-F04",
          "name": "Quality and Distress",
          "topicCount": 13
        },
        {
          "id": "D18-F09",
          "name": "Integrated Equity Scoring",
          "topicCount": 14
        },
        {
          "id": "D18-F10",
          "name": "Sector-Specific Equity Scoring",
          "topicCount": 9
        }
      ]
    },
    {
      "id": "D21",
      "name": "Credit Risk and Default",
      "slug": "credit-risk-and-default",
      "topicCount": 7,
      "families": [
        {
          "id": "D21-F01",
          "name": "Probability of Default",
          "topicCount": 7
        }
      ]
    },
    {
      "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": "D40",
      "name": "Model Validation and Backtesting",
      "slug": "model-validation-and-backtesting",
      "topicCount": 10,
      "families": [
        {
          "id": "D40-F05",
          "name": "Classification and Score Validation",
          "topicCount": 10
        }
      ]
    },
    {
      "id": "D46",
      "name": "Earnings and Per-Share Analytics",
      "slug": "earnings-and-per-share-analytics",
      "topicCount": 8,
      "families": [
        {
          "id": "D46-F01",
          "name": "Earnings and Share Foundations",
          "topicCount": 4
        },
        {
          "id": "D46-F02",
          "name": "Basic and Diluted EPS",
          "topicCount": 4
        }
      ]
    }
  ],
  "topics": [
    {
      "id": "D00-F01-A01",
      "name": "Variables, Constants, Expressions, and Equations",
      "headline": null,
      "slug": "variables-constants-expressions-and-equations",
      "path": "foundations/mathematical-language-and-quantitative-reasoning/variables-constants-expressions-and-equations",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F01",
        "family": "Mathematical Language and Quantitative Reasoning",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/mathematical-language-and-quantitative-reasoning/variables-constants-expressions-and-equations",
        "entry": "variablesConstantsExpressionsAndEquations",
        "params": [
          "input"
        ],
        "exports": [
          "variablesConstantsExpressionsAndEquations"
        ],
        "archetype": "record-transform",
        "signature": "variablesConstantsExpressionsAndEquations(input)"
      },
      "api": {
        "summary": "Substitutes named quantities into a cash-balance equation and checks that the rearranged form still holds, returning the ending cash implied by `startingCash`, `inflows` and `outflows`.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F01 topic first reads `values`, which must be a non-empty array of finite numbers, and validates it before any per-topic branch runs. This topic then reads `startingCash`, `inflows` and `outflows`, each coerced with `Number`; `values` is demanded but not used by this calculation.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ endingCash: number; balances: boolean }",
          "description": "`endingCash` is `startingCash + inflows - outflows`. `balances` is true when moving the three terms back across the equals sign lands within 1e-12 of zero, which it does for any finite input."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "values is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          },
          {
            "when": "values contains a value that is not a finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F01-A01.json",
        "call": "variablesConstantsExpressionsAndEquations({\"values\":[1,2,3,4,5],\"startingCash\":1000,\"inflows\":250,\"outflows\":120,\"slope\":2,\"intercept\":1,\"part\":25,\"whole\":200,\"elapsed\":5,\"old\":4.5,\"new\":4.75,\"base\":16,\"exponent\":0.5,\"a\":2})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "startingCash": 1000,
              "inflows": 250,
              "outflows": 120,
              "slope": 2,
              "intercept": 1,
              "part": 25,
              "whole": 200,
              "elapsed": 5,
              "old": 4.5,
              "new": 4.75,
              "base": 16,
              "exponent": 0.5,
              "a": 2
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 28
            }
          }
        ],
        "output": {
          "endingCash": 1130,
          "balances": true
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: endingCash, balances"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a01/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a01/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a01/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Variables, Constants, Expressions, and Equations — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: ending cash = starting cash + inflows - outflows\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST",
          "title": "NIST/SEMATECH e-Handbook of Statistical Methods",
          "author": "NIST/SEMATECH",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/mathematical-language-and-quantitative-reasoning/variables-constants-expressions-and-equations/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/mathematical-language-and-quantitative-reasoning/variables-constants-expressions-and-equations/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F01-A02",
      "name": "Functions, Domains, Ranges, and Graphs",
      "headline": null,
      "slug": "functions-domains-ranges-and-graphs",
      "path": "foundations/mathematical-language-and-quantitative-reasoning/functions-domains-ranges-and-graphs",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F01",
        "family": "Mathematical Language and Quantitative Reasoning",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/mathematical-language-and-quantitative-reasoning/functions-domains-ranges-and-graphs",
        "entry": "functionsDomainsRangesAndGraphs",
        "params": [
          "input"
        ],
        "exports": [
          "functionsDomainsRangesAndGraphs"
        ],
        "archetype": "record-transform",
        "signature": "functionsDomainsRangesAndGraphs(input)"
      },
      "api": {
        "summary": "Evaluates the straight-line function `intercept + slope * value` at every entry of `values` and reports the input span it was evaluated over alongside the output span it produced.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F01 topic first reads `values`, which must be a non-empty array of finite numbers, and validates it before any per-topic branch runs. This topic then reads `intercept` and `slope`, both coerced with `Number`, and uses `values` as the points at which the function is evaluated.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ domain: [number, number]; range: [number, number]; outputs: number[] }",
          "description": "`domain` is the smallest and largest entry of `values`, `range` the smallest and largest of the computed outputs, and `outputs` the value of the function at each input, in input order."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "values is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          },
          {
            "when": "values contains a value that is not a finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F01-A02.json",
        "call": "functionsDomainsRangesAndGraphs({\"values\":[1,2,3,4,5],\"startingCash\":1000,\"inflows\":250,\"outflows\":120,\"slope\":2,\"intercept\":1,\"part\":25,\"whole\":200,\"elapsed\":5,\"old\":4.5,\"new\":4.75,\"base\":16,\"exponent\":0.5,\"a\":2})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "startingCash": 1000,
              "inflows": 250,
              "outflows": 120,
              "slope": 2,
              "intercept": 1,
              "part": 25,
              "whole": 200,
              "elapsed": 5,
              "old": 4.5,
              "new": 4.75,
              "base": 16,
              "exponent": 0.5,
              "a": 2
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 28
            }
          }
        ],
        "output": {
          "domain": [
            1,
            5
          ],
          "range": [
            3,
            11
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: domain, range"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a02/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a02/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a02/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Functions, Domains, Ranges, and Graphs — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: fee(amount) = fixed fee + (rate / 100) × amount\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "OPENSTAX",
          "title": "College Algebra: Domain and Range",
          "author": "OpenStax",
          "url": null
        },
        {
          "key": "NIST",
          "title": "NIST/SEMATECH e-Handbook of Statistical Methods",
          "author": "NIST/SEMATECH",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/mathematical-language-and-quantitative-reasoning/functions-domains-ranges-and-graphs/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/mathematical-language-and-quantitative-reasoning/functions-domains-ranges-and-graphs/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F01-A03",
      "name": "Ratios, Proportions, Rates, and Percentages",
      "headline": null,
      "slug": "ratios-proportions-rates-and-percentages",
      "path": "foundations/mathematical-language-and-quantitative-reasoning/ratios-proportions-rates-and-percentages",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F01",
        "family": "Mathematical Language and Quantitative Reasoning",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/mathematical-language-and-quantitative-reasoning/ratios-proportions-rates-and-percentages",
        "entry": "ratiosProportionsRatesAndPercentages",
        "params": [
          "input"
        ],
        "exports": [
          "ratiosProportionsRatesAndPercentages"
        ],
        "archetype": "record-transform",
        "signature": "ratiosProportionsRatesAndPercentages(input)"
      },
      "api": {
        "summary": "Turns a part-and-whole pair into a ratio and a percentage, and turns the same part spread over an elapsed span into a rate per period.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F01 topic first reads `values`, which must be a non-empty array of finite numbers, and validates it before any per-topic branch runs. This topic then reads `part`, `whole` and `elapsed`, each coerced with `Number`; `values` is demanded but not used by this calculation.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ratio: number; percentage: number; ratePerPeriod: number }",
          "description": "`ratio` is `part / whole`, `percentage` is that ratio times 100, and `ratePerPeriod` is `part / elapsed`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "values is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          },
          {
            "when": "values contains a value that is not a finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "whole is zero, or elapsed is zero or negative",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F01-A03.json",
        "call": "ratiosProportionsRatesAndPercentages({\"values\":[1,2,3,4,5],\"startingCash\":1000,\"inflows\":250,\"outflows\":120,\"slope\":2,\"intercept\":1,\"part\":350,\"whole\":500,\"elapsed\":25,\"old\":4.5,\"new\":4.75,\"base\":16,\"exponent\":0.5,\"a\":2})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "startingCash": 1000,
              "inflows": 250,
              "outflows": 120,
              "slope": 2,
              "intercept": 1,
              "part": 350,
              "whole": 500,
              "elapsed": 25,
              "old": 4.5,
              "new": 4.75,
              "base": 16,
              "exponent": 0.5,
              "a": 2
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 28
            }
          }
        ],
        "output": {
          "ratio": 0.7,
          "percentage": 70,
          "ratePerPeriod": 14
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: ratio, percentage, ratePerPeriod"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a03/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a03/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a03/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Ratios, Proportions, Rates, and Percentages — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: expense share = expenses / revenue; cost per customer = expenses / customers\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST",
          "title": "NIST/SEMATECH e-Handbook of Statistical Methods",
          "author": "NIST/SEMATECH",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/mathematical-language-and-quantitative-reasoning/ratios-proportions-rates-and-percentages/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/mathematical-language-and-quantitative-reasoning/ratios-proportions-rates-and-percentages/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F01-A04",
      "name": "Percentage Change, Percentage Points, and Basis Points",
      "headline": null,
      "slug": "percentage-change-percentage-points-and-basis-points",
      "path": "foundations/mathematical-language-and-quantitative-reasoning/percentage-change-percentage-points-and-basis-points",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F01",
        "family": "Mathematical Language and Quantitative Reasoning",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/mathematical-language-and-quantitative-reasoning/percentage-change-percentage-points-and-basis-points",
        "entry": "percentageChangePercentagePointsAndBasisPoints",
        "params": [
          "input"
        ],
        "exports": [
          "percentageChangePercentagePointsAndBasisPoints"
        ],
        "archetype": "record-transform",
        "signature": "percentageChangePercentagePointsAndBasisPoints(input)"
      },
      "api": {
        "summary": "Expresses the move from an old level to a new one three ways: as a percent change relative to the old level, as a raw difference in percentage points, and as that difference scaled to basis points.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F01 topic first reads `values`, which must be a non-empty array of finite numbers, and validates it before any per-topic branch runs. This topic then reads `old` and `new`, both coerced with `Number`; `values` is demanded but not used by this calculation.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ percentageChange: number; percentagePoints: number; basisPoints: number }",
          "description": "`percentageChange` is `100 * (new - old) / Math.abs(old)`, so the sign follows the direction of the move even when `old` is negative. `percentagePoints` is the plain difference `new - old`, and `basisPoints` is that same difference multiplied by 100."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "values is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          },
          {
            "when": "values contains a value that is not a finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "old is zero",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F01-A04.json",
        "call": "percentageChangePercentagePointsAndBasisPoints({\"values\":[1,2,3,4,5],\"startingCash\":1000,\"inflows\":250,\"outflows\":120,\"slope\":2,\"intercept\":1,\"part\":25,\"whole\":200,\"elapsed\":5,\"old\":4.5,\"new\":4.75,\"base\":16,\"exponent\":0.5,\"a\":2})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "startingCash": 1000,
              "inflows": 250,
              "outflows": 120,
              "slope": 2,
              "intercept": 1,
              "part": 25,
              "whole": 200,
              "elapsed": 5,
              "old": 4.5,
              "new": 4.75,
              "base": 16,
              "exponent": 0.5,
              "a": 2
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 28
            }
          }
        ],
        "output": {
          "percentageChange": 5.555555555555555,
          "percentagePoints": 0.25
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: percentageChange, percentagePoints"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a04/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a04/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a04/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Percentage Change, Percentage Points, and Basis Points — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: relative change = (new - old) / old × 100; basis points = percentage-point change × 100\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "INVESTOR",
          "title": "Basis Point",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "NIST",
          "title": "NIST/SEMATECH e-Handbook of Statistical Methods",
          "author": "NIST/SEMATECH",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/mathematical-language-and-quantitative-reasoning/percentage-change-percentage-points-and-basis-points/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/mathematical-language-and-quantitative-reasoning/percentage-change-percentage-points-and-basis-points/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F01-A05",
      "name": "Exponents, Roots, and Logarithms",
      "headline": null,
      "slug": "exponents-roots-and-logarithms",
      "path": "foundations/mathematical-language-and-quantitative-reasoning/exponents-roots-and-logarithms",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F01",
        "family": "Mathematical Language and Quantitative Reasoning",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/mathematical-language-and-quantitative-reasoning/exponents-roots-and-logarithms",
        "entry": "exponentsRootsAndLogarithms",
        "params": [
          "input"
        ],
        "exports": [
          "exponentsRootsAndLogarithms"
        ],
        "archetype": "record-transform",
        "signature": "exponentsRootsAndLogarithms(input)"
      },
      "api": {
        "summary": "Applies the three operations that share one base: raising it to an exponent, taking its square root, and taking its natural logarithm.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F01 topic first reads `values`, which must be a non-empty array of finite numbers, and validates it before any per-topic branch runs. This topic then reads `base` and `exponent`, both coerced with `Number`; `values` is demanded but not used by this calculation.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ power: number; squareRoot: number; naturalLog: number }",
          "description": "`power` is `base` raised to `exponent`, `squareRoot` is the square root of `base`, and `naturalLog` is its natural logarithm."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "values is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          },
          {
            "when": "values contains a value that is not a finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "base is zero or negative",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F01-A05.json",
        "call": "exponentsRootsAndLogarithms({\"values\":[1,2,3,4,5],\"startingCash\":1000,\"inflows\":250,\"outflows\":120,\"slope\":2,\"intercept\":1,\"part\":25,\"whole\":200,\"elapsed\":5,\"old\":4.5,\"new\":4.75,\"base\":16,\"exponent\":0.5,\"a\":2})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "startingCash": 1000,
              "inflows": 250,
              "outflows": 120,
              "slope": 2,
              "intercept": 1,
              "part": 25,
              "whole": 200,
              "elapsed": 5,
              "old": 4.5,
              "new": 4.75,
              "base": 16,
              "exponent": 0.5,
              "a": 2
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 28
            }
          }
        ],
        "output": {
          "power": 4,
          "squareRoot": 4
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: power, squareRoot"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a05/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a05/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a05/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Exponents, Roots, and Logarithms — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: future amount = present amount × (1 + growth rate) ^ periods\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST_LOG",
          "title": "NIST Dataplot: Exponential and Logarithmic Functions",
          "author": "NIST/SEMATECH",
          "url": null
        },
        {
          "key": "OPENSTAX",
          "title": "College Algebra: Domain and Range",
          "author": "OpenStax",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/mathematical-language-and-quantitative-reasoning/exponents-roots-and-logarithms/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/mathematical-language-and-quantitative-reasoning/exponents-roots-and-logarithms/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F01-A06",
      "name": "Summation, Products, and Index Notation",
      "headline": null,
      "slug": "summation-products-and-index-notation",
      "path": "foundations/mathematical-language-and-quantitative-reasoning/summation-products-and-index-notation",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F01",
        "family": "Mathematical Language and Quantitative Reasoning",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/mathematical-language-and-quantitative-reasoning/summation-products-and-index-notation",
        "entry": "summationProductsAndIndexNotation",
        "params": [
          "input"
        ],
        "exports": [
          "summationProductsAndIndexNotation"
        ],
        "archetype": "record-transform",
        "signature": "summationProductsAndIndexNotation(input)"
      },
      "api": {
        "summary": "Reduces a series to its sum and its product, and re-emits it as explicitly numbered terms so subscript notation can be read against real values.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F01 topic first reads `values`, which must be a non-empty array of finite numbers, and validates it before any per-topic branch runs. This topic uses `values` itself and reads no further keys.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ sum: number; product: number; indexedTerms: { index: number; value: number }[] }",
          "description": "`sum` and `product` reduce the series. `indexedTerms` pairs each value with its position, numbered from 1 rather than 0."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "values is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          },
          {
            "when": "values contains a value that is not a finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F01-A06.json",
        "call": "summationProductsAndIndexNotation({\"values\":[2,3,5],\"startingCash\":1000,\"inflows\":250,\"outflows\":120,\"slope\":2,\"intercept\":1,\"part\":25,\"whole\":200,\"elapsed\":5,\"old\":4.5,\"new\":4.75,\"base\":16,\"exponent\":0.5,\"a\":2})",
        "args": [
          {
            "value": {
              "values": [
                2,
                3,
                5
              ],
              "startingCash": 1000,
              "inflows": 250,
              "outflows": 120,
              "slope": 2,
              "intercept": 1,
              "part": 25,
              "whole": 200,
              "elapsed": 5,
              "old": 4.5,
              "new": 4.75,
              "base": 16,
              "exponent": 0.5,
              "a": 2
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 28
            }
          }
        ],
        "output": {
          "sum": 10,
          "product": 30,
          "indexedTerms": [
            {
              "index": 1,
              "value": 2
            },
            {
              "index": 2,
              "value": 3
            },
            {
              "index": 3,
              "value": 5
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: sum, product, indexedTerms"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a06/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a06/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a06/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Summation, Products, and Index Notation — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: sum = value₁ + value₂ + … + valueₙ; product = factor₁ × factor₂ × … × factorₙ\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST",
          "title": "NIST/SEMATECH e-Handbook of Statistical Methods",
          "author": "NIST/SEMATECH",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/mathematical-language-and-quantitative-reasoning/summation-products-and-index-notation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/mathematical-language-and-quantitative-reasoning/summation-products-and-index-notation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F01-A07",
      "name": "Linear Equations and Systems",
      "headline": null,
      "slug": "linear-equations-and-systems",
      "path": "foundations/mathematical-language-and-quantitative-reasoning/linear-equations-and-systems",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F01",
        "family": "Mathematical Language and Quantitative Reasoning",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/mathematical-language-and-quantitative-reasoning/linear-equations-and-systems",
        "entry": "linearEquationsAndSystems",
        "params": [
          "input"
        ],
        "exports": [
          "linearEquationsAndSystems"
        ],
        "archetype": "record-transform",
        "signature": "linearEquationsAndSystems(input)"
      },
      "api": {
        "summary": "Solves the two-equation system `a*x + b*y = c` and `d*x + e*y = f` by Cramer's rule, returning the solution and the determinant that decides whether one exists.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F01 topic first reads `values`, which must be a non-empty array of finite numbers, and validates it before any per-topic branch runs. This topic then reads the six coefficients `a`, `b`, `c`, `d`, `e` and `f`, each coerced with `Number`; `values` is demanded but not used by this calculation.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ x: number; y: number; determinant: number }",
          "description": "`determinant` is `a*e - b*d`. `x` is `(c*e - b*f)` over that determinant and `y` is `(a*f - c*d)` over it."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "values is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          },
          {
            "when": "values contains a value that is not a finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the determinant a*e - b*d is zero, so the system has no unique solution",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F01-A07.json",
        "call": "linearEquationsAndSystems({\"values\":[1,2,3,4,5],\"startingCash\":1000,\"inflows\":250,\"outflows\":120,\"slope\":2,\"intercept\":1,\"part\":25,\"whole\":200,\"elapsed\":5,\"old\":4.5,\"new\":4.75,\"base\":16,\"exponent\":0.5,\"a\":2})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "startingCash": 1000,
              "inflows": 250,
              "outflows": 120,
              "slope": 2,
              "intercept": 1,
              "part": 25,
              "whole": 200,
              "elapsed": 5,
              "old": 4.5,
              "new": 4.75,
              "base": 16,
              "exponent": 0.5,
              "a": 2
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 28
            }
          }
        ],
        "output": {
          "x": 3,
          "y": 1
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: x, y"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a07/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a07/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a07/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Linear Equations and Systems — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: a×x + b×y = c and d×x + e×y = f\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST",
          "title": "NIST/SEMATECH e-Handbook of Statistical Methods",
          "author": "NIST/SEMATECH",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/mathematical-language-and-quantitative-reasoning/linear-equations-and-systems/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/mathematical-language-and-quantitative-reasoning/linear-equations-and-systems/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F01-A08",
      "name": "Inequalities, Bounds, and Constraints",
      "headline": null,
      "slug": "inequalities-bounds-and-constraints",
      "path": "foundations/mathematical-language-and-quantitative-reasoning/inequalities-bounds-and-constraints",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F01",
        "family": "Mathematical Language and Quantitative Reasoning",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/mathematical-language-and-quantitative-reasoning/inequalities-bounds-and-constraints",
        "entry": "inequalitiesBoundsAndConstraints",
        "params": [
          "input"
        ],
        "exports": [
          "inequalitiesBoundsAndConstraints"
        ],
        "archetype": "record-transform",
        "signature": "inequalitiesBoundsAndConstraints(input)"
      },
      "api": {
        "summary": "Tests a candidate number against a lower and upper bound, reporting whether it is admissible, what it becomes once clamped into range, and how far outside the range it sits.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F01 topic first reads `values`, which must be a non-empty array of finite numbers, and validates it before any per-topic branch runs. This topic then reads `candidate`, `lower` and `upper`, each coerced with `Number`; `values` is demanded but not used by this calculation.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ withinBounds: boolean; clamped: number; distanceToFeasible: number }",
          "description": "`withinBounds` is true when the candidate lies inside the closed interval, bounds included. `clamped` is the candidate pulled to the nearest bound when it is outside. `distanceToFeasible` is how far it must move to become admissible, and is 0 when it already is."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "values is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          },
          {
            "when": "values contains a value that is not a finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "lower is greater than upper",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F01-A08.json",
        "call": "inequalitiesBoundsAndConstraints({\"values\":[1,2,3,4,5],\"startingCash\":1000,\"inflows\":250,\"outflows\":120,\"slope\":2,\"intercept\":1,\"part\":25,\"whole\":200,\"elapsed\":5,\"old\":4.5,\"new\":4.75,\"base\":16,\"exponent\":0.5,\"a\":2})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "startingCash": 1000,
              "inflows": 250,
              "outflows": 120,
              "slope": 2,
              "intercept": 1,
              "part": 25,
              "whole": 200,
              "elapsed": 5,
              "old": 4.5,
              "new": 4.75,
              "base": 16,
              "exponent": 0.5,
              "a": 2
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 28
            }
          }
        ],
        "output": {
          "withinBounds": false,
          "clamped": 10
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: withinBounds, clamped"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a08/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a08/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a08/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Inequalities, Bounds, and Constraints — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: committed + new spend ≤ limit, so new spend ≤ limit - committed\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST",
          "title": "NIST/SEMATECH e-Handbook of Statistical Methods",
          "author": "NIST/SEMATECH",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/mathematical-language-and-quantitative-reasoning/inequalities-bounds-and-constraints/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/mathematical-language-and-quantitative-reasoning/inequalities-bounds-and-constraints/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F01-A09",
      "name": "Units, Dimensions, Scale, and Normalization",
      "headline": null,
      "slug": "units-dimensions-scale-and-normalization",
      "path": "foundations/mathematical-language-and-quantitative-reasoning/units-dimensions-scale-and-normalization",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F01",
        "family": "Mathematical Language and Quantitative Reasoning",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/mathematical-language-and-quantitative-reasoning/units-dimensions-scale-and-normalization",
        "entry": "unitsDimensionsScaleAndNormalization",
        "params": [
          "input"
        ],
        "exports": [
          "unitsDimensionsScaleAndNormalization"
        ],
        "archetype": "record-transform",
        "signature": "unitsDimensionsScaleAndNormalization(input)"
      },
      "api": {
        "summary": "Rescales a series by subtracting an offset and dividing by a scale, so numbers recorded in one unit can be compared on a common footing.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F01 topic first reads `values`, which must be a non-empty array of finite numbers, and validates it before any per-topic branch runs. This topic then reads `offset` and `scale`, both coerced with `Number`, and `sourceUnit`, which is passed through untouched as a label.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ normalized: number[]; sourceUnit: unknown; targetUnit: string }",
          "description": "`normalized` holds `(value - offset) / scale` for each entry in input order. `sourceUnit` is echoed back from the input and `targetUnit` is always the fixed label `scaled units`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "values is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          },
          {
            "when": "values contains a value that is not a finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "scale is zero",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F01-A09.json",
        "call": "unitsDimensionsScaleAndNormalization({\"values\":[1,2,3,4,5],\"startingCash\":1000,\"inflows\":250,\"outflows\":120,\"slope\":2,\"intercept\":1,\"part\":25,\"whole\":200,\"elapsed\":5,\"old\":4.5,\"new\":4.75,\"base\":16,\"exponent\":0.5,\"a\":2})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "startingCash": 1000,
              "inflows": 250,
              "outflows": 120,
              "slope": 2,
              "intercept": 1,
              "part": 25,
              "whole": 200,
              "elapsed": 5,
              "old": 4.5,
              "new": 4.75,
              "base": 16,
              "exponent": 0.5,
              "a": 2
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 28
            }
          }
        ],
        "output": {
          "normalized": [
            0,
            0.5,
            1,
            1.5,
            2
          ],
          "sourceUnit": "SAR millions"
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: normalized, sourceUnit"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a09/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a09/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a09/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Units, Dimensions, Scale, and Normalization — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: base amount = displayed amount × scale; per-unit amount = base amount / count\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "BIPM",
          "title": "The International System of Units (SI Brochure), 9th edition",
          "author": "Bureau International des Poids et Mesures",
          "url": null
        },
        {
          "key": "NIST",
          "title": "NIST/SEMATECH e-Handbook of Statistical Methods",
          "author": "NIST/SEMATECH",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/mathematical-language-and-quantitative-reasoning/units-dimensions-scale-and-normalization/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/mathematical-language-and-quantitative-reasoning/units-dimensions-scale-and-normalization/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F01-A10",
      "name": "Rounding, Precision, Tolerance, and Significant Digits",
      "headline": null,
      "slug": "rounding-precision-tolerance-and-significant-digits",
      "path": "foundations/mathematical-language-and-quantitative-reasoning/rounding-precision-tolerance-and-significant-digits",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F01",
        "family": "Mathematical Language and Quantitative Reasoning",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/mathematical-language-and-quantitative-reasoning/rounding-precision-tolerance-and-significant-digits",
        "entry": "roundingPrecisionToleranceAndSignificantDigits",
        "params": [
          "input"
        ],
        "exports": [
          "roundingPrecisionToleranceAndSignificantDigits"
        ],
        "archetype": "record-transform",
        "signature": "roundingPrecisionToleranceAndSignificantDigits(input)"
      },
      "api": {
        "summary": "Rounds a candidate to a fixed number of decimal places and measures it against a reference value and an allowed tolerance.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F01 topic first reads `values`, which must be a non-empty array of finite numbers, and validates it before any per-topic branch runs. This topic then reads `candidate`, `digits`, `reference` and `tolerance`, each coerced with `Number`; `values` is demanded but not used by this calculation.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ rounded: number; withinTolerance: boolean; absoluteError: number }",
          "description": "`rounded` is the candidate fixed to `digits` decimal places and read back as a number. `absoluteError` is the unrounded distance from `reference`, and `withinTolerance` is true when that distance is at most `tolerance`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "values is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          },
          {
            "when": "values contains a value that is not a finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F01-A10.json",
        "call": "roundingPrecisionToleranceAndSignificantDigits({\"values\":[1,2,3,4,5],\"startingCash\":1000,\"inflows\":250,\"outflows\":120,\"slope\":2,\"intercept\":1,\"part\":25,\"whole\":200,\"elapsed\":5,\"old\":4.5,\"new\":4.75,\"base\":16,\"exponent\":0.5,\"a\":2})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "startingCash": 1000,
              "inflows": 250,
              "outflows": 120,
              "slope": 2,
              "intercept": 1,
              "part": 25,
              "whole": 200,
              "elapsed": 5,
              "old": 4.5,
              "new": 4.75,
              "base": 16,
              "exponent": 0.5,
              "a": 2
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 28
            }
          }
        ],
        "output": {
          "rounded": 10,
          "withinTolerance": true
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: rounded, withinTolerance"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a10/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a10/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f01-a10/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Rounding, Precision, Tolerance, and Significant Digits — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: difference = |value - reference|; accept when difference ≤ tolerance\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST811",
          "title": "Guide for the Use of the International System of Units (SI), NIST SP 811",
          "author": "NIST/SEMATECH",
          "url": null
        },
        {
          "key": "NIST",
          "title": "NIST/SEMATECH e-Handbook of Statistical Methods",
          "author": "NIST/SEMATECH",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/mathematical-language-and-quantitative-reasoning/rounding-precision-tolerance-and-significant-digits/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/mathematical-language-and-quantitative-reasoning/rounding-precision-tolerance-and-significant-digits/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F02-A01",
      "name": "Simple Interest",
      "headline": null,
      "slug": "simple-interest",
      "path": "foundations/financial-arithmetic-time-value-and-returns/simple-interest",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F02",
        "family": "Financial Arithmetic, Time Value, and Returns",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-arithmetic-time-value-and-returns/simple-interest",
        "entry": "simpleInterest",
        "params": [
          "input"
        ],
        "exports": [
          "simpleInterest"
        ],
        "archetype": "record-transform",
        "signature": "simpleInterest(input)"
      },
      "api": {
        "summary": "Computes interest that accrues on the original principal only, never on interest already earned, and the balance that leaves at the end.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F02 topic first reads `principal`, `rate` and `periods` and validates them before any per-topic branch runs. This topic uses exactly those three and reads no further keys. `rate` is the rate per period, matching the unit `periods` is counted in.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ interest: number; endingValue: number }",
          "description": "`interest` is `principal * rate * periods` and `endingValue` is the principal plus that interest."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "principal is negative, periods is negative, or rate is at or below -1",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F02-A01.json",
        "call": "simpleInterest({\"principal\":1000,\"rate\":0.05,\"periods\":3,\"compoundsPerPeriod\":12,\"futureValue\":1200,\"cashFlows\":[-1000,400,400,400],\"startValue\":100,\"endValue\":110,\"returns\":[0.1,-0.05,0.08],\"frequency\":12,\"periodicReturn\":0.01})",
        "args": [
          {
            "value": {
              "principal": 1000,
              "rate": 0.05,
              "periods": 3,
              "compoundsPerPeriod": 12,
              "futureValue": 1200,
              "cashFlows": [
                -1000,
                400,
                400,
                400
              ],
              "startValue": 100,
              "endValue": 110,
              "returns": [
                0.1,
                -0.05,
                0.08
              ],
              "frequency": 12,
              "periodicReturn": 0.01
            },
            "elided": null
          }
        ],
        "output": {
          "interest": 150,
          "endingValue": 1150
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: interest, endingValue"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a01/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a01/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a01/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Simple Interest — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: interest = P x r x t; amount = P x (1 + r x t)\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "INVESTOR_INTEREST - Interest",
          "title": "INVESTOR_INTEREST - Interest",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "CFA_TVM - Time Value of Money in Finance",
          "title": "CFA_TVM - Time Value of Money in Finance",
          "author": "CFA Institute",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/simple-interest/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-arithmetic-time-value-and-returns/simple-interest/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F02-A02",
      "name": "Compound Interest",
      "headline": null,
      "slug": "compound-interest",
      "path": "foundations/financial-arithmetic-time-value-and-returns/compound-interest",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F02",
        "family": "Financial Arithmetic, Time Value, and Returns",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-arithmetic-time-value-and-returns/compound-interest",
        "entry": "compoundInterest",
        "params": [
          "input"
        ],
        "exports": [
          "compoundInterest"
        ],
        "archetype": "record-transform",
        "signature": "compoundInterest(input)"
      },
      "api": {
        "summary": "Grows a principal at a periodic rate applied `compoundsPerPeriod` times within each period, so earned interest starts earning interest itself.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F02 topic first reads `principal`, `rate` and `periods` and validates them before any per-topic branch runs. This topic then reads `compoundsPerPeriod`, the number of compounding steps inside one period, coerced with `Number`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ endingValue: number; interest: number }",
          "description": "`endingValue` is `principal * (1 + rate / compoundsPerPeriod)` raised to `compoundsPerPeriod * periods`. `interest` is that value less the original principal."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "principal is negative, periods is negative, or rate is at or below -1",
            "behaviour": "throws RangeError"
          },
          {
            "when": "compoundsPerPeriod is zero or negative",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F02-A02.json",
        "call": "compoundInterest({\"principal\":1000,\"rate\":0.05,\"periods\":3,\"compoundsPerPeriod\":12,\"futureValue\":1200,\"cashFlows\":[-1000,400,400,400],\"startValue\":100,\"endValue\":110,\"returns\":[0.1,-0.05,0.08],\"frequency\":12,\"periodicReturn\":0.01})",
        "args": [
          {
            "value": {
              "principal": 1000,
              "rate": 0.05,
              "periods": 3,
              "compoundsPerPeriod": 12,
              "futureValue": 1200,
              "cashFlows": [
                -1000,
                400,
                400,
                400
              ],
              "startValue": 100,
              "endValue": 110,
              "returns": [
                0.1,
                -0.05,
                0.08
              ],
              "frequency": 12,
              "periodicReturn": 0.01
            },
            "elided": null
          }
        ],
        "output": {
          "endingValue": 1161.4722313334678,
          "interest": 161.4722313334678
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: endingValue, interest"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a02/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a02/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a02/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Compound Interest — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: A = P x (1 + r)^t; general frequency: A = P x (1 + r/n)^(n x t)\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "INVESTOR_COMPOUND - Compound Interest",
          "title": "INVESTOR_COMPOUND - Compound Interest",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "INVESTOR_CDS - Investor Bulletin: Brokered CDs",
          "title": "INVESTOR_CDS - Investor Bulletin: Brokered CDs",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "CFA_TVM - Time Value of Money in Finance",
          "title": "CFA_TVM - Time Value of Money in Finance",
          "author": "CFA Institute",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/compound-interest/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-arithmetic-time-value-and-returns/compound-interest/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F02-A03",
      "name": "Present Value and Future Value",
      "headline": null,
      "slug": "present-future-value",
      "path": "foundations/financial-arithmetic-time-value-and-returns/present-future-value",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F02",
        "family": "Financial Arithmetic, Time Value, and Returns",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-arithmetic-time-value-and-returns/present-future-value",
        "entry": "presentValueAndFutureValue",
        "params": [
          "input"
        ],
        "exports": [
          "presentValueAndFutureValue"
        ],
        "archetype": "record-transform",
        "signature": "presentValueAndFutureValue(input)"
      },
      "api": {
        "summary": "Moves money along the timeline in both directions at once: it compounds `principal` forward and discounts a supplied `futureValue` back, over the same number of periods at the same rate.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F02 topic first reads `principal`, `rate` and `periods` and validates them before any per-topic branch runs. This topic then reads the input key `futureValue`, the amount to be discounted back to today, coerced with `Number`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ futureValue: number; presentValue: number }",
          "description": "The returned `futureValue` is `principal * (1 + rate) ** periods` and is computed from `principal`, not from the input key of the same name. `presentValue` is the input `futureValue` divided by `(1 + rate) ** periods`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "principal is negative, periods is negative, or rate is at or below -1",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F02-A03.json",
        "call": "presentValueAndFutureValue({\"principal\":1000,\"rate\":0.05,\"periods\":3,\"compoundsPerPeriod\":12,\"futureValue\":1200,\"cashFlows\":[-1000,400,400,400],\"startValue\":100,\"endValue\":110,\"returns\":[0.1,-0.05,0.08],\"frequency\":12,\"periodicReturn\":0.01})",
        "args": [
          {
            "value": {
              "principal": 1000,
              "rate": 0.05,
              "periods": 3,
              "compoundsPerPeriod": 12,
              "futureValue": 1200,
              "cashFlows": [
                -1000,
                400,
                400,
                400
              ],
              "startValue": 100,
              "endValue": 110,
              "returns": [
                0.1,
                -0.05,
                0.08
              ],
              "frequency": 12,
              "periodicReturn": 0.01
            },
            "elided": null
          }
        ],
        "output": {
          "futureValue": 1157.6250000000002,
          "presentValue": 1036.6051182377712
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: futureValue, presentValue"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a03/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a03/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a03/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Present Value and Future Value — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: FV = PV x (1 + r)^t; PV = FV / (1 + r)^t\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "CFA_TVM - Time Value of Money in Finance",
          "title": "CFA_TVM - Time Value of Money in Finance",
          "author": "CFA Institute",
          "url": null
        },
        {
          "key": "CFA_QM - CFA Institute Quantitative Methods Study Session",
          "title": "CFA_QM - CFA Institute Quantitative Methods Study Session",
          "author": "CFA Institute",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/present-future-value/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-arithmetic-time-value-and-returns/present-future-value/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F02-A04",
      "name": "Discount Factors and Discount Rates",
      "headline": null,
      "slug": "discount-factors",
      "path": "foundations/financial-arithmetic-time-value-and-returns/discount-factors",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F02",
        "family": "Financial Arithmetic, Time Value, and Returns",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-arithmetic-time-value-and-returns/discount-factors",
        "entry": "discountFactorsAndDiscountRates",
        "params": [
          "input"
        ],
        "exports": [
          "discountFactorsAndDiscountRates"
        ],
        "archetype": "record-transform",
        "signature": "discountFactorsAndDiscountRates(input)"
      },
      "api": {
        "summary": "Converts a rate and a horizon into the single multiplier that pulls a future amount back to today, and converts that multiplier back into the per-period rate it implies.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F02 topic first reads `principal`, `rate` and `periods` and validates them before any per-topic branch runs. This topic uses `rate` and `periods` and reads no further keys; `principal` is validated but not used.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ discountFactor: number; discountRate: number }",
          "description": "`discountFactor` is `1 / (1 + rate) ** periods`. `discountRate` is the per-period rate recovered from that factor, and is returned as 0 when `periods` is 0, since no rate can be inferred over no time."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "principal is negative, periods is negative, or rate is at or below -1",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F02-A04.json",
        "call": "discountFactorsAndDiscountRates({\"principal\":1000,\"rate\":0.05,\"periods\":3,\"compoundsPerPeriod\":12,\"futureValue\":1200,\"cashFlows\":[-1000,400,400,400],\"startValue\":100,\"endValue\":110,\"returns\":[0.1,-0.05,0.08],\"frequency\":12,\"periodicReturn\":0.01})",
        "args": [
          {
            "value": {
              "principal": 1000,
              "rate": 0.05,
              "periods": 3,
              "compoundsPerPeriod": 12,
              "futureValue": 1200,
              "cashFlows": [
                -1000,
                400,
                400,
                400
              ],
              "startValue": 100,
              "endValue": 110,
              "returns": [
                0.1,
                -0.05,
                0.08
              ],
              "frequency": 12,
              "periodicReturn": 0.01
            },
            "elided": null
          }
        ],
        "output": {
          "discountFactor": 0.863837598531476,
          "discountRate": 0.050000000000000044
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: discountFactor, discountRate"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a04/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a04/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a04/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Discount Factors and Discount Rates — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: discount factor = 1 / (1 + r)^t; PV = future cash x discount factor\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "CFA_TVM - Time Value of Money in Finance",
          "title": "CFA_TVM - Time Value of Money in Finance",
          "author": "CFA Institute",
          "url": null
        },
        {
          "key": "CFA_QM - CFA Institute Quantitative Methods Study Session",
          "title": "CFA_QM - CFA Institute Quantitative Methods Study Session",
          "author": "CFA Institute",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/discount-factors/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-arithmetic-time-value-and-returns/discount-factors/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F02-A05",
      "name": "Cash-Flow Timelines and Net Present Value",
      "headline": null,
      "slug": "cashflow-npv",
      "path": "foundations/financial-arithmetic-time-value-and-returns/cashflow-npv",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F02",
        "family": "Financial Arithmetic, Time Value, and Returns",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-arithmetic-time-value-and-returns/cashflow-npv",
        "entry": "cashFlowTimelinesAndNetPresentValue",
        "params": [
          "input"
        ],
        "exports": [
          "cashFlowTimelinesAndNetPresentValue"
        ],
        "archetype": "record-transform",
        "signature": "cashFlowTimelinesAndNetPresentValue(input)"
      },
      "api": {
        "summary": "Discounts a dated series of cash flows back to today at a single rate and sums them into a net present value.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F02 topic first reads `principal`, `rate` and `periods` and validates them before any per-topic branch runs. This topic then reads `cashFlows`, a non-empty array of finite numbers whose position in the array is the period the flow lands in, counted from 0. `principal` and `periods` are validated but not used.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ npv: number; presentValues: number[] }",
          "description": "`presentValues` holds each flow divided by `(1 + rate)` raised to its zero-based position, so the first flow is undiscounted. `npv` is their sum."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "principal is negative, periods is negative, or rate is at or below -1",
            "behaviour": "throws RangeError"
          },
          {
            "when": "cashFlows is missing, empty, not an array, or contains a non-finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F02-A05.json",
        "call": "cashFlowTimelinesAndNetPresentValue({\"principal\":1000,\"rate\":0.05,\"periods\":3,\"compoundsPerPeriod\":12,\"futureValue\":1200,\"cashFlows\":[-1000,400,400,400],\"startValue\":100,\"endValue\":110,\"returns\":[0.1,-0.05,0.08],\"frequency\":12,\"periodicReturn\":0.01})",
        "args": [
          {
            "value": {
              "principal": 1000,
              "rate": 0.05,
              "periods": 3,
              "compoundsPerPeriod": 12,
              "futureValue": 1200,
              "cashFlows": [
                -1000,
                400,
                400,
                400
              ],
              "startValue": 100,
              "endValue": 110,
              "returns": [
                0.1,
                -0.05,
                0.08
              ],
              "frequency": 12,
              "periodicReturn": 0.01
            },
            "elided": null
          }
        ],
        "output": {
          "npv": 89.29921174819128,
          "presentValues": [
            -1000,
            380.95238095238096,
            362.81179138321994,
            345.5350394125904
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: npv, presentValues"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a05/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a05/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a05/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Cash-Flow Timelines and Net Present Value — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: NPV = CF0 + CF1/(1+r)^1 + CF2/(1+r)^2 + ...\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "CFA_TVM - Time Value of Money in Finance",
          "title": "CFA_TVM - Time Value of Money in Finance",
          "author": "CFA Institute",
          "url": null
        },
        {
          "key": "CFA_QM - CFA Institute Quantitative Methods Study Session",
          "title": "CFA_QM - CFA Institute Quantitative Methods Study Session",
          "author": "CFA Institute",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/cashflow-npv/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-arithmetic-time-value-and-returns/cashflow-npv/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F02-A06",
      "name": "Simple Return",
      "headline": null,
      "slug": "simple-return",
      "path": "foundations/financial-arithmetic-time-value-and-returns/simple-return",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F02",
        "family": "Financial Arithmetic, Time Value, and Returns",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-arithmetic-time-value-and-returns/simple-return",
        "entry": "simpleReturn",
        "params": [
          "input"
        ],
        "exports": [
          "simpleReturn"
        ],
        "archetype": "record-transform",
        "signature": "simpleReturn(input)"
      },
      "api": {
        "summary": "Measures the plain percentage gain between a starting and an ending value over one holding period.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F02 topic first reads `principal`, `rate` and `periods` and validates them before any per-topic branch runs. This topic then reads `startValue` and `endValue`, which must both be strictly positive; `principal`, `rate` and `periods` are validated but not used.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ simpleReturn: number; percentageReturn: number }",
          "description": "`simpleReturn` is `endValue / startValue - 1` as a decimal fraction and `percentageReturn` is the same number expressed in percent."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "principal is negative, periods is negative, or rate is at or below -1",
            "behaviour": "throws RangeError"
          },
          {
            "when": "startValue or endValue is zero or negative",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F02-A06.json",
        "call": "simpleReturn({\"principal\":1000,\"rate\":0.05,\"periods\":3,\"compoundsPerPeriod\":12,\"futureValue\":1200,\"cashFlows\":[-1000,400,400,400],\"startValue\":100,\"endValue\":110,\"returns\":[0.1,-0.05,0.08],\"frequency\":12,\"periodicReturn\":0.01})",
        "args": [
          {
            "value": {
              "principal": 1000,
              "rate": 0.05,
              "periods": 3,
              "compoundsPerPeriod": 12,
              "futureValue": 1200,
              "cashFlows": [
                -1000,
                400,
                400,
                400
              ],
              "startValue": 100,
              "endValue": 110,
              "returns": [
                0.1,
                -0.05,
                0.08
              ],
              "frequency": 12,
              "periodicReturn": 0.01
            },
            "elided": null
          }
        ],
        "output": {
          "simpleReturn": 0.10000000000000009,
          "percentageReturn": 10.000000000000009
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: simpleReturn, percentageReturn"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a06/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a06/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a06/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Simple Return — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: total return = (ending value + cash received - starting value) / starting value\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "INVESTOR_RETURN - Annual Return",
          "title": "INVESTOR_RETURN - Annual Return",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "CFA_QM - CFA Institute Quantitative Methods Study Session",
          "title": "CFA_QM - CFA Institute Quantitative Methods Study Session",
          "author": "CFA Institute",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/simple-return/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-arithmetic-time-value-and-returns/simple-return/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F02-A07",
      "name": "Log Return",
      "headline": null,
      "slug": "log-return",
      "path": "foundations/financial-arithmetic-time-value-and-returns/log-return",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F02",
        "family": "Financial Arithmetic, Time Value, and Returns",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-arithmetic-time-value-and-returns/log-return",
        "entry": "logReturn",
        "params": [
          "input"
        ],
        "exports": [
          "logReturn"
        ],
        "archetype": "record-transform",
        "signature": "logReturn(input)"
      },
      "api": {
        "summary": "Takes the natural logarithm of the growth ratio between a starting and an ending value, and converts it back to show the two are the same move.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F02 topic first reads `principal`, `rate` and `periods` and validates them before any per-topic branch runs. This topic then reads `startValue` and `endValue`, which must both be strictly positive; `principal`, `rate` and `periods` are validated but not used.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ logReturn: number; recoveredSimpleReturn: number }",
          "description": "`logReturn` is the natural log of `endValue / startValue`. `recoveredSimpleReturn` exponentiates it back and subtracts 1, giving the matching simple return."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "principal is negative, periods is negative, or rate is at or below -1",
            "behaviour": "throws RangeError"
          },
          {
            "when": "startValue or endValue is zero or negative",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F02-A07.json",
        "call": "logReturn({\"principal\":1000,\"rate\":0.05,\"periods\":3,\"compoundsPerPeriod\":12,\"futureValue\":1200,\"cashFlows\":[-1000,400,400,400],\"startValue\":100,\"endValue\":110,\"returns\":[0.1,-0.05,0.08],\"frequency\":12,\"periodicReturn\":0.01})",
        "args": [
          {
            "value": {
              "principal": 1000,
              "rate": 0.05,
              "periods": 3,
              "compoundsPerPeriod": 12,
              "futureValue": 1200,
              "cashFlows": [
                -1000,
                400,
                400,
                400
              ],
              "startValue": 100,
              "endValue": 110,
              "returns": [
                0.1,
                -0.05,
                0.08
              ],
              "frequency": 12,
              "periodicReturn": 0.01
            },
            "elided": null
          }
        ],
        "output": {
          "logReturn": 0.09531017980432493,
          "recoveredSimpleReturn": 0.10000000000000009
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: logReturn, recoveredSimpleReturn"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a07/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a07/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a07/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Log Return — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: log return = ln(ending value / starting value)\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST_LOG - NIST Dataplot: Exponential and Logarithmic Functions",
          "title": "NIST_LOG - NIST Dataplot: Exponential and Logarithmic Functions",
          "author": "Institutional source",
          "url": null
        },
        {
          "key": "CFA_QM - CFA Institute Quantitative Methods Study Session",
          "title": "CFA_QM - CFA Institute Quantitative Methods Study Session",
          "author": "CFA Institute",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/log-return/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-arithmetic-time-value-and-returns/log-return/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F02-A08",
      "name": "Holding-Period and Cumulative Return",
      "headline": null,
      "slug": "holding-period-return",
      "path": "foundations/financial-arithmetic-time-value-and-returns/holding-period-return",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F02",
        "family": "Financial Arithmetic, Time Value, and Returns",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-arithmetic-time-value-and-returns/holding-period-return",
        "entry": "holdingPeriodAndCumulativeReturn",
        "params": [
          "input"
        ],
        "exports": [
          "holdingPeriodAndCumulativeReturn"
        ],
        "archetype": "record-transform",
        "signature": "holdingPeriodAndCumulativeReturn(input)"
      },
      "api": {
        "summary": "Chains a series of period returns into the single growth factor they compound to, and applies that factor to a starting value.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F02 topic first reads `principal`, `rate` and `periods` and validates them before any per-topic branch runs. Before reaching this branch the engine also rejects a `startValue` or `endValue` that is zero or negative (omitting them entirely is not caught, because `Number(undefined)` is `NaN`), and `returns` to be a non-empty array of finite numbers none of which is at or below -1. The calculation itself uses `returns` and `startValue`; `endValue`, `principal`, `rate` and `periods` are validated but not used.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ growthFactor: number; cumulativeReturn: number; endingValue: number }",
          "description": "`growthFactor` is the product of `1 + r` across the series, `cumulativeReturn` is that factor less 1, and `endingValue` is `startValue` grown by the factor."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "principal is negative, periods is negative, or rate is at or below -1",
            "behaviour": "throws RangeError"
          },
          {
            "when": "startValue or endValue is zero or negative",
            "behaviour": "throws RangeError"
          },
          {
            "when": "returns is missing, empty, not an array, or contains a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of returns is at or below -1, a loss of 100% or worse",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F02-A08.json",
        "call": "holdingPeriodAndCumulativeReturn({\"principal\":1000,\"rate\":0.05,\"periods\":3,\"compoundsPerPeriod\":12,\"futureValue\":1200,\"cashFlows\":[-1000,400,400,400],\"startValue\":100,\"endValue\":110,\"returns\":[0.1,-0.05,0.08],\"frequency\":12,\"periodicReturn\":0.01})",
        "args": [
          {
            "value": {
              "principal": 1000,
              "rate": 0.05,
              "periods": 3,
              "compoundsPerPeriod": 12,
              "futureValue": 1200,
              "cashFlows": [
                -1000,
                400,
                400,
                400
              ],
              "startValue": 100,
              "endValue": 110,
              "returns": [
                0.1,
                -0.05,
                0.08
              ],
              "frequency": 12,
              "periodicReturn": 0.01
            },
            "elided": null
          }
        ],
        "output": {
          "growthFactor": 1.1286,
          "cumulativeReturn": 0.12860000000000005
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: growthFactor, cumulativeReturn"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a08/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a08/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a08/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Holding-Period and Cumulative Return — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: cumulative return = (1+r1)(1+r2)...(1+rn) - 1\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "INVESTOR_RETURN - Annual Return",
          "title": "INVESTOR_RETURN - Annual Return",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "CFA_QM - CFA Institute Quantitative Methods Study Session",
          "title": "CFA_QM - CFA Institute Quantitative Methods Study Session",
          "author": "CFA Institute",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/holding-period-return/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-arithmetic-time-value-and-returns/holding-period-return/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F02-A09",
      "name": "Arithmetic versus Geometric Average Return",
      "headline": null,
      "slug": "arithmetic-geometric-return",
      "path": "foundations/financial-arithmetic-time-value-and-returns/arithmetic-geometric-return",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F02",
        "family": "Financial Arithmetic, Time Value, and Returns",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-arithmetic-time-value-and-returns/arithmetic-geometric-return",
        "entry": "arithmeticVersusGeometricAverageReturn",
        "params": [
          "input"
        ],
        "exports": [
          "arithmeticVersusGeometricAverageReturn"
        ],
        "archetype": "record-transform",
        "signature": "arithmeticVersusGeometricAverageReturn(input)"
      },
      "api": {
        "summary": "Averages the same return series two ways, by adding and by compounding, so the gap between the plain mean and the rate actually realised is visible.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F02 topic first reads `principal`, `rate` and `periods` and validates them before any per-topic branch runs. Before reaching this branch the engine also rejects a `startValue` or `endValue` that is zero or negative (omitting them entirely is not caught, because `Number(undefined)` is `NaN`), and `returns` to be a non-empty array of finite numbers none of which is at or below -1. Only `returns` feeds the result; the rest are validated but not used.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ arithmeticAverage: number; geometricAverage: number }",
          "description": "`arithmeticAverage` is the plain mean of the series. `geometricAverage` is the compound growth factor taken to the power `1 / n` and reduced by 1, where n is the number of returns."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "principal is negative, periods is negative, or rate is at or below -1",
            "behaviour": "throws RangeError"
          },
          {
            "when": "startValue or endValue is zero or negative",
            "behaviour": "throws RangeError"
          },
          {
            "when": "returns is missing, empty, not an array, or contains a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of returns is at or below -1, a loss of 100% or worse",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F02-A09.json",
        "call": "arithmeticVersusGeometricAverageReturn({\"principal\":1000,\"rate\":0.05,\"periods\":3,\"compoundsPerPeriod\":12,\"futureValue\":1200,\"cashFlows\":[-1000,400,400,400],\"startValue\":100,\"endValue\":110,\"returns\":[0.1,-0.05,0.08],\"frequency\":12,\"periodicReturn\":0.01})",
        "args": [
          {
            "value": {
              "principal": 1000,
              "rate": 0.05,
              "periods": 3,
              "compoundsPerPeriod": 12,
              "futureValue": 1200,
              "cashFlows": [
                -1000,
                400,
                400,
                400
              ],
              "startValue": 100,
              "endValue": 110,
              "returns": [
                0.1,
                -0.05,
                0.08
              ],
              "frequency": 12,
              "periodicReturn": 0.01
            },
            "elided": null
          }
        ],
        "output": {
          "arithmeticAverage": 0.043333333333333335,
          "geometricAverage": 0.04115010832757027
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: arithmeticAverage, geometricAverage"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a09/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a09/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a09/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Arithmetic versus Geometric Average Return — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: arithmetic mean = (r1 + r2 + ... + rn)/n; geometric mean = [(1+r1)...(1+rn)]^(1/n) - 1\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "CFA_QM - CFA Institute Quantitative Methods Study Session",
          "title": "CFA_QM - CFA Institute Quantitative Methods Study Session",
          "author": "CFA Institute",
          "url": null
        },
        {
          "key": "INVESTOR_RETURN - Annual Return",
          "title": "INVESTOR_RETURN - Annual Return",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/arithmetic-geometric-return/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-arithmetic-time-value-and-returns/arithmetic-geometric-return/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F02-A10",
      "name": "Return Annualization and Deannualization",
      "headline": null,
      "slug": "annualization-deannualization",
      "path": "foundations/financial-arithmetic-time-value-and-returns/annualization-deannualization",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F02",
        "family": "Financial Arithmetic, Time Value, and Returns",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-arithmetic-time-value-and-returns/annualization-deannualization",
        "entry": "returnAnnualizationAndDeannualization",
        "params": [
          "input"
        ],
        "exports": [
          "returnAnnualizationAndDeannualization"
        ],
        "archetype": "record-transform",
        "signature": "returnAnnualizationAndDeannualization(input)"
      },
      "api": {
        "summary": "Scales a single-period return up to an annual figure by compounding it `frequency` times, then scales that annual figure back down to confirm the two conversions are inverses.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F02 topic first reads `principal`, `rate` and `periods` and validates them before any per-topic branch runs. This branch sits at the end of the chain, so the engine also rejects a `startValue` or `endValue` that is zero or negative (omitting them entirely is not caught, because `Number(undefined)` is `NaN`) and requires `returns` to be a non-empty array of finite numbers none of which is at or below -1, even though none of them affect the answer. The result depends only on `periodicReturn`, the return over one period, and `frequency`, the number of such periods in a year.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ annualizedReturn: number; deannualizedReturn: number }",
          "description": "`annualizedReturn` is `(1 + periodicReturn) ** frequency - 1`. `deannualizedReturn` takes that result back down by the `frequency` root, recovering `periodicReturn`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "principal is negative, periods is negative, or rate is at or below -1",
            "behaviour": "throws RangeError"
          },
          {
            "when": "startValue or endValue is zero or negative",
            "behaviour": "throws RangeError"
          },
          {
            "when": "returns is missing, empty, not an array, or contains a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of returns is at or below -1, a loss of 100% or worse",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F02-A10.json",
        "call": "returnAnnualizationAndDeannualization({\"principal\":1000,\"rate\":0.05,\"periods\":3,\"compoundsPerPeriod\":12,\"futureValue\":1200,\"cashFlows\":[-1000,400,400,400],\"startValue\":100,\"endValue\":110,\"returns\":[0.1,-0.05,0.08],\"frequency\":12,\"periodicReturn\":0.01})",
        "args": [
          {
            "value": {
              "principal": 1000,
              "rate": 0.05,
              "periods": 3,
              "compoundsPerPeriod": 12,
              "futureValue": 1200,
              "cashFlows": [
                -1000,
                400,
                400,
                400
              ],
              "startValue": 100,
              "endValue": 110,
              "returns": [
                0.1,
                -0.05,
                0.08
              ],
              "frequency": 12,
              "periodicReturn": 0.01
            },
            "elided": null
          }
        ],
        "output": {
          "annualizedReturn": 0.12682503013196977,
          "deannualizedReturn": 0.010000000000000009
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: annualizedReturn, deannualizedReturn"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a10/static/concept-anatomy.svg"
          },
          {
            "file": "lesson-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a10/static/lesson-map.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f02-a10/static/mistake-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "lesson-flow.md",
            "caption": "Return Annualization and Deannualization — four-part map",
            "source": "flowchart LR\n    A[\"Name the input\"] --> B[\"Apply: annualized = (1 + HPR)^(1/years) - 1; target period = (1 + annual rate)^(years) - 1\"]\n    B --> C[\"Check units and boundary\"]\n    C --> D[\"Explain the output\"]"
          }
        ]
      },
      "references": [
        {
          "key": "INVESTOR_RETURN - Annual Return",
          "title": "INVESTOR_RETURN - Annual Return",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "CFA_QM - CFA Institute Quantitative Methods Study Session",
          "title": "CFA_QM - CFA Institute Quantitative Methods Study Session",
          "author": "CFA Institute",
          "url": null
        },
        {
          "key": "CFA_TVM - Time Value of Money in Finance",
          "title": "CFA_TVM - Time Value of Money in Finance",
          "author": "CFA Institute",
          "url": null
        },
        {
          "key": "Author-derived and synthetic boundary",
          "title": "Author-derived and synthetic boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-arithmetic-time-value-and-returns/annualization-deannualization/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-arithmetic-time-value-and-returns/annualization-deannualization/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F03-A01",
      "name": "Observations, Entities, Variables, and Datasets",
      "headline": null,
      "slug": "observations-entities-variables-and-datasets",
      "path": "foundations/data-variables-samples-and-measurement/observations-entities-variables-and-datasets",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F03",
        "family": "Data, Variables, Samples, and Measurement",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/data-variables-samples-and-measurement/observations-entities-variables-and-datasets",
        "entry": "observationsEntitiesVariablesAndDatasets",
        "params": [
          "input"
        ],
        "exports": [
          "observationsEntitiesVariablesAndDatasets"
        ],
        "archetype": "record-transform",
        "signature": "observationsEntitiesVariablesAndDatasets(input)"
      },
      "api": {
        "summary": "Counts what a table actually contains: how many rows, how many distinct columns across all of them, and how many distinct entities those rows describe.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F03 topic first reads `rows`, which must be a non-empty array of row objects, and derives the sorted union of every key seen across them before any per-topic branch runs. This topic reads each row's `entity` field and no other keys.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ observations: number; variables: number; entities: number; columns: string[] }",
          "description": "`observations` is the row count and `variables` the number of distinct column names. `entities` counts the distinct `entity` values across rows, so rows without one collapse into a single bucket. `columns` is the union of every key present on any row, sorted alphabetically."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "rows is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(r * c)",
          "space": "O(r * c)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F03-A01.json",
        "call": "observationsEntitiesVariablesAndDatasets({\"rows\":[{\"entity\":\"A\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":10,\"rating\":\"low\"},{\"entity\":\"A\",\"timestamp\":\"2025-01-02T00:00:00Z\",\"value\":null,\"rating\":\"medium\",\"censored\":true},{\"entity\":\"B\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":12,\"rating\":\"high\"}],\"ordinalColumns\":[\"rating\"],\"populationSize\":100,\"frameSize\":80,\"keyColumns\":[\"entity\",\"timestamp\"],\"truncationRule\":\"values below 5 excluded\",\"measurements\":[9.9,10,10.1,10],\"referenceValue\":10,\"vintages\":[{\"availableAt\":\"2025-02-01T00:00:00Z\",\"value\":100},{\"availableAt\":\"2025-03-01T00:00:00Z\",\"value\":102},{\"availableAt\":\"2025-04-01T00:00:00Z\",\"value\":101}],\"asOf\":\"2025-03-15T00:00:00Z\",\"provenance\":{\"source\":\"teaching.csv\",\"owner\":\"Fintech Builder\",\"license\":\"CC-BY-4.0\",\"retrievedAt\":\"2026-08-10\",\"transformations\":[\"parse\",\"validate\"]}})",
        "args": [
          {
            "value": {
              "rows": [
                {
                  "entity": "A",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 10,
                  "rating": "low"
                },
                {
                  "entity": "A",
                  "timestamp": "2025-01-02T00:00:00Z",
                  "value": null,
                  "rating": "medium",
                  "censored": true
                },
                {
                  "entity": "B",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 12,
                  "rating": "high"
                }
              ],
              "ordinalColumns": [
                "rating"
              ],
              "populationSize": 100,
              "frameSize": 80,
              "keyColumns": [
                "entity",
                "timestamp"
              ],
              "truncationRule": "values below 5 excluded",
              "measurements": [
                9.9,
                10,
                10.1,
                10
              ],
              "referenceValue": 10,
              "vintages": [
                {
                  "availableAt": "2025-02-01T00:00:00Z",
                  "value": 100
                },
                {
                  "availableAt": "2025-03-01T00:00:00Z",
                  "value": 102
                },
                {
                  "availableAt": "2025-04-01T00:00:00Z",
                  "value": 101
                }
              ],
              "asOf": "2025-03-15T00:00:00Z",
              "provenance": {
                "source": "teaching.csv",
                "owner": "Fintech Builder",
                "license": "CC-BY-4.0",
                "retrievedAt": "2026-08-10",
                "transformations": [
                  "parse",
                  "validate"
                ]
              }
            },
            "elided": null
          }
        ],
        "output": {
          "observations": 4,
          "variables": 5
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: observations, variables"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a01/static/article-hero.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a01/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a01/static/mistake-contrast.svg"
          },
          {
            "file": "teaching-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a01/static/teaching-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "concept-flow.md",
            "caption": "Concept flow — D00-F03-A01",
            "source": "flowchart LR\n    A[\"Synthetic records\"] --> B[\"Declare meaning\"]\n    B --> C[\"Run diagnostic\"]\n    C --> D{\"Assumption survives?\"}\n    D -->|Yes| E[\"Explain: observations = 4; variables = 5\"]\n    D -->|No| F[\"Stop and repair metadata\"]"
          }
        ]
      },
      "references": [
        {
          "key": "1. W3C Data on the Web Best Practices",
          "title": "1. W3C Data on the Web Best Practices",
          "author": null,
          "url": null
        },
        {
          "key": "2. U.S. Census Bureau",
          "title": "Sample Size Definitions",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/data-variables-samples-and-measurement/observations-entities-variables-and-datasets/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/data-variables-samples-and-measurement/observations-entities-variables-and-datasets/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F03-A02",
      "name": "Numeric, Categorical, Ordinal, and Binary Variables",
      "headline": null,
      "slug": "numeric-categorical-ordinal-and-binary-variables",
      "path": "foundations/data-variables-samples-and-measurement/numeric-categorical-ordinal-and-binary-variables",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F03",
        "family": "Data, Variables, Samples, and Measurement",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/data-variables-samples-and-measurement/numeric-categorical-ordinal-and-binary-variables",
        "entry": "numericCategoricalOrdinalAndBinaryVariables",
        "params": [
          "input"
        ],
        "exports": [
          "numericCategoricalOrdinalAndBinaryVariables"
        ],
        "archetype": "record-transform",
        "signature": "numericCategoricalOrdinalAndBinaryVariables(input)"
      },
      "api": {
        "summary": "Classifies every column of a table as binary, numeric, ordinal or categorical by inspecting the values actually present in it.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F03 topic first reads `rows`, which must be a non-empty array of row objects, and derives the sorted union of every key seen across them before any per-topic branch runs. This topic then reads `ordinalColumns`, an optional array of column names that should be treated as ordered rather than merely categorical; it defaults to empty.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ types: Record<string, string> }",
          "description": "`types` maps each column name to one of `binary`, `numeric`, `ordinal` or `categorical`. Null and undefined entries are ignored when judging a column. A column whose remaining values are all booleans is `binary`; all numbers with two or fewer distinct values is also `binary`, otherwise `numeric`; anything else is `ordinal` when the column is listed in `ordinalColumns` and `categorical` when it is not."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "rows is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(r * c)",
          "space": "O(r * c)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F03-A02.json",
        "call": "numericCategoricalOrdinalAndBinaryVariables({\"rows\":[{\"entity\":\"A\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":10,\"rating\":\"low\"},{\"entity\":\"A\",\"timestamp\":\"2025-01-02T00:00:00Z\",\"value\":null,\"rating\":\"medium\",\"censored\":true},{\"entity\":\"B\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":12,\"rating\":\"high\"}],\"ordinalColumns\":[\"rating\"],\"populationSize\":100,\"frameSize\":80,\"keyColumns\":[\"entity\",\"timestamp\"],\"truncationRule\":\"values below 5 excluded\",\"measurements\":[9.9,10,10.1,10],\"referenceValue\":10,\"vintages\":[{\"availableAt\":\"2025-02-01T00:00:00Z\",\"value\":100},{\"availableAt\":\"2025-03-01T00:00:00Z\",\"value\":102},{\"availableAt\":\"2025-04-01T00:00:00Z\",\"value\":101}],\"asOf\":\"2025-03-15T00:00:00Z\",\"provenance\":{\"source\":\"teaching.csv\",\"owner\":\"Fintech Builder\",\"license\":\"CC-BY-4.0\",\"retrievedAt\":\"2026-08-10\",\"transformations\":[\"parse\",\"validate\"]}})",
        "args": [
          {
            "value": {
              "rows": [
                {
                  "entity": "A",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 10,
                  "rating": "low"
                },
                {
                  "entity": "A",
                  "timestamp": "2025-01-02T00:00:00Z",
                  "value": null,
                  "rating": "medium",
                  "censored": true
                },
                {
                  "entity": "B",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 12,
                  "rating": "high"
                }
              ],
              "ordinalColumns": [
                "rating"
              ],
              "populationSize": 100,
              "frameSize": 80,
              "keyColumns": [
                "entity",
                "timestamp"
              ],
              "truncationRule": "values below 5 excluded",
              "measurements": [
                9.9,
                10,
                10.1,
                10
              ],
              "referenceValue": 10,
              "vintages": [
                {
                  "availableAt": "2025-02-01T00:00:00Z",
                  "value": 100
                },
                {
                  "availableAt": "2025-03-01T00:00:00Z",
                  "value": 102
                },
                {
                  "availableAt": "2025-04-01T00:00:00Z",
                  "value": 101
                }
              ],
              "asOf": "2025-03-15T00:00:00Z",
              "provenance": {
                "source": "teaching.csv",
                "owner": "Fintech Builder",
                "license": "CC-BY-4.0",
                "retrievedAt": "2026-08-10",
                "transformations": [
                  "parse",
                  "validate"
                ]
              }
            },
            "elided": null
          }
        ],
        "output": {
          "types": {
            "censored": "binary",
            "entity": "categorical",
            "rating": "ordinal",
            "timestamp": "categorical",
            "value": "numeric"
          }
        },
        "outputElided": null,
        "outputShape": "object with 1 field: types"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a02/static/article-hero.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a02/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a02/static/mistake-contrast.svg"
          },
          {
            "file": "teaching-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a02/static/teaching-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "concept-flow.md",
            "caption": "Concept flow — D00-F03-A02",
            "source": "flowchart LR\n    A[\"Synthetic records\"] --> B[\"Declare meaning\"]\n    B --> C[\"Run diagnostic\"]\n    C --> D{\"Assumption survives?\"}\n    D -->|Yes| E[\"Explain: value → numeric; rating → ordinal; censored → binary\"]\n    D -->|No| F[\"Stop and repair metadata\"]"
          }
        ]
      },
      "references": [
        {
          "key": "1. pandas User Guide",
          "title": "Categorical Data",
          "author": null,
          "url": null
        },
        {
          "key": "2. W3C Data on the Web Best Practices",
          "title": "2. W3C Data on the Web Best Practices",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/data-variables-samples-and-measurement/numeric-categorical-ordinal-and-binary-variables/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/data-variables-samples-and-measurement/numeric-categorical-ordinal-and-binary-variables/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F03-A03",
      "name": "Population, Sample, Census, and Sampling Frame",
      "headline": null,
      "slug": "population-sample-census-and-sampling-frame",
      "path": "foundations/data-variables-samples-and-measurement/population-sample-census-and-sampling-frame",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F03",
        "family": "Data, Variables, Samples, and Measurement",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/data-variables-samples-and-measurement/population-sample-census-and-sampling-frame",
        "entry": "populationSampleCensusAndSamplingFrame",
        "params": [
          "input"
        ],
        "exports": [
          "populationSampleCensusAndSamplingFrame"
        ],
        "archetype": "record-transform",
        "signature": "populationSampleCensusAndSamplingFrame(input)"
      },
      "api": {
        "summary": "Relates the rows in hand to the population they are meant to represent and to the frame they were drawn from, reporting the sampling fraction and the frame's coverage.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F03 topic first reads `rows`, which must be a non-empty array of row objects, and derives the sorted union of every key seen across them before any per-topic branch runs. This topic then reads `populationSize`, the size of the target population, and `frameSize`, the size of the list actually sampled from. Both are coerced with `Number` and neither is range-checked.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ sampleSize: number; populationSize: number; samplingFraction: number; frameCoverage: number; isCensus: boolean }",
          "description": "`sampleSize` is the row count and `populationSize` echoes the input. `samplingFraction` is sample over population and `frameCoverage` is frame over population. `isCensus` is true when the sample size equals the population size."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "rows is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(r * c)",
          "space": "O(r * c)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F03-A03.json",
        "call": "populationSampleCensusAndSamplingFrame({\"rows\":[{\"entity\":\"A\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":10,\"rating\":\"low\"},{\"entity\":\"A\",\"timestamp\":\"2025-01-02T00:00:00Z\",\"value\":null,\"rating\":\"medium\",\"censored\":true},{\"entity\":\"B\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":12,\"rating\":\"high\"}],\"ordinalColumns\":[\"rating\"],\"populationSize\":100,\"frameSize\":80,\"keyColumns\":[\"entity\",\"timestamp\"],\"truncationRule\":\"values below 5 excluded\",\"measurements\":[9.9,10,10.1,10],\"referenceValue\":10,\"vintages\":[{\"availableAt\":\"2025-02-01T00:00:00Z\",\"value\":100},{\"availableAt\":\"2025-03-01T00:00:00Z\",\"value\":102},{\"availableAt\":\"2025-04-01T00:00:00Z\",\"value\":101}],\"asOf\":\"2025-03-15T00:00:00Z\",\"provenance\":{\"source\":\"teaching.csv\",\"owner\":\"Fintech Builder\",\"license\":\"CC-BY-4.0\",\"retrievedAt\":\"2026-08-10\",\"transformations\":[\"parse\",\"validate\"]}})",
        "args": [
          {
            "value": {
              "rows": [
                {
                  "entity": "A",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 10,
                  "rating": "low"
                },
                {
                  "entity": "A",
                  "timestamp": "2025-01-02T00:00:00Z",
                  "value": null,
                  "rating": "medium",
                  "censored": true
                },
                {
                  "entity": "B",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 12,
                  "rating": "high"
                }
              ],
              "ordinalColumns": [
                "rating"
              ],
              "populationSize": 100,
              "frameSize": 80,
              "keyColumns": [
                "entity",
                "timestamp"
              ],
              "truncationRule": "values below 5 excluded",
              "measurements": [
                9.9,
                10,
                10.1,
                10
              ],
              "referenceValue": 10,
              "vintages": [
                {
                  "availableAt": "2025-02-01T00:00:00Z",
                  "value": 100
                },
                {
                  "availableAt": "2025-03-01T00:00:00Z",
                  "value": 102
                },
                {
                  "availableAt": "2025-04-01T00:00:00Z",
                  "value": 101
                }
              ],
              "asOf": "2025-03-15T00:00:00Z",
              "provenance": {
                "source": "teaching.csv",
                "owner": "Fintech Builder",
                "license": "CC-BY-4.0",
                "retrievedAt": "2026-08-10",
                "transformations": [
                  "parse",
                  "validate"
                ]
              }
            },
            "elided": null
          }
        ],
        "output": {
          "sampleSize": 4,
          "populationSize": 100
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: sampleSize, populationSize"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a03/static/article-hero.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a03/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a03/static/mistake-contrast.svg"
          },
          {
            "file": "teaching-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a03/static/teaching-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "concept-flow.md",
            "caption": "Concept flow — D00-F03-A03",
            "source": "flowchart LR\n    A[\"Synthetic records\"] --> B[\"Declare meaning\"]\n    B --> C[\"Run diagnostic\"]\n    C --> D{\"Assumption survives?\"}\n    D -->|Yes| E[\"Explain: sample observations = 4; population = 100; frame coverage = 80%\"]\n    D -->|No| F[\"Stop and repair metadata\"]"
          }
        ]
      },
      "references": [
        {
          "key": "1. U.S. Census Bureau",
          "title": "Sample Size Definitions",
          "author": null,
          "url": null
        },
        {
          "key": "2. NIST/SEMATECH e-Handbook Glossary",
          "title": "2. NIST/SEMATECH e-Handbook Glossary",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/data-variables-samples-and-measurement/population-sample-census-and-sampling-frame/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/data-variables-samples-and-measurement/population-sample-census-and-sampling-frame/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F03-A04",
      "name": "Cross-Sectional, Time-Series, Panel, and Event Data",
      "headline": null,
      "slug": "cross-sectional-time-series-panel-and-event-data",
      "path": "foundations/data-variables-samples-and-measurement/cross-sectional-time-series-panel-and-event-data",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F03",
        "family": "Data, Variables, Samples, and Measurement",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/data-variables-samples-and-measurement/cross-sectional-time-series-panel-and-event-data",
        "entry": "crossSectionalTimeSeriesPanelAndEventData",
        "params": [
          "input"
        ],
        "exports": [
          "crossSectionalTimeSeriesPanelAndEventData"
        ],
        "archetype": "record-transform",
        "signature": "crossSectionalTimeSeriesPanelAndEventData(input)"
      },
      "api": {
        "summary": "Infers a table's layout from the shape of its own keys, deciding whether the rows are cross-sectional, a time series, a panel, or event records.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F03 topic first reads `rows`, which must be a non-empty array of row objects, and derives the sorted union of every key seen across them before any per-topic branch runs. This topic reads each row's `entity` and `timestamp` fields and checks whether an `event` key is present on any row.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ layout: string; entityCount: number; timeCount: number }",
          "description": "`layout` is `panel` when both entities and timestamps vary, `time-series` when only timestamps do, and `cross-sectional` otherwise; the presence of an `event` key on any row overrides all three with `event`. That override is a presence test only: the key's value is never inspected, so a null `event` value still yields `event`, and the semantic question of whether the column records occurrences is left to the reader. `entityCount` and `timeCount` are the distinct counts behind that decision."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "rows is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(r * c)",
          "space": "O(r * c)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F03-A04.json",
        "call": "crossSectionalTimeSeriesPanelAndEventData({\"rows\":[{\"entity\":\"A\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":10,\"rating\":\"low\"},{\"entity\":\"A\",\"timestamp\":\"2025-01-02T00:00:00Z\",\"value\":null,\"rating\":\"medium\",\"censored\":true},{\"entity\":\"B\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":12,\"rating\":\"high\"}],\"ordinalColumns\":[\"rating\"],\"populationSize\":100,\"frameSize\":80,\"keyColumns\":[\"entity\",\"timestamp\"],\"truncationRule\":\"values below 5 excluded\",\"measurements\":[9.9,10,10.1,10],\"referenceValue\":10,\"vintages\":[{\"availableAt\":\"2025-02-01T00:00:00Z\",\"value\":100},{\"availableAt\":\"2025-03-01T00:00:00Z\",\"value\":102},{\"availableAt\":\"2025-04-01T00:00:00Z\",\"value\":101}],\"asOf\":\"2025-03-15T00:00:00Z\",\"provenance\":{\"source\":\"teaching.csv\",\"owner\":\"Fintech Builder\",\"license\":\"CC-BY-4.0\",\"retrievedAt\":\"2026-08-10\",\"transformations\":[\"parse\",\"validate\"]}})",
        "args": [
          {
            "value": {
              "rows": [
                {
                  "entity": "A",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 10,
                  "rating": "low"
                },
                {
                  "entity": "A",
                  "timestamp": "2025-01-02T00:00:00Z",
                  "value": null,
                  "rating": "medium",
                  "censored": true
                },
                {
                  "entity": "B",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 12,
                  "rating": "high"
                }
              ],
              "ordinalColumns": [
                "rating"
              ],
              "populationSize": 100,
              "frameSize": 80,
              "keyColumns": [
                "entity",
                "timestamp"
              ],
              "truncationRule": "values below 5 excluded",
              "measurements": [
                9.9,
                10,
                10.1,
                10
              ],
              "referenceValue": 10,
              "vintages": [
                {
                  "availableAt": "2025-02-01T00:00:00Z",
                  "value": 100
                },
                {
                  "availableAt": "2025-03-01T00:00:00Z",
                  "value": 102
                },
                {
                  "availableAt": "2025-04-01T00:00:00Z",
                  "value": 101
                }
              ],
              "asOf": "2025-03-15T00:00:00Z",
              "provenance": {
                "source": "teaching.csv",
                "owner": "Fintech Builder",
                "license": "CC-BY-4.0",
                "retrievedAt": "2026-08-10",
                "transformations": [
                  "parse",
                  "validate"
                ]
              }
            },
            "elided": null
          }
        ],
        "output": {
          "layout": "panel",
          "entityCount": 2
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: layout, entityCount"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a04/static/article-hero.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a04/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a04/static/mistake-contrast.svg"
          },
          {
            "file": "teaching-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a04/static/teaching-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "concept-flow.md",
            "caption": "Concept flow — D00-F03-A04",
            "source": "flowchart LR\n    A[\"Synthetic records\"] --> B[\"Declare meaning\"]\n    B --> C[\"Run diagnostic\"]\n    C --> D{\"Assumption survives?\"}\n    D -->|Yes| E[\"Explain: layout = panel; entity count = 2; time count = 2\"]\n    D -->|No| F[\"Stop and repair metadata\"]"
          }
        ]
      },
      "references": [
        {
          "key": "1. pandas User Guide",
          "title": "Time Series and Date Functionality",
          "author": null,
          "url": null
        },
        {
          "key": "2. W3C Data on the Web Best Practices",
          "title": "2. W3C Data on the Web Best Practices",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/data-variables-samples-and-measurement/cross-sectional-time-series-panel-and-event-data/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/data-variables-samples-and-measurement/cross-sectional-time-series-panel-and-event-data/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F03-A05",
      "name": "Identifiers, Keys, Joins, and Data Grain",
      "headline": null,
      "slug": "identifiers-keys-joins-and-data-grain",
      "path": "foundations/data-variables-samples-and-measurement/identifiers-keys-joins-and-data-grain",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F03",
        "family": "Data, Variables, Samples, and Measurement",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/data-variables-samples-and-measurement/identifiers-keys-joins-and-data-grain",
        "entry": "identifiersKeysJoinsAndDataGrain",
        "params": [
          "input"
        ],
        "exports": [
          "identifiersKeysJoinsAndDataGrain"
        ],
        "archetype": "record-transform",
        "signature": "identifiersKeysJoinsAndDataGrain(input)"
      },
      "api": {
        "summary": "Checks whether a proposed set of key columns really identifies one row each, which is what makes a table safe to join.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F03 topic first reads `rows`, which must be a non-empty array of row objects, and derives the sorted union of every key seen across them before any per-topic branch runs. This topic then reads `keyColumns`, an optional array of column names forming the candidate key; it defaults to `entity` and `timestamp`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ grain: string; unique: boolean; duplicateKeys: number }",
          "description": "`grain` is a label built from the key column names. `duplicateKeys` is the number of rows beyond the first that repeat a key combination, and `unique` is true exactly when that count is 0."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "rows is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(r * c)",
          "space": "O(r * c)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F03-A05.json",
        "call": "identifiersKeysJoinsAndDataGrain({\"rows\":[{\"entity\":\"A\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":10,\"rating\":\"low\"},{\"entity\":\"A\",\"timestamp\":\"2025-01-02T00:00:00Z\",\"value\":null,\"rating\":\"medium\",\"censored\":true},{\"entity\":\"B\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":12,\"rating\":\"high\"}],\"ordinalColumns\":[\"rating\"],\"populationSize\":100,\"frameSize\":80,\"keyColumns\":[\"entity\",\"timestamp\"],\"truncationRule\":\"values below 5 excluded\",\"measurements\":[9.9,10,10.1,10],\"referenceValue\":10,\"vintages\":[{\"availableAt\":\"2025-02-01T00:00:00Z\",\"value\":100},{\"availableAt\":\"2025-03-01T00:00:00Z\",\"value\":102},{\"availableAt\":\"2025-04-01T00:00:00Z\",\"value\":101}],\"asOf\":\"2025-03-15T00:00:00Z\",\"provenance\":{\"source\":\"teaching.csv\",\"owner\":\"Fintech Builder\",\"license\":\"CC-BY-4.0\",\"retrievedAt\":\"2026-08-10\",\"transformations\":[\"parse\",\"validate\"]}})",
        "args": [
          {
            "value": {
              "rows": [
                {
                  "entity": "A",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 10,
                  "rating": "low"
                },
                {
                  "entity": "A",
                  "timestamp": "2025-01-02T00:00:00Z",
                  "value": null,
                  "rating": "medium",
                  "censored": true
                },
                {
                  "entity": "B",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 12,
                  "rating": "high"
                }
              ],
              "ordinalColumns": [
                "rating"
              ],
              "populationSize": 100,
              "frameSize": 80,
              "keyColumns": [
                "entity",
                "timestamp"
              ],
              "truncationRule": "values below 5 excluded",
              "measurements": [
                9.9,
                10,
                10.1,
                10
              ],
              "referenceValue": 10,
              "vintages": [
                {
                  "availableAt": "2025-02-01T00:00:00Z",
                  "value": 100
                },
                {
                  "availableAt": "2025-03-01T00:00:00Z",
                  "value": 102
                },
                {
                  "availableAt": "2025-04-01T00:00:00Z",
                  "value": 101
                }
              ],
              "asOf": "2025-03-15T00:00:00Z",
              "provenance": {
                "source": "teaching.csv",
                "owner": "Fintech Builder",
                "license": "CC-BY-4.0",
                "retrievedAt": "2026-08-10",
                "transformations": [
                  "parse",
                  "validate"
                ]
              }
            },
            "elided": null
          }
        ],
        "output": {
          "grain": "entity × timestamp",
          "unique": true
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: grain, unique"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a05/static/article-hero.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a05/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a05/static/mistake-contrast.svg"
          },
          {
            "file": "teaching-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a05/static/teaching-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "concept-flow.md",
            "caption": "Concept flow — D00-F03-A05",
            "source": "flowchart LR\n    A[\"Synthetic records\"] --> B[\"Declare meaning\"]\n    B --> C[\"Run diagnostic\"]\n    C --> D{\"Assumption survives?\"}\n    D -->|Yes| E[\"Explain: grain = entity × timestamp; composite key unique = true\"]\n    D -->|No| F[\"Stop and repair metadata\"]"
          }
        ]
      },
      "references": [
        {
          "key": "1. PostgreSQL Documentation",
          "title": "Constraints",
          "author": null,
          "url": null
        },
        {
          "key": "2. pandas API Reference",
          "title": "merge",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/data-variables-samples-and-measurement/identifiers-keys-joins-and-data-grain/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/data-variables-samples-and-measurement/identifiers-keys-joins-and-data-grain/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F03-A06",
      "name": "Timestamps, Time Zones, Calendars, and Observation Time",
      "headline": null,
      "slug": "timestamps-time-zones-calendars-and-observation-time",
      "path": "foundations/data-variables-samples-and-measurement/timestamps-time-zones-calendars-and-observation-time",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F03",
        "family": "Data, Variables, Samples, and Measurement",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/data-variables-samples-and-measurement/timestamps-time-zones-calendars-and-observation-time",
        "entry": "timestampsTimeZonesCalendarsAndObservationTime",
        "params": [
          "input"
        ],
        "exports": [
          "timestampsTimeZonesCalendarsAndObservationTime"
        ],
        "archetype": "record-transform",
        "signature": "timestampsTimeZonesCalendarsAndObservationTime(input)"
      },
      "api": {
        "summary": "Audits a table's timestamps: whether the rows arrive in chronological order, whether every stamp carries a zone, and which rows sit at the two ends of the span.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F03 topic first reads `rows`, which must be a non-empty array of row objects, and derives the sorted union of every key seen across them before any per-topic branch runs. This topic reads each row's `timestamp` field, parsed as a date string, and reads no other keys.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ordered: boolean; timezoneAware: boolean; first: string; last: string }",
          "description": "`ordered` is true when no row's timestamp precedes the one before it. `timezoneAware` is true only when every timestamp ends in a `Z` or an explicit numeric offset. `first` and `last` are the raw timestamp strings of the earliest and latest rows."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "rows is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(r * c)",
          "space": "O(r * c)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F03-A06.json",
        "call": "timestampsTimeZonesCalendarsAndObservationTime({\"rows\":[{\"entity\":\"A\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":10,\"rating\":\"low\"},{\"entity\":\"A\",\"timestamp\":\"2025-01-02T00:00:00Z\",\"value\":null,\"rating\":\"medium\",\"censored\":true},{\"entity\":\"B\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":12,\"rating\":\"high\"}],\"ordinalColumns\":[\"rating\"],\"populationSize\":100,\"frameSize\":80,\"keyColumns\":[\"entity\",\"timestamp\"],\"truncationRule\":\"values below 5 excluded\",\"measurements\":[9.9,10,10.1,10],\"referenceValue\":10,\"vintages\":[{\"availableAt\":\"2025-02-01T00:00:00Z\",\"value\":100},{\"availableAt\":\"2025-03-01T00:00:00Z\",\"value\":102},{\"availableAt\":\"2025-04-01T00:00:00Z\",\"value\":101}],\"asOf\":\"2025-03-15T00:00:00Z\",\"provenance\":{\"source\":\"teaching.csv\",\"owner\":\"Fintech Builder\",\"license\":\"CC-BY-4.0\",\"retrievedAt\":\"2026-08-10\",\"transformations\":[\"parse\",\"validate\"]}})",
        "args": [
          {
            "value": {
              "rows": [
                {
                  "entity": "A",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 10,
                  "rating": "low"
                },
                {
                  "entity": "A",
                  "timestamp": "2025-01-02T00:00:00Z",
                  "value": null,
                  "rating": "medium",
                  "censored": true
                },
                {
                  "entity": "B",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 12,
                  "rating": "high"
                }
              ],
              "ordinalColumns": [
                "rating"
              ],
              "populationSize": 100,
              "frameSize": 80,
              "keyColumns": [
                "entity",
                "timestamp"
              ],
              "truncationRule": "values below 5 excluded",
              "measurements": [
                9.9,
                10,
                10.1,
                10
              ],
              "referenceValue": 10,
              "vintages": [
                {
                  "availableAt": "2025-02-01T00:00:00Z",
                  "value": 100
                },
                {
                  "availableAt": "2025-03-01T00:00:00Z",
                  "value": 102
                },
                {
                  "availableAt": "2025-04-01T00:00:00Z",
                  "value": 101
                }
              ],
              "asOf": "2025-03-15T00:00:00Z",
              "provenance": {
                "source": "teaching.csv",
                "owner": "Fintech Builder",
                "license": "CC-BY-4.0",
                "retrievedAt": "2026-08-10",
                "transformations": [
                  "parse",
                  "validate"
                ]
              }
            },
            "elided": null
          }
        ],
        "output": {
          "ordered": false,
          "timezoneAware": true
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: ordered, timezoneAware"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a06/static/article-hero.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a06/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a06/static/mistake-contrast.svg"
          },
          {
            "file": "teaching-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a06/static/teaching-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "concept-flow.md",
            "caption": "Concept flow — D00-F03-A06",
            "source": "flowchart LR\n    A[\"Synthetic records\"] --> B[\"Declare meaning\"]\n    B --> C[\"Run diagnostic\"]\n    C --> D{\"Assumption survives?\"}\n    D -->|Yes| E[\"Explain: timezone-aware = true; globally ordered = false\"]\n    D -->|No| F[\"Stop and repair metadata\"]"
          }
        ]
      },
      "references": [
        {
          "key": "1. IANA Time Zone Database",
          "title": "Theory and Naming",
          "author": null,
          "url": null
        },
        {
          "key": "2. pandas User Guide",
          "title": "Time Series and Date Functionality",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/data-variables-samples-and-measurement/timestamps-time-zones-calendars-and-observation-time/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/data-variables-samples-and-measurement/timestamps-time-zones-calendars-and-observation-time/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F03-A07",
      "name": "Missing, Nonfinite, Censored, and Truncated Values",
      "headline": null,
      "slug": "missing-nonfinite-censored-and-truncated-values",
      "path": "foundations/data-variables-samples-and-measurement/missing-nonfinite-censored-and-truncated-values",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F03",
        "family": "Data, Variables, Samples, and Measurement",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/data-variables-samples-and-measurement/missing-nonfinite-censored-and-truncated-values",
        "entry": "missingNonfiniteCensoredAndTruncatedValues",
        "params": [
          "input"
        ],
        "exports": [
          "missingNonfiniteCensoredAndTruncatedValues"
        ],
        "archetype": "record-transform",
        "signature": "missingNonfiniteCensoredAndTruncatedValues(input)"
      },
      "api": {
        "summary": "Tallies the ways a table's `value` column can fail to be an ordinary number, separating missing entries, non-finite ones and censored rows.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F03 topic first reads `rows`, which must be a non-empty array of row objects, and derives the sorted union of every key seen across them before any per-topic branch runs. This topic reads each row's `value` and `censored` fields, and reads `truncationRule` at the top level as a flag for whether a truncation rule was applied at all.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ missing: number; nonfinite: number; censored: number; truncated: boolean }",
          "description": "`missing` counts rows whose `value` is null or undefined, `nonfinite` counts numeric values that are infinite or NaN, and `censored` counts rows whose `censored` field is truthy. `truncated` is simply whether `truncationRule` was supplied and truthy, not a count."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "rows is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(r * c)",
          "space": "O(r * c)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F03-A07.json",
        "call": "missingNonfiniteCensoredAndTruncatedValues({\"rows\":[{\"entity\":\"A\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":10,\"rating\":\"low\"},{\"entity\":\"A\",\"timestamp\":\"2025-01-02T00:00:00Z\",\"value\":null,\"rating\":\"medium\",\"censored\":true},{\"entity\":\"B\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":12,\"rating\":\"high\"}],\"ordinalColumns\":[\"rating\"],\"populationSize\":100,\"frameSize\":80,\"keyColumns\":[\"entity\",\"timestamp\"],\"truncationRule\":\"values below 5 excluded\",\"measurements\":[9.9,10,10.1,10],\"referenceValue\":10,\"vintages\":[{\"availableAt\":\"2025-02-01T00:00:00Z\",\"value\":100},{\"availableAt\":\"2025-03-01T00:00:00Z\",\"value\":102},{\"availableAt\":\"2025-04-01T00:00:00Z\",\"value\":101}],\"asOf\":\"2025-03-15T00:00:00Z\",\"provenance\":{\"source\":\"teaching.csv\",\"owner\":\"Fintech Builder\",\"license\":\"CC-BY-4.0\",\"retrievedAt\":\"2026-08-10\",\"transformations\":[\"parse\",\"validate\"]}})",
        "args": [
          {
            "value": {
              "rows": [
                {
                  "entity": "A",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 10,
                  "rating": "low"
                },
                {
                  "entity": "A",
                  "timestamp": "2025-01-02T00:00:00Z",
                  "value": null,
                  "rating": "medium",
                  "censored": true
                },
                {
                  "entity": "B",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 12,
                  "rating": "high"
                }
              ],
              "ordinalColumns": [
                "rating"
              ],
              "populationSize": 100,
              "frameSize": 80,
              "keyColumns": [
                "entity",
                "timestamp"
              ],
              "truncationRule": "values below 5 excluded",
              "measurements": [
                9.9,
                10,
                10.1,
                10
              ],
              "referenceValue": 10,
              "vintages": [
                {
                  "availableAt": "2025-02-01T00:00:00Z",
                  "value": 100
                },
                {
                  "availableAt": "2025-03-01T00:00:00Z",
                  "value": 102
                },
                {
                  "availableAt": "2025-04-01T00:00:00Z",
                  "value": 101
                }
              ],
              "asOf": "2025-03-15T00:00:00Z",
              "provenance": {
                "source": "teaching.csv",
                "owner": "Fintech Builder",
                "license": "CC-BY-4.0",
                "retrievedAt": "2026-08-10",
                "transformations": [
                  "parse",
                  "validate"
                ]
              }
            },
            "elided": null
          }
        ],
        "output": {
          "missing": 1,
          "nonfinite": 0
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: missing, nonfinite"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a07/static/article-hero.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a07/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a07/static/mistake-contrast.svg"
          },
          {
            "file": "teaching-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a07/static/teaching-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "concept-flow.md",
            "caption": "Concept flow — D00-F03-A07",
            "source": "flowchart LR\n    A[\"Synthetic records\"] --> B[\"Declare meaning\"]\n    B --> C[\"Run diagnostic\"]\n    C --> D{\"Assumption survives?\"}\n    D -->|Yes| E[\"Explain: missing = 1; nonfinite = 0\"]\n    D -->|No| F[\"Stop and repair metadata\"]"
          }
        ]
      },
      "references": [
        {
          "key": "1. pandas User Guide",
          "title": "Working with Missing Data",
          "author": null,
          "url": null
        },
        {
          "key": "2. NIST/SEMATECH e-Handbook",
          "title": "Censoring",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/data-variables-samples-and-measurement/missing-nonfinite-censored-and-truncated-values/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/data-variables-samples-and-measurement/missing-nonfinite-censored-and-truncated-values/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F03-A08",
      "name": "Measurement Error, Resolution, Accuracy, and Precision",
      "headline": null,
      "slug": "measurement-error-resolution-accuracy-and-precision",
      "path": "foundations/data-variables-samples-and-measurement/measurement-error-resolution-accuracy-and-precision",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F03",
        "family": "Data, Variables, Samples, and Measurement",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/data-variables-samples-and-measurement/measurement-error-resolution-accuracy-and-precision",
        "entry": "measurementErrorResolutionAccuracyAndPrecision",
        "params": [
          "input"
        ],
        "exports": [
          "measurementErrorResolutionAccuracyAndPrecision"
        ],
        "archetype": "record-transform",
        "signature": "measurementErrorResolutionAccuracyAndPrecision(input)"
      },
      "api": {
        "summary": "Compares repeated measurements against a known reference to separate accuracy from precision, and reports the smallest gap between the distinct values present in the sample.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F03 topic first reads `rows`, which must be a non-empty array of row objects, and derives the sorted union of every key seen across them before any per-topic branch runs, even though this topic does not use them. The calculation itself reads `measurements`, a non-empty array of finite numbers, and `referenceValue`, the true value they are aimed at.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ bias: number; mae: number; resolution: number; precisionStd: number }",
          "description": "`bias` is the mean signed error against `referenceValue` and `mae` is the mean absolute error. `resolution` is the smallest gap between consecutive distinct measurements: an observed spacing in this sample, which is a lower bound on the recording step and not a measurement of the instrument's own display increment. `precisionStd` is the population standard deviation of the measurements, dividing by n rather than n-1."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "rows is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          },
          {
            "when": "measurements is missing, empty, not an array, or contains a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "every measurement is the same number, so no gap between distinct values exists",
            "behaviour": "throws RangeError in TypeScript and ValueError in Python; the topic facade rejects this state rather than reporting a placeholder resolution"
          }
        ],
        "complexity": {
          "time": "O(r * c + m log m)",
          "space": "O(r * c + m)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F03-A08.json",
        "call": "measurementErrorResolutionAccuracyAndPrecision({\"rows\":[{\"entity\":\"A\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":10,\"rating\":\"low\"},{\"entity\":\"A\",\"timestamp\":\"2025-01-02T00:00:00Z\",\"value\":null,\"rating\":\"medium\",\"censored\":true},{\"entity\":\"B\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":12,\"rating\":\"high\"}],\"ordinalColumns\":[\"rating\"],\"populationSize\":100,\"frameSize\":80,\"keyColumns\":[\"entity\",\"timestamp\"],\"truncationRule\":\"values below 5 excluded\",\"measurements\":[9.9,10,10.1,10],\"referenceValue\":10,\"vintages\":[{\"availableAt\":\"2025-02-01T00:00:00Z\",\"value\":100},{\"availableAt\":\"2025-03-01T00:00:00Z\",\"value\":102},{\"availableAt\":\"2025-04-01T00:00:00Z\",\"value\":101}],\"asOf\":\"2025-03-15T00:00:00Z\",\"provenance\":{\"source\":\"teaching.csv\",\"owner\":\"Fintech Builder\",\"license\":\"CC-BY-4.0\",\"retrievedAt\":\"2026-08-10\",\"transformations\":[\"parse\",\"validate\"]}})",
        "args": [
          {
            "value": {
              "rows": [
                {
                  "entity": "A",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 10,
                  "rating": "low"
                },
                {
                  "entity": "A",
                  "timestamp": "2025-01-02T00:00:00Z",
                  "value": null,
                  "rating": "medium",
                  "censored": true
                },
                {
                  "entity": "B",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 12,
                  "rating": "high"
                }
              ],
              "ordinalColumns": [
                "rating"
              ],
              "populationSize": 100,
              "frameSize": 80,
              "keyColumns": [
                "entity",
                "timestamp"
              ],
              "truncationRule": "values below 5 excluded",
              "measurements": [
                9.9,
                10,
                10.1,
                10
              ],
              "referenceValue": 10,
              "vintages": [
                {
                  "availableAt": "2025-02-01T00:00:00Z",
                  "value": 100
                },
                {
                  "availableAt": "2025-03-01T00:00:00Z",
                  "value": 102
                },
                {
                  "availableAt": "2025-04-01T00:00:00Z",
                  "value": 101
                }
              ],
              "asOf": "2025-03-15T00:00:00Z",
              "provenance": {
                "source": "teaching.csv",
                "owner": "Fintech Builder",
                "license": "CC-BY-4.0",
                "retrievedAt": "2026-08-10",
                "transformations": [
                  "parse",
                  "validate"
                ]
              }
            },
            "elided": null
          }
        ],
        "output": {
          "bias": 0,
          "mae": 0.05,
          "resolution": 0.1,
          "precisionStd": 0.0707106781186545
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: bias, mae, resolution, precisionStd"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a08/static/article-hero.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a08/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a08/static/mistake-contrast.svg"
          },
          {
            "file": "teaching-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a08/static/teaching-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "concept-flow.md",
            "caption": "Concept flow — D00-F03-A08",
            "source": "flowchart LR\n    A[\"Synthetic records\"] --> B[\"Declare meaning\"]\n    B --> C[\"Run diagnostic\"]\n    C --> D{\"Assumption survives?\"}\n    D -->|Yes| E[\"Explain: bias = 0.00; mean absolute error = 0.05\"]\n    D -->|No| F[\"Stop and repair metadata\"]"
          }
        ]
      },
      "references": [
        {
          "key": "1. NIST Glossary",
          "title": "Accuracy",
          "author": null,
          "url": null
        },
        {
          "key": "2. NIST Technical Note 1297",
          "title": "Terminology",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/data-variables-samples-and-measurement/measurement-error-resolution-accuracy-and-precision/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/data-variables-samples-and-measurement/measurement-error-resolution-accuracy-and-precision/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F03-A09",
      "name": "Revisions, Vintages, and Point-in-Time Availability",
      "headline": null,
      "slug": "revisions-vintages-and-point-in-time-availability",
      "path": "foundations/data-variables-samples-and-measurement/revisions-vintages-and-point-in-time-availability",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F03",
        "family": "Data, Variables, Samples, and Measurement",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/data-variables-samples-and-measurement/revisions-vintages-and-point-in-time-availability",
        "entry": "revisionsVintagesAndPointInTimeAvailability",
        "params": [
          "input"
        ],
        "exports": [
          "revisionsVintagesAndPointInTimeAvailability"
        ],
        "archetype": "record-transform",
        "signature": "revisionsVintagesAndPointInTimeAvailability(input)"
      },
      "api": {
        "summary": "Picks the value that was genuinely knowable at a given moment by keeping only the vintages published on or before it, which is what stops a backtest reading the future.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F03 topic first reads `rows`, which must be a non-empty array of row objects, and derives the sorted union of every key seen across them before any per-topic branch runs, even though this topic does not use them. The calculation itself reads `asOf`, the cutoff timestamp, and `vintages`, an array of published revisions each carrying an `availableAt` timestamp and a `value`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ asOf: string; value: unknown; vintage: string | null; excludedFutureVintages: number }",
          "description": "`asOf` echoes the cutoff. `value` and `vintage` come from the latest vintage whose `availableAt` is at or before the cutoff, and are both null when no vintage qualifies. `excludedFutureVintages` counts the revisions dropped for being published after the cutoff."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "rows is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(r * c + v log v)",
          "space": "O(r * c + v)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F03-A09.json",
        "call": "revisionsVintagesAndPointInTimeAvailability({\"rows\":[{\"entity\":\"A\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":10,\"rating\":\"low\"},{\"entity\":\"A\",\"timestamp\":\"2025-01-02T00:00:00Z\",\"value\":null,\"rating\":\"medium\",\"censored\":true},{\"entity\":\"B\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":12,\"rating\":\"high\"}],\"ordinalColumns\":[\"rating\"],\"populationSize\":100,\"frameSize\":80,\"keyColumns\":[\"entity\",\"timestamp\"],\"truncationRule\":\"values below 5 excluded\",\"measurements\":[9.9,10,10.1,10],\"referenceValue\":10,\"vintages\":[{\"availableAt\":\"2025-02-01T00:00:00Z\",\"value\":100},{\"availableAt\":\"2025-03-01T00:00:00Z\",\"value\":102},{\"availableAt\":\"2025-04-01T00:00:00Z\",\"value\":101}],\"asOf\":\"2025-03-15T00:00:00Z\",\"provenance\":{\"source\":\"teaching.csv\",\"owner\":\"Fintech Builder\",\"license\":\"CC-BY-4.0\",\"retrievedAt\":\"2026-08-10\",\"transformations\":[\"parse\",\"validate\"]}})",
        "args": [
          {
            "value": {
              "rows": [
                {
                  "entity": "A",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 10,
                  "rating": "low"
                },
                {
                  "entity": "A",
                  "timestamp": "2025-01-02T00:00:00Z",
                  "value": null,
                  "rating": "medium",
                  "censored": true
                },
                {
                  "entity": "B",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 12,
                  "rating": "high"
                }
              ],
              "ordinalColumns": [
                "rating"
              ],
              "populationSize": 100,
              "frameSize": 80,
              "keyColumns": [
                "entity",
                "timestamp"
              ],
              "truncationRule": "values below 5 excluded",
              "measurements": [
                9.9,
                10,
                10.1,
                10
              ],
              "referenceValue": 10,
              "vintages": [
                {
                  "availableAt": "2025-02-01T00:00:00Z",
                  "value": 100
                },
                {
                  "availableAt": "2025-03-01T00:00:00Z",
                  "value": 102
                },
                {
                  "availableAt": "2025-04-01T00:00:00Z",
                  "value": 101
                }
              ],
              "asOf": "2025-03-15T00:00:00Z",
              "provenance": {
                "source": "teaching.csv",
                "owner": "Fintech Builder",
                "license": "CC-BY-4.0",
                "retrievedAt": "2026-08-10",
                "transformations": [
                  "parse",
                  "validate"
                ]
              }
            },
            "elided": null
          }
        ],
        "output": {
          "asOf": "2025-03-15T00:00:00Z",
          "value": 102
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: asOf, value"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a09/static/article-hero.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a09/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a09/static/mistake-contrast.svg"
          },
          {
            "file": "teaching-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a09/static/teaching-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "concept-flow.md",
            "caption": "Concept flow — D00-F03-A09",
            "source": "flowchart LR\n    A[\"Synthetic records\"] --> B[\"Declare meaning\"]\n    B --> C[\"Run diagnostic\"]\n    C --> D{\"Assumption survives?\"}\n    D -->|Yes| E[\"Explain: as-of 2025-03-15 → value 102, not future value 101\"]\n    D -->|No| F[\"Stop and repair metadata\"]"
          }
        ]
      },
      "references": [
        {
          "key": "1. FRED API",
          "title": "Real-Time Periods",
          "author": null,
          "url": null
        },
        {
          "key": "2. FRED API",
          "title": "Series Vintage Dates",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/data-variables-samples-and-measurement/revisions-vintages-and-point-in-time-availability/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/data-variables-samples-and-measurement/revisions-vintages-and-point-in-time-availability/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F03-A10",
      "name": "Data Provenance, Lineage, Ownership, and Licensing",
      "headline": null,
      "slug": "data-provenance-lineage-ownership-and-licensing",
      "path": "foundations/data-variables-samples-and-measurement/data-provenance-lineage-ownership-and-licensing",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F03",
        "family": "Data, Variables, Samples, and Measurement",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/data-variables-samples-and-measurement/data-provenance-lineage-ownership-and-licensing",
        "entry": "dataProvenanceLineageOwnershipAndLicensing",
        "params": [
          "input"
        ],
        "exports": [
          "dataProvenanceLineageOwnershipAndLicensing"
        ],
        "archetype": "record-transform",
        "signature": "dataProvenanceLineageOwnershipAndLicensing(input)"
      },
      "api": {
        "summary": "Checks a dataset's provenance record against the five fields the engine treats as mandatory and reports which of them are absent.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "A plain object. Every F03 topic first reads `rows`, which must be a non-empty array of row objects, and derives the sorted union of every key seen across them before any per-topic branch runs, even though this topic does not use them. The calculation itself reads `provenance`, an optional record that defaults to empty and is checked for `source`, `owner`, `license`, `retrievedAt` and `transformations`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ complete: boolean; missingFields: string[]; lineageSteps: number }",
          "description": "`missingFields` lists whichever of the five required fields is absent or falsy, and `complete` is true only when that list is empty. `lineageSteps` is the length of `provenance.transformations`, or 0 when it is absent."
        },
        "warmup": null,
        "errors": [
          {
            "when": "input is not a plain object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "rows is missing, empty, or not an array",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(r * c)",
          "space": "O(r * c)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F03-A10.json",
        "call": "dataProvenanceLineageOwnershipAndLicensing({\"rows\":[{\"entity\":\"A\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":10,\"rating\":\"low\"},{\"entity\":\"A\",\"timestamp\":\"2025-01-02T00:00:00Z\",\"value\":null,\"rating\":\"medium\",\"censored\":true},{\"entity\":\"B\",\"timestamp\":\"2025-01-01T00:00:00Z\",\"value\":12,\"rating\":\"high\"}],\"ordinalColumns\":[\"rating\"],\"populationSize\":100,\"frameSize\":80,\"keyColumns\":[\"entity\",\"timestamp\"],\"truncationRule\":\"values below 5 excluded\",\"measurements\":[9.9,10,10.1,10],\"referenceValue\":10,\"vintages\":[{\"availableAt\":\"2025-02-01T00:00:00Z\",\"value\":100},{\"availableAt\":\"2025-03-01T00:00:00Z\",\"value\":102},{\"availableAt\":\"2025-04-01T00:00:00Z\",\"value\":101}],\"asOf\":\"2025-03-15T00:00:00Z\",\"provenance\":{\"source\":\"teaching.csv\",\"owner\":\"Fintech Builder\",\"license\":\"CC-BY-4.0\",\"retrievedAt\":\"2026-08-10\",\"transformations\":[\"parse\",\"validate\"]}})",
        "args": [
          {
            "value": {
              "rows": [
                {
                  "entity": "A",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 10,
                  "rating": "low"
                },
                {
                  "entity": "A",
                  "timestamp": "2025-01-02T00:00:00Z",
                  "value": null,
                  "rating": "medium",
                  "censored": true
                },
                {
                  "entity": "B",
                  "timestamp": "2025-01-01T00:00:00Z",
                  "value": 12,
                  "rating": "high"
                }
              ],
              "ordinalColumns": [
                "rating"
              ],
              "populationSize": 100,
              "frameSize": 80,
              "keyColumns": [
                "entity",
                "timestamp"
              ],
              "truncationRule": "values below 5 excluded",
              "measurements": [
                9.9,
                10,
                10.1,
                10
              ],
              "referenceValue": 10,
              "vintages": [
                {
                  "availableAt": "2025-02-01T00:00:00Z",
                  "value": 100
                },
                {
                  "availableAt": "2025-03-01T00:00:00Z",
                  "value": 102
                },
                {
                  "availableAt": "2025-04-01T00:00:00Z",
                  "value": 101
                }
              ],
              "asOf": "2025-03-15T00:00:00Z",
              "provenance": {
                "source": "teaching.csv",
                "owner": "Fintech Builder",
                "license": "CC-BY-4.0",
                "retrievedAt": "2026-08-10",
                "transformations": [
                  "parse",
                  "validate"
                ]
              }
            },
            "elided": null
          }
        ],
        "output": {
          "complete": true,
          "missingFields": []
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: complete, missingFields"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a10/static/article-hero.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a10/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a10/static/mistake-contrast.svg"
          },
          {
            "file": "teaching-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f03-a10/static/teaching-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "concept-flow.md",
            "caption": "Concept flow — D00-F03-A10",
            "source": "flowchart LR\n    A[\"Synthetic records\"] --> B[\"Declare meaning\"]\n    B --> C[\"Run diagnostic\"]\n    C --> D{\"Assumption survives?\"}\n    D -->|Yes| E[\"Explain: required fields complete = true; missing fields = none\"]\n    D -->|No| F[\"Stop and repair metadata\"]"
          }
        ]
      },
      "references": [
        {
          "key": "1. W3C PROV-O: The PROV Ontology",
          "title": "1. W3C PROV-O: The PROV Ontology",
          "author": null,
          "url": null
        },
        {
          "key": "2. W3C Data on the Web Best Practices",
          "title": "2. W3C Data on the Web Best Practices",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/data-variables-samples-and-measurement/data-provenance-lineage-ownership-and-licensing/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/data-variables-samples-and-measurement/data-provenance-lineage-ownership-and-licensing/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F04-A01",
      "name": "Count, Sum, Minimum, Maximum, and Range",
      "headline": null,
      "slug": "count-sum-minimum-maximum-and-range",
      "path": "foundations/location-ranking-and-exploratory-summaries/count-sum-minimum-maximum-and-range",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F04",
        "family": "Location, Ranking, and Exploratory Summaries",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/location-ranking-and-exploratory-summaries/count-sum-minimum-maximum-and-range",
        "entry": "countSumMinimumMaximumAndRange",
        "params": [
          "input"
        ],
        "exports": [
          "countSumMinimumMaximumAndRange"
        ],
        "archetype": "record-transform",
        "signature": "countSumMinimumMaximumAndRange(input)"
      },
      "api": {
        "summary": "Reduces one numeric series to the five headline aggregates: how many observations there are, their total, the smallest and largest value, and the distance between those extremes.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations to summarise, under the key `values`. Entries are coerced with `Number` before use, so numeric strings are accepted and anything that coerces to `NaN` or an infinity is rejected.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ count: number; sum: number; minimum: number; maximum: number; range: number }",
          "description": "`count` is the number of observations, `sum` their total, `minimum` and `maximum` the extremes, and `range` is `maximum - minimum`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F04-A01.json",
        "call": "countSumMinimumMaximumAndRange({\"values\":[1,2,2,4,9],\"weights\":[1,1,2,1,1],\"trimProportion\":0.2,\"bins\":4})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ],
              "weights": [
                1,
                1,
                2,
                1,
                1
              ],
              "trimProportion": 0.2,
              "bins": 4
            },
            "elided": null
          }
        ],
        "output": {
          "count": 5,
          "sum": 18
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: count, sum"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a01/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a01/static/calculation-ledger.svg"
          },
          {
            "file": "comparison-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a01/static/comparison-map.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a01/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a01/static/mistake-contrast.svg"
          },
          {
            "file": "scenario-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a01/static/scenario-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F04-A01",
            "source": "flowchart LR\n    A[\"Finite observations\"] --> B[\"Name units and scope\"]\n    B --> C[\"Freeze: n = number of values; S = Σxᵢ; range = max(x) − min(x)\"]\n    C --> D[\"Calculate full precision\"]\n    D --> E{\"Boundary satisfied?\"}\n    E -->|Yes| F[\"Report count 5 · sum 18 · min 1 · max 9 · range 8\"]\n    E -->|No| G[\"Abstain and repair contract\"]\n    F --> H[\"Pair with distribution context\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Location",
          "author": null,
          "url": null
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Location, Scale, and Shape",
          "author": null,
          "url": null
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/count-sum-minimum-maximum-and-range/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/location-ranking-and-exploratory-summaries/count-sum-minimum-maximum-and-range/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F04-A02",
      "name": "Arithmetic Mean",
      "headline": null,
      "slug": "arithmetic-mean",
      "path": "foundations/location-ranking-and-exploratory-summaries/arithmetic-mean",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F04",
        "family": "Location, Ranking, and Exploratory Summaries",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/location-ranking-and-exploratory-summaries/arithmetic-mean",
        "entry": "arithmeticMean",
        "params": [
          "input"
        ],
        "exports": [
          "arithmeticMean"
        ],
        "archetype": "record-transform",
        "signature": "arithmeticMean(input)"
      },
      "api": {
        "summary": "Divides the sum of a numeric series by the number of observations and reports both the mean and the count it was divided by.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations to average, under the key `values`. Entries are coerced with `Number`, and every one must be finite.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ mean: number; count: number }",
          "description": "`mean` is the arithmetic average and `count` is the divisor used, so the reader can see how many observations stand behind the number."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F04-A02.json",
        "call": "arithmeticMean({\"values\":[1,2,2,4,9],\"weights\":[1,1,2,1,1],\"trimProportion\":0.2,\"bins\":4})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ],
              "weights": [
                1,
                1,
                2,
                1,
                1
              ],
              "trimProportion": 0.2,
              "bins": 4
            },
            "elided": null
          }
        ],
        "output": {
          "mean": 3.6,
          "count": 5
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: mean, count"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a02/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a02/static/calculation-ledger.svg"
          },
          {
            "file": "comparison-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a02/static/comparison-map.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a02/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a02/static/mistake-contrast.svg"
          },
          {
            "file": "scenario-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a02/static/scenario-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F04-A02",
            "source": "flowchart LR\n    A[\"Finite observations\"] --> B[\"Name units and scope\"]\n    B --> C[\"Freeze: x̄ = (1/n) Σxᵢ\"]\n    C --> D[\"Calculate full precision\"]\n    D --> E{\"Boundary satisfied?\"}\n    E -->|Yes| F[\"Report mean = 3.6 because 18 ÷ 5 = 3.6\"]\n    E -->|No| G[\"Abstain and repair contract\"]\n    F --> H[\"Pair with distribution context\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Location",
          "author": null,
          "url": null
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/arithmetic-mean/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/location-ranking-and-exploratory-summaries/arithmetic-mean/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F04-A03",
      "name": "Weighted Mean",
      "headline": null,
      "slug": "weighted-mean",
      "path": "foundations/location-ranking-and-exploratory-summaries/weighted-mean",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F04",
        "family": "Location, Ranking, and Exploratory Summaries",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/location-ranking-and-exploratory-summaries/weighted-mean",
        "entry": "weightedMean",
        "params": [
          "input"
        ],
        "exports": [
          "weightedMean"
        ],
        "archetype": "record-transform",
        "signature": "weightedMean(input)"
      },
      "api": {
        "summary": "Computes a weighted average of `values` using the parallel `weights` series, dividing the sum of value-times-weight products by the total weight.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[]; weights: number[] }",
            "required": true,
            "description": "`values` holds the observations and `weights` the importance attached to each one, position by position. Both are coerced with `Number` and must be finite; the weights are not normalised for you, the function divides by their sum.",
            "constraints": {
              "weights": "same length as `values`, and the weights must not sum to zero"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ weightedMean: number; weightSum: number }",
          "description": "`weightedMean` is the weighted average and `weightSum` is the denominator that was used, which is what tells you whether the weights were proportions or raw counts."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`weights` is missing, empty, or holds a non-finite entry",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`weights` and `values` differ in length, or the weights sum to exactly zero",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F04-A03.json",
        "call": "weightedMean({\"values\":[1,2,2,4,9],\"weights\":[1,1,2,1,1],\"trimProportion\":0.2,\"bins\":4})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ],
              "weights": [
                1,
                1,
                2,
                1,
                1
              ],
              "trimProportion": 0.2,
              "bins": 4
            },
            "elided": null
          }
        ],
        "output": {
          "weightedMean": 3.3333333333333335,
          "weightSum": 6
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: weightedMean, weightSum"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a03/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a03/static/calculation-ledger.svg"
          },
          {
            "file": "comparison-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a03/static/comparison-map.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a03/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a03/static/mistake-contrast.svg"
          },
          {
            "file": "scenario-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a03/static/scenario-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F04-A03",
            "source": "flowchart LR\n    A[\"Finite observations\"] --> B[\"Name units and scope\"]\n    B --> C[\"Freeze: x̄w = Σ(wᵢxᵢ) / Σwᵢ, with aligned values and Σwᵢ ≠ 0\"]\n    C --> D[\"Calculate full precision\"]\n    D --> E{\"Boundary satisfied?\"}\n    E -->|Yes| F[\"Report weighted mean ≈ 3.3333 · total weight 6\"]\n    E -->|No| G[\"Abstain and repair contract\"]\n    F --> H[\"Pair with distribution context\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NumPy Reference",
          "title": "average",
          "author": null,
          "url": null
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/weighted-mean/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/location-ranking-and-exploratory-summaries/weighted-mean/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F04-A04",
      "name": "Median and Mode",
      "headline": null,
      "slug": "median-and-mode",
      "path": "foundations/location-ranking-and-exploratory-summaries/median-and-mode",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F04",
        "family": "Location, Ranking, and Exploratory Summaries",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/location-ranking-and-exploratory-summaries/median-and-mode",
        "entry": "medianAndMode",
        "params": [
          "input"
        ],
        "exports": [
          "medianAndMode"
        ],
        "archetype": "record-transform",
        "signature": "medianAndMode(input)"
      },
      "api": {
        "summary": "Reports the middle of a numeric series and its most frequent values, tallying exact equality so a tie produces several modes rather than one arbitrary winner.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations to summarise, under the key `values`. Modes are counted on exact numeric equality after `Number` coercion, so 2 and 2.0 are the same value.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ median: number; modes: number[]; modeFrequency: number }",
          "description": "`median` is the 0.5 quantile by linear interpolation between order statistics, `modes` lists every value attaining the highest count in ascending order, and `modeFrequency` is that highest count."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F04-A04.json",
        "call": "medianAndMode({\"values\":[1,2,2,4,9],\"weights\":[1,1,2,1,1],\"trimProportion\":0.2,\"bins\":4})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ],
              "weights": [
                1,
                1,
                2,
                1,
                1
              ],
              "trimProportion": 0.2,
              "bins": 4
            },
            "elided": null
          }
        ],
        "output": {
          "median": 2,
          "modes": [
            2
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: median, modes"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a04/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a04/static/calculation-ledger.svg"
          },
          {
            "file": "comparison-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a04/static/comparison-map.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a04/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a04/static/mistake-contrast.svg"
          },
          {
            "file": "scenario-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a04/static/scenario-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F04-A04",
            "source": "flowchart LR\n    A[\"Finite observations\"] --> B[\"Name units and scope\"]\n    B --> C[\"Freeze: median = middle ordered value(s); mode set = {x : frequency(x) is maximal}\"]\n    C --> D[\"Calculate full precision\"]\n    D --> E{\"Boundary satisfied?\"}\n    E -->|Yes| F[\"Report median 2 · modes [2] · mode frequency 2\"]\n    E -->|No| G[\"Abstain and repair contract\"]\n    F --> H[\"Pair with distribution context\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Location",
          "author": null,
          "url": null
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/median-and-mode/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/location-ranking-and-exploratory-summaries/median-and-mode/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F04-A05",
      "name": "Trimmed and Winsorized Means",
      "headline": null,
      "slug": "trimmed-and-winsorized-means",
      "path": "foundations/location-ranking-and-exploratory-summaries/trimmed-and-winsorized-means",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F04",
        "family": "Location, Ranking, and Exploratory Summaries",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/location-ranking-and-exploratory-summaries/trimmed-and-winsorized-means",
        "entry": "trimmedAndWinsorizedMeans",
        "params": [
          "input"
        ],
        "exports": [
          "trimmedAndWinsorizedMeans"
        ],
        "archetype": "record-transform",
        "signature": "trimmedAndWinsorizedMeans(input)"
      },
      "api": {
        "summary": "Cuts the same number of observations off each tail of the sorted series and averages what is left, then averages again with those tails replaced by the surviving boundary values instead of discarded.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[]; trimProportion: number }",
            "required": true,
            "description": "`values` holds the observations and `trimProportion` the share to remove from each tail. The cut size is `floor(values.length * trimProportion)`, so small samples may round the trim down to zero.",
            "constraints": {
              "trimProportion": "0 <= trimProportion < 0.5, and the two cuts together must leave at least one observation"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ trimmedMean: number; winsorizedMean: number; trimmedCount: number }",
          "description": "`trimmedMean` averages only the surviving middle, `winsorizedMean` averages the full-length series with each tail replaced by the nearest kept value, and `trimmedCount` is how many observations the trimmed mean was computed from."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`trimProportion` is negative, is 0.5 or more, or is not a number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the two cuts together would remove every observation",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F04-A05.json",
        "call": "trimmedAndWinsorizedMeans({\"values\":[1,2,2,4,9],\"weights\":[1,1,2,1,1],\"trimProportion\":0.2,\"bins\":4})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ],
              "weights": [
                1,
                1,
                2,
                1,
                1
              ],
              "trimProportion": 0.2,
              "bins": 4
            },
            "elided": null
          }
        ],
        "output": {
          "trimmedMean": 2.6666666666666665,
          "winsorizedMean": 2.8
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: trimmedMean, winsorizedMean"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a05/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a05/static/calculation-ledger.svg"
          },
          {
            "file": "comparison-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a05/static/comparison-map.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a05/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a05/static/mistake-contrast.svg"
          },
          {
            "file": "scenario-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a05/static/scenario-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F04-A05",
            "source": "flowchart LR\n    A[\"Finite observations\"] --> B[\"Name units and scope\"]\n    B --> C[\"Freeze: k = floor(nα); trim x(k+1)…x(n−k); Winsorize by clamping each tail to the retained boundary\"]\n    C --> D[\"Calculate full precision\"]\n    D --> E{\"Boundary satisfied?\"}\n    E -->|Yes| F[\"Report 20% trimmed mean ≈ 2.6667 · Winsorized mean 2.8\"]\n    E -->|No| G[\"Abstain and repair contract\"]\n    F --> H[\"Pair with distribution context\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Location",
          "author": null,
          "url": null
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/trimmed-and-winsorized-means/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/location-ranking-and-exploratory-summaries/trimmed-and-winsorized-means/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F04-A06",
      "name": "Percentiles, Quantiles, and Quartiles",
      "headline": null,
      "slug": "percentiles-quantiles-and-quartiles",
      "path": "foundations/location-ranking-and-exploratory-summaries/percentiles-quantiles-and-quartiles",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F04",
        "family": "Location, Ranking, and Exploratory Summaries",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/location-ranking-and-exploratory-summaries/percentiles-quantiles-and-quartiles",
        "entry": "percentilesQuantilesAndQuartiles",
        "params": [
          "input"
        ],
        "exports": [
          "percentilesQuantilesAndQuartiles"
        ],
        "archetype": "record-transform",
        "signature": "percentilesQuantilesAndQuartiles(input)"
      },
      "api": {
        "summary": "Returns the three quartiles of a numeric series and the interquartile range between the first and third, using linear interpolation between neighbouring order statistics.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations to cut into quantiles, under the key `values`. The series is sorted internally, so the caller's order does not matter.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ quantiles: { '0.25': number; '0.5': number; '0.75': number }; iqr: number }",
          "description": "`quantiles` is keyed by the three cut points as strings, and `iqr` is the 0.75 quantile minus the 0.25 quantile."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F04-A06.json",
        "call": "percentilesQuantilesAndQuartiles({\"values\":[1,2,2,4,9],\"weights\":[1,1,2,1,1],\"trimProportion\":0.2,\"bins\":4})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ],
              "weights": [
                1,
                1,
                2,
                1,
                1
              ],
              "trimProportion": 0.2,
              "bins": 4
            },
            "elided": null
          }
        ],
        "output": {
          "quantiles": {
            "0.25": 2,
            "0.5": 2,
            "0.75": 4
          },
          "iqr": 2
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: quantiles, iqr"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a06/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a06/static/calculation-ledger.svg"
          },
          {
            "file": "comparison-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a06/static/comparison-map.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a06/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a06/static/mistake-contrast.svg"
          },
          {
            "file": "scenario-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a06/static/scenario-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F04-A06",
            "source": "flowchart LR\n    A[\"Finite observations\"] --> B[\"Name units and scope\"]\n    B --> C[\"Freeze: Type 7: h = 1 + (n−1)q; linearly interpolate between ordered positions around h\"]\n    C --> D[\"Calculate full precision\"]\n    D --> E{\"Boundary satisfied?\"}\n    E -->|Yes| F[\"Report Q1 2 · median 2 · Q3 4 · IQR 2 (type 7)\"]\n    E -->|No| G[\"Abstain and repair contract\"]\n    F --> H[\"Pair with distribution context\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST",
          "title": "Percentile Definitions",
          "author": null,
          "url": null
        },
        {
          "key": "NumPy Reference",
          "title": "percentile",
          "author": null,
          "url": null
        },
        {
          "key": "Hyndman and Fan",
          "title": "Sample Quantiles in Statistical Packages",
          "author": null,
          "url": null
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/percentiles-quantiles-and-quartiles/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/location-ranking-and-exploratory-summaries/percentiles-quantiles-and-quartiles/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F04-A07",
      "name": "Ranks, Ties, and Percentile Rank",
      "headline": null,
      "slug": "ranks-ties-and-percentile-rank",
      "path": "foundations/location-ranking-and-exploratory-summaries/ranks-ties-and-percentile-rank",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F04",
        "family": "Location, Ranking, and Exploratory Summaries",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/location-ranking-and-exploratory-summaries/ranks-ties-and-percentile-rank",
        "entry": "ranksTiesAndPercentileRank",
        "params": [
          "input"
        ],
        "exports": [
          "ranksTiesAndPercentileRank"
        ],
        "archetype": "record-transform",
        "signature": "ranksTiesAndPercentileRank(input)"
      },
      "api": {
        "summary": "Assigns each observation its position in the sorted series, giving tied observations the average of the positions they span, and rescales those ranks onto a 0-to-100 percentile scale.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations to rank, under the key `values`. Ranks are returned in the caller's original order, not in sorted order.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ranks: number[]; percentileRanks: number[]; tieCount: number }",
          "description": "`ranks` holds one-based average ranks aligned to the input order, `percentileRanks` maps each rank onto 0 to 100 as `(rank - 1) / (n - 1) * 100`, and `tieCount` is how many observations are duplicates of a value already seen."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`values` holds fewer than two observations, which would make the percentile scale divide by zero",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F04-A07.json",
        "call": "ranksTiesAndPercentileRank({\"values\":[1,2,2,4,9],\"weights\":[1,1,2,1,1],\"trimProportion\":0.2,\"bins\":4})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ],
              "weights": [
                1,
                1,
                2,
                1,
                1
              ],
              "trimProportion": 0.2,
              "bins": 4
            },
            "elided": null
          }
        ],
        "output": {
          "ranks": [
            1,
            2.5,
            2.5,
            4,
            5
          ],
          "percentileRanks": [
            0,
            37.5,
            37.5,
            75,
            100
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: ranks, percentileRanks"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a07/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a07/static/calculation-ledger.svg"
          },
          {
            "file": "comparison-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a07/static/comparison-map.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a07/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a07/static/mistake-contrast.svg"
          },
          {
            "file": "scenario-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a07/static/scenario-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F04-A07",
            "source": "flowchart LR\n    A[\"Finite observations\"] --> B[\"Name units and scope\"]\n    B --> C[\"Freeze: average tied rank; percentile rank = 100(r−1)/(n−1), defined here for n ≥ 2\"]\n    C --> D[\"Calculate full precision\"]\n    D --> E{\"Boundary satisfied?\"}\n    E -->|Yes| F[\"Report ranks [1, 2.5, 2.5, 4, 5] · one duplicate beyond unique values\"]\n    E -->|No| G[\"Abstain and repair contract\"]\n    F --> H[\"Pair with distribution context\"]"
          }
        ]
      },
      "references": [
        {
          "key": "SciPy Reference",
          "title": "rankdata",
          "author": null,
          "url": null
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/ranks-ties-and-percentile-rank/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/location-ranking-and-exploratory-summaries/ranks-ties-and-percentile-rank/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F04-A08",
      "name": "Frequency Tables and Relative Frequency",
      "headline": null,
      "slug": "frequency-tables-and-relative-frequency",
      "path": "foundations/location-ranking-and-exploratory-summaries/frequency-tables-and-relative-frequency",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F04",
        "family": "Location, Ranking, and Exploratory Summaries",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/location-ranking-and-exploratory-summaries/frequency-tables-and-relative-frequency",
        "entry": "frequencyTablesAndRelativeFrequency",
        "params": [
          "input"
        ],
        "exports": [
          "frequencyTablesAndRelativeFrequency"
        ],
        "archetype": "record-transform",
        "signature": "frequencyTablesAndRelativeFrequency(input)"
      },
      "api": {
        "summary": "Counts how often each distinct value occurs in a numeric series and expresses those counts as shares of the total.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations to tabulate, under the key `values`. Distinctness is exact numeric equality after `Number` coercion, so this suits repeated discrete levels rather than continuous measurements.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ frequency: Record<string, number>; relativeFrequency: Record<string, number> }",
          "description": "Both maps are keyed by the distinct values rendered as strings, in ascending numeric order. `frequency` holds raw counts and `relativeFrequency` holds each count divided by the number of observations."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F04-A08.json",
        "call": "frequencyTablesAndRelativeFrequency({\"values\":[1,2,2,4,9],\"weights\":[1,1,2,1,1],\"trimProportion\":0.2,\"bins\":4})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ],
              "weights": [
                1,
                1,
                2,
                1,
                1
              ],
              "trimProportion": 0.2,
              "bins": 4
            },
            "elided": null
          }
        ],
        "output": {
          "frequency": {
            "1": 1,
            "2": 2,
            "4": 1,
            "9": 1
          },
          "relativeFrequency": {
            "1": 0.2,
            "2": 0.4,
            "4": 0.2,
            "9": 0.2
          }
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: frequency, relativeFrequency"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a08/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a08/static/calculation-ledger.svg"
          },
          {
            "file": "comparison-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a08/static/comparison-map.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a08/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a08/static/mistake-contrast.svg"
          },
          {
            "file": "scenario-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a08/static/scenario-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F04-A08",
            "source": "flowchart LR\n    A[\"Finite observations\"] --> B[\"Name units and scope\"]\n    B --> C[\"Freeze: f(v) = count(xᵢ = v); relative f(v) = f(v)/n\"]\n    C --> D[\"Calculate full precision\"]\n    D --> E{\"Boundary satisfied?\"}\n    E -->|Yes| F[\"Report 2 → count 2 and share 40%; 1, 4, 9 → 20% each\"]\n    E -->|No| G[\"Abstain and repair contract\"]\n    F --> H[\"Pair with distribution context\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Histogram",
          "author": null,
          "url": null
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/frequency-tables-and-relative-frequency/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/location-ranking-and-exploratory-summaries/frequency-tables-and-relative-frequency/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F04-A09",
      "name": "Histograms and Empirical Distribution Functions",
      "headline": null,
      "slug": "histograms-and-empirical-distribution-functions",
      "path": "foundations/location-ranking-and-exploratory-summaries/histograms-and-empirical-distribution-functions",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F04",
        "family": "Location, Ranking, and Exploratory Summaries",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/location-ranking-and-exploratory-summaries/histograms-and-empirical-distribution-functions",
        "entry": "histogramsAndEmpiricalDistributionFunctions",
        "params": [
          "input"
        ],
        "exports": [
          "histogramsAndEmpiricalDistributionFunctions"
        ],
        "archetype": "record-transform",
        "signature": "histogramsAndEmpiricalDistributionFunctions(input)"
      },
      "api": {
        "summary": "Splits the observed span into equal-width bins and counts the observations in each, alongside the empirical distribution function evaluated at every sorted observation.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[]; bins: number }",
            "required": true,
            "description": "`values` holds the observations and `bins` the number of equal-width buckets to spread them across. The bins span minimum to maximum; when every observation is identical the width falls back to 1 and everything lands in the last bin.",
            "constraints": {
              "bins": "integer, at least 1"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ binCounts: number[]; binWidth: number; ecdf: { x: number; p: number }[] }",
          "description": "`binCounts` has one entry per bin in ascending order, `binWidth` is the common width used, and `ecdf` pairs each sorted observation `x` with the cumulative share `p` of observations at or below its position."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`bins` is not an integer or is less than 1",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F04-A09.json",
        "call": "histogramsAndEmpiricalDistributionFunctions({\"values\":[1,2,2,4,9],\"weights\":[1,1,2,1,1],\"trimProportion\":0.2,\"bins\":4})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ],
              "weights": [
                1,
                1,
                2,
                1,
                1
              ],
              "trimProportion": 0.2,
              "bins": 4
            },
            "elided": null
          }
        ],
        "output": {
          "binCounts": [
            3,
            1,
            0,
            1
          ],
          "binWidth": 2
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: binCounts, binWidth"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a09/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a09/static/calculation-ledger.svg"
          },
          {
            "file": "comparison-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a09/static/comparison-map.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a09/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a09/static/mistake-contrast.svg"
          },
          {
            "file": "scenario-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a09/static/scenario-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F04-A09",
            "source": "flowchart LR\n    A[\"Finite observations\"] --> B[\"Name units and scope\"]\n    B --> C[\"Freeze: histogram bin count = # values in interval; Fₙ(x) = (1/n) Σ1[xᵢ ≤ x]\"]\n    C --> D[\"Calculate full precision\"]\n    D --> E{\"Boundary satisfied?\"}\n    E -->|Yes| F[\"Report four bin counts [3, 1, 0, 1] · ECDF finishes at 1\"]\n    E -->|No| G[\"Abstain and repair contract\"]\n    F --> H[\"Pair with distribution context\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Histogram",
          "author": null,
          "url": null
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Empirical Distribution Function",
          "author": null,
          "url": null
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Location, Scale, and Shape",
          "author": null,
          "url": null
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/histograms-and-empirical-distribution-functions/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/location-ranking-and-exploratory-summaries/histograms-and-empirical-distribution-functions/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F04-A10",
      "name": "Five-Number Summary and Box Plot",
      "headline": null,
      "slug": "five-number-summary-and-box-plot",
      "path": "foundations/location-ranking-and-exploratory-summaries/five-number-summary-and-box-plot",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F04",
        "family": "Location, Ranking, and Exploratory Summaries",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/location-ranking-and-exploratory-summaries/five-number-summary-and-box-plot",
        "entry": "fiveNumberSummaryAndBoxPlot",
        "params": [
          "input"
        ],
        "exports": [
          "fiveNumberSummaryAndBoxPlot"
        ],
        "archetype": "record-transform",
        "signature": "fiveNumberSummaryAndBoxPlot(input)"
      },
      "api": {
        "summary": "Produces the minimum, three quartiles, and maximum of a numeric series, the Tukey 1.5-IQR fences drawn from them, and the observations lying outside those fences.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations to summarise, under the key `values`. Quartiles use linear interpolation between neighbouring order statistics.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ fiveNumberSummary: number[]; fences: [number, number]; outliers: number[] }",
          "description": "`fiveNumberSummary` is `[minimum, q1, median, q3, maximum]`, `fences` is `[q1 - 1.5 * iqr, q3 + 1.5 * iqr]`, and `outliers` lists the observations strictly outside the fences in the caller's original order."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F04-A10.json",
        "call": "fiveNumberSummaryAndBoxPlot({\"values\":[1,2,2,4,9],\"weights\":[1,1,2,1,1],\"trimProportion\":0.2,\"bins\":4})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ],
              "weights": [
                1,
                1,
                2,
                1,
                1
              ],
              "trimProportion": 0.2,
              "bins": 4
            },
            "elided": null
          }
        ],
        "output": {
          "fiveNumberSummary": [
            1,
            2,
            2,
            4,
            9
          ],
          "fences": [
            -1,
            7
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: fiveNumberSummary, fences"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a10/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a10/static/calculation-ledger.svg"
          },
          {
            "file": "comparison-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a10/static/comparison-map.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a10/static/concept-anatomy.svg"
          },
          {
            "file": "mistake-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a10/static/mistake-contrast.svg"
          },
          {
            "file": "scenario-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f04-a10/static/scenario-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F04-A10",
            "source": "flowchart LR\n    A[\"Finite observations\"] --> B[\"Name units and scope\"]\n    B --> C[\"Freeze: IQR = Q3−Q1; inner fences = Q1−1.5IQR and Q3+1.5IQR; whiskers stop at extreme observations within fences\"]\n    C --> D[\"Calculate full precision\"]\n    D --> E{\"Boundary satisfied?\"}\n    E -->|Yes| F[\"Report five numbers [1, 2, 2, 4, 9] · fences [−1, 7] · possible outlier [9]\"]\n    E -->|No| G[\"Abstain and repair contract\"]\n    F --> H[\"Pair with distribution context\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Box Plot",
          "author": null,
          "url": null
        },
        {
          "key": "NIST",
          "title": "Percentile Definitions",
          "author": null,
          "url": null
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/five-number-summary-and-box-plot/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/location-ranking-and-exploratory-summaries/five-number-summary-and-box-plot/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F05-A01",
      "name": "Deviation, Absolute Deviation, and Squared Deviation",
      "headline": null,
      "slug": "deviation-absolute-deviation-and-squared-deviation",
      "path": "foundations/dispersion-shape-and-robust-statistics/deviation-absolute-deviation-and-squared-deviation",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F05",
        "family": "Dispersion, Shape, and Robust Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dispersion-shape-and-robust-statistics/deviation-absolute-deviation-and-squared-deviation",
        "entry": "deviationAbsoluteDeviationAndSquaredDeviation",
        "params": [
          "input"
        ],
        "exports": [
          "deviationAbsoluteDeviationAndSquaredDeviation"
        ],
        "archetype": "record-transform",
        "signature": "deviationAbsoluteDeviationAndSquaredDeviation(input)"
      },
      "api": {
        "summary": "Centres a numeric series on its arithmetic mean and returns the three per-observation distance forms built from that centring: signed, absolute, and squared.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations to centre, under the key `values`. Entries are coerced with `Number` and must all be finite.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ center: number; deviations: number[]; absoluteDeviations: number[]; squaredDeviations: number[] }",
          "description": "`center` is the arithmetic mean; the three arrays hold `value - center`, its absolute value, and its square, each aligned to the caller's input order."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F05-A01.json",
        "call": "deviationAbsoluteDeviationAndSquaredDeviation({\"values\":[1,2,2,4,9]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "center": 3.6,
          "deviations": [
            -2.6,
            -1.6,
            -1.6,
            0.3999999999999999,
            5.4
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: center, deviations"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a01/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a01/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a01/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a01/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a01/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a01/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F05-A01",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Deviation, Absolute Deviation, and Squared Deviation\"]\n    D --> E[\"Formula: dᵢ=xᵢ−c; |dᵢ|; dᵢ²\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Skewness and Kurtosis",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dispersion-shape-and-robust-statistics/deviation-absolute-deviation-and-squared-deviation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dispersion-shape-and-robust-statistics/deviation-absolute-deviation-and-squared-deviation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F05-A02",
      "name": "Range and Interquartile Range",
      "headline": null,
      "slug": "range-and-interquartile-range",
      "path": "foundations/dispersion-shape-and-robust-statistics/range-and-interquartile-range",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F05",
        "family": "Dispersion, Shape, and Robust Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dispersion-shape-and-robust-statistics/range-and-interquartile-range",
        "entry": "rangeAndInterquartileRange",
        "params": [
          "input"
        ],
        "exports": [
          "rangeAndInterquartileRange"
        ],
        "archetype": "record-transform",
        "signature": "rangeAndInterquartileRange(input)"
      },
      "api": {
        "summary": "Measures spread two ways on the same series: the full distance from smallest to largest, and the distance covering the middle half between the first and third quartiles.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations whose spread is being measured, under the key `values`. Quartiles use linear interpolation between neighbouring order statistics.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ range: number; iqr: number; q1: number; q3: number }",
          "description": "`range` is `maximum - minimum`, `iqr` is `q3 - q1`, and `q1` and `q3` are returned alongside so the interquartile range can be traced back to the cut points it came from."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F05-A02.json",
        "call": "rangeAndInterquartileRange({\"values\":[1,2,2,4,9]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "range": 8,
          "iqr": 2
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: range, iqr"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a02/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a02/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a02/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a02/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a02/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a02/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F05-A02",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Range and Interquartile Range\"]\n    D --> E[\"Formula: range=max−min; IQR=Q3−Q1 using linear/type-7 quartiles\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Skewness and Kurtosis",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dispersion-shape-and-robust-statistics/range-and-interquartile-range/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dispersion-shape-and-robust-statistics/range-and-interquartile-range/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F05-A03",
      "name": "Mean Absolute Deviation",
      "headline": null,
      "slug": "mean-absolute-deviation",
      "path": "foundations/dispersion-shape-and-robust-statistics/mean-absolute-deviation",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F05",
        "family": "Dispersion, Shape, and Robust Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dispersion-shape-and-robust-statistics/mean-absolute-deviation",
        "entry": "meanAbsoluteDeviation",
        "params": [
          "input"
        ],
        "exports": [
          "meanAbsoluteDeviation"
        ],
        "archetype": "record-transform",
        "signature": "meanAbsoluteDeviation(input)"
      },
      "api": {
        "summary": "Averages the absolute distances of the observations from their arithmetic mean, giving a spread figure in the same units as the data and without squaring.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations to measure, under the key `values`. The centre used is the arithmetic mean of this same series, not a supplied reference point.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ meanAbsoluteDeviation: number; center: number }",
          "description": "`meanAbsoluteDeviation` is the average absolute distance from the centre, and `center` is the arithmetic mean the distances were taken from."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F05-A03.json",
        "call": "meanAbsoluteDeviation({\"values\":[1,2,2,4,9]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "meanAbsoluteDeviation": 2.3200000000000003,
          "center": 3.6
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: meanAbsoluteDeviation, center"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a03/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a03/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a03/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a03/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a03/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a03/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F05-A03",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Mean Absolute Deviation\"]\n    D --> E[\"Formula: MADmean=(1/n)Σ|xᵢ−x̄|\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Skewness and Kurtosis",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dispersion-shape-and-robust-statistics/mean-absolute-deviation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dispersion-shape-and-robust-statistics/mean-absolute-deviation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F05-A04",
      "name": "Median Absolute Deviation",
      "headline": null,
      "slug": "median-absolute-deviation",
      "path": "foundations/dispersion-shape-and-robust-statistics/median-absolute-deviation",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F05",
        "family": "Dispersion, Shape, and Robust Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dispersion-shape-and-robust-statistics/median-absolute-deviation",
        "entry": "medianAbsoluteDeviation",
        "params": [
          "input"
        ],
        "exports": [
          "medianAbsoluteDeviation"
        ],
        "archetype": "record-transform",
        "signature": "medianAbsoluteDeviation(input)"
      },
      "api": {
        "summary": "Takes the median of the absolute distances from the series median, and rescales it by 1.4826 so it lines up with a standard deviation under normality.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations to measure, under the key `values`. Both the centre and the spread are medians, so a handful of extreme observations cannot drag the result.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ medianAbsoluteDeviation: number; median: number; scaledMad: number }",
          "description": "`medianAbsoluteDeviation` is the raw median of the absolute deviations, `median` is the centre they were taken from, and `scaledMad` is that raw figure multiplied by 1.4826."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F05-A04.json",
        "call": "medianAbsoluteDeviation({\"values\":[1,2,2,4,9]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "medianAbsoluteDeviation": 1,
          "median": 2
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: medianAbsoluteDeviation, median"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a04/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a04/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a04/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a04/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a04/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a04/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F05-A04",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Median Absolute Deviation\"]\n    D --> E[\"Formula: MADmedian=median(|xᵢ−median(x)|); scaled MAD=1.4826×MADmedian\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Skewness and Kurtosis",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dispersion-shape-and-robust-statistics/median-absolute-deviation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dispersion-shape-and-robust-statistics/median-absolute-deviation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F05-A05",
      "name": "Population and Sample Variance",
      "headline": null,
      "slug": "population-and-sample-variance",
      "path": "foundations/dispersion-shape-and-robust-statistics/population-and-sample-variance",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F05",
        "family": "Dispersion, Shape, and Robust Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dispersion-shape-and-robust-statistics/population-and-sample-variance",
        "entry": "populationAndSampleVariance",
        "params": [
          "input"
        ],
        "exports": [
          "populationAndSampleVariance"
        ],
        "archetype": "record-transform",
        "signature": "populationAndSampleVariance(input)"
      },
      "api": {
        "summary": "Averages the squared deviations from the mean twice over the same series: once dividing by the observation count, once by that count less one.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations to measure, under the key `values`. At least two are needed, because the sample figure divides by `n - 1`.",
            "constraints": {
              "values": "at least two observations"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ populationVariance: number; sampleVariance: number }",
          "description": "`populationVariance` divides the sum of squared deviations by `n`, `sampleVariance` divides it by `n - 1`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`values` holds fewer than two observations, so the sample divisor `n - 1` would be zero",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F05-A05.json",
        "call": "populationAndSampleVariance({\"values\":[1,2,2,4,9]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "populationVariance": 8.24,
          "sampleVariance": 10.3
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: populationVariance, sampleVariance"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a05/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a05/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a05/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a05/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a05/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a05/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F05-A05",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Population and Sample Variance\"]\n    D --> E[\"Formula: σ²=Σ(xᵢ−μ)²/N; s²=Σ(xᵢ−x̄)²/(n−1)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Skewness and Kurtosis",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dispersion-shape-and-robust-statistics/population-and-sample-variance/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dispersion-shape-and-robust-statistics/population-and-sample-variance/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F05-A06",
      "name": "Population and Sample Standard Deviation",
      "headline": null,
      "slug": "population-and-sample-standard-deviation",
      "path": "foundations/dispersion-shape-and-robust-statistics/population-and-sample-standard-deviation",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F05",
        "family": "Dispersion, Shape, and Robust Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dispersion-shape-and-robust-statistics/population-and-sample-standard-deviation",
        "entry": "populationAndSampleStandardDeviation",
        "params": [
          "input"
        ],
        "exports": [
          "populationAndSampleStandardDeviation"
        ],
        "archetype": "record-transform",
        "signature": "populationAndSampleStandardDeviation(input)"
      },
      "api": {
        "summary": "Takes the square root of both the population and the sample variance of one series, returning spread in the same units as the observations.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations to measure, under the key `values`. At least two are needed, because the sample figure divides by `n - 1`.",
            "constraints": {
              "values": "at least two observations"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ populationStandardDeviation: number; sampleStandardDeviation: number }",
          "description": "The square roots of the `n`-divisor and `n - 1`-divisor variances respectively."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`values` holds fewer than two observations, so the sample divisor `n - 1` would be zero",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F05-A06.json",
        "call": "populationAndSampleStandardDeviation({\"values\":[1,2,2,4,9]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "populationStandardDeviation": 2.870540018881465,
          "sampleStandardDeviation": 3.2093613071762426
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: populationStandardDeviation, sampleStandardDeviation"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a06/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a06/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a06/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a06/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a06/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a06/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F05-A06",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Population and Sample Standard Deviation\"]\n    D --> E[\"Formula: σ=√σ²; s=√s²\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Skewness and Kurtosis",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dispersion-shape-and-robust-statistics/population-and-sample-standard-deviation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dispersion-shape-and-robust-statistics/population-and-sample-standard-deviation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F05-A07",
      "name": "Coefficient of Variation and Scale Comparability",
      "headline": null,
      "slug": "coefficient-of-variation-and-scale-comparability",
      "path": "foundations/dispersion-shape-and-robust-statistics/coefficient-of-variation-and-scale-comparability",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F05",
        "family": "Dispersion, Shape, and Robust Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dispersion-shape-and-robust-statistics/coefficient-of-variation-and-scale-comparability",
        "entry": "coefficientOfVariationAndScaleComparability",
        "params": [
          "input"
        ],
        "exports": [
          "coefficientOfVariationAndScaleComparability"
        ],
        "archetype": "record-transform",
        "signature": "coefficientOfVariationAndScaleComparability(input)"
      },
      "api": {
        "summary": "Divides the sample standard deviation by the absolute value of the mean, turning spread into a unit-free figure that can be compared across series measured on different scales.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations to measure, under the key `values`. The ratio is only meaningful for series on a ratio scale with a mean away from zero.",
            "constraints": {
              "values": "at least two observations, and a non-zero mean"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ coefficientOfVariation: number; scaleFree: boolean }",
          "description": "`coefficientOfVariation` is the sample standard deviation over the absolute mean, and `scaleFree` is always `true`, marking the figure as carrying no units."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`values` holds fewer than two observations, so the sample divisor `n - 1` would be zero",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the arithmetic mean of `values` is exactly zero, leaving the ratio undefined",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F05-A07.json",
        "call": "coefficientOfVariationAndScaleComparability({\"values\":[1,2,2,4,9]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "coefficientOfVariation": 0.8914892519934007,
          "scaleFree": true
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: coefficientOfVariation, scaleFree"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a07/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a07/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a07/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a07/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a07/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a07/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F05-A07",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Coefficient of Variation and Scale Comparability\"]\n    D --> E[\"Formula: CV=s/|x̄|\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Skewness and Kurtosis",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dispersion-shape-and-robust-statistics/coefficient-of-variation-and-scale-comparability/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dispersion-shape-and-robust-statistics/coefficient-of-variation-and-scale-comparability/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F05-A08",
      "name": "Z-Score, Robust Z-Score, and Standardization",
      "headline": null,
      "slug": "z-score-robust-z-score-and-standardization",
      "path": "foundations/dispersion-shape-and-robust-statistics/z-score-robust-z-score-and-standardization",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F05",
        "family": "Dispersion, Shape, and Robust Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dispersion-shape-and-robust-statistics/z-score-robust-z-score-and-standardization",
        "entry": "zScoreRobustZScoreAndStandardization",
        "params": [
          "input"
        ],
        "exports": [
          "zScoreRobustZScoreAndStandardization"
        ],
        "archetype": "record-transform",
        "signature": "zScoreRobustZScoreAndStandardization(input)"
      },
      "api": {
        "summary": "Standardises every observation twice: once against the mean and sample standard deviation, and once against the median and median absolute deviation scaled by 0.67448975.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations to standardise, under the key `values`. Both output arrays stay aligned to the caller's input order.",
            "constraints": {
              "values": "at least two observations, and not all identical"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ zScores: number[]; robustZScores: number[] }",
          "description": "`zScores` holds `(value - mean) / sampleStandardDeviation`, and `robustZScores` holds `0.67448975 * (value - median) / mad`, with every entry set to 0 when the median absolute deviation is zero."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`values` holds fewer than two observations, so the sample divisor `n - 1` would be zero",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the sample standard deviation is zero because every observation is identical",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F05-A08.json",
        "call": "zScoreRobustZScoreAndStandardization({\"values\":[1,2,2,4,9]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "zScores": [
            -0.8101300387046826,
            -0.4985415622798047,
            -0.4985415622798047,
            0.12463539056995114,
            1.6825777726943407
          ],
          "robustZScores": [
            -0.67448975,
            0,
            0,
            1.3489795,
            4.72142825
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: zScores, robustZScores"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a08/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a08/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a08/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a08/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a08/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a08/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F05-A08",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Z-Score, Robust Z-Score, and Standardization\"]\n    D --> E[\"Formula: z=(x−x̄)/s; robust z=0.67448975(x−median)/MAD\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Skewness and Kurtosis",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dispersion-shape-and-robust-statistics/z-score-robust-z-score-and-standardization/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dispersion-shape-and-robust-statistics/z-score-robust-z-score-and-standardization/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F05-A09",
      "name": "Skewness and Tail Asymmetry",
      "headline": null,
      "slug": "skewness-and-tail-asymmetry",
      "path": "foundations/dispersion-shape-and-robust-statistics/skewness-and-tail-asymmetry",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F05",
        "family": "Dispersion, Shape, and Robust Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dispersion-shape-and-robust-statistics/skewness-and-tail-asymmetry",
        "entry": "skewnessAndTailAsymmetry",
        "params": [
          "input"
        ],
        "exports": [
          "skewnessAndTailAsymmetry"
        ],
        "archetype": "record-transform",
        "signature": "skewnessAndTailAsymmetry(input)"
      },
      "api": {
        "summary": "Divides the third central moment by the second raised to the power 1.5, giving the moment coefficient of skewness, and labels which tail is the longer one.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations whose asymmetry is being measured, under the key `values`. Both moments are population moments, dividing by `n` rather than applying a small-sample correction.",
            "constraints": {
              "values": "at least two observations, and not all identical"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ momentSkewness: number; direction: 'right' | 'left' | 'symmetric' }",
          "description": "`momentSkewness` is `m3 / m2 ** 1.5`, and `direction` is `right` when it is positive, `left` when negative, and `symmetric` at exactly zero."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`values` holds fewer than two observations, so the sample divisor `n - 1` would be zero",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the second central moment is zero because every observation is identical",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F05-A09.json",
        "call": "skewnessAndTailAsymmetry({\"values\":[1,2,2,4,9]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "momentSkewness": 1.1140963830468877,
          "direction": "right"
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: momentSkewness, direction"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a09/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a09/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a09/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a09/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a09/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a09/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F05-A09",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Skewness and Tail Asymmetry\"]\n    D --> E[\"Formula: g₁=m₃/m₂^(3/2), where mₖ=(1/n)Σ(xᵢ−x̄)ᵏ\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Skewness and Kurtosis",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dispersion-shape-and-robust-statistics/skewness-and-tail-asymmetry/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dispersion-shape-and-robust-statistics/skewness-and-tail-asymmetry/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F05-A10",
      "name": "Kurtosis, Excess Kurtosis, and Tail Weight",
      "headline": null,
      "slug": "kurtosis-excess-kurtosis-and-tail-weight",
      "path": "foundations/dispersion-shape-and-robust-statistics/kurtosis-excess-kurtosis-and-tail-weight",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F05",
        "family": "Dispersion, Shape, and Robust Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dispersion-shape-and-robust-statistics/kurtosis-excess-kurtosis-and-tail-weight",
        "entry": "kurtosisExcessKurtosisAndTailWeight",
        "params": [
          "input"
        ],
        "exports": [
          "kurtosisExcessKurtosisAndTailWeight"
        ],
        "archetype": "record-transform",
        "signature": "kurtosisExcessKurtosisAndTailWeight(input)"
      },
      "api": {
        "summary": "Divides the fourth central moment by the square of the second, subtracts 3 to give excess kurtosis, and says whether the tails are heavier or lighter than a normal distribution's.",
        "params": [
          {
            "name": "input",
            "type": "{ values: number[] }",
            "required": true,
            "description": "The observations whose tail weight is being measured, under the key `values`. Both moments are population moments, dividing by `n` rather than applying a small-sample correction.",
            "constraints": {
              "values": "at least two observations, and not all identical"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ kurtosis: number; excessKurtosis: number; tailWeightVsNormal: 'heavier' | 'lighter' }",
          "description": "`kurtosis` is `m4 / m2 ** 2`, `excessKurtosis` is that less 3, and `tailWeightVsNormal` is `heavier` when kurtosis exceeds 3 and `lighter` otherwise, including at exactly 3."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`values` is missing, is not an array, or is empty",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any entry of `values` does not coerce to a finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`values` holds fewer than two observations, so the sample divisor `n - 1` would be zero",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the second central moment is zero because every observation is identical",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F05-A10.json",
        "call": "kurtosisExcessKurtosisAndTailWeight({\"values\":[1,2,2,4,9]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                2,
                4,
                9
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "kurtosis": 2.6779621076444537,
          "excessKurtosis": -0.32203789235554625
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: kurtosis, excessKurtosis"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a10/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a10/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a10/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a10/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a10/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f05-a10/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F05-A10",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Kurtosis, Excess Kurtosis, and Tail Weight\"]\n    D --> E[\"Formula: kurtosis=m₄/m₂²; excess=kurtosis−3\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Skewness and Kurtosis",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dispersion-shape-and-robust-statistics/kurtosis-excess-kurtosis-and-tail-weight/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dispersion-shape-and-robust-statistics/kurtosis-excess-kurtosis-and-tail-weight/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F06-A01",
      "name": "Experiments, Outcomes, Sample Spaces, and Events",
      "headline": null,
      "slug": "experiments-outcomes-sample-spaces-and-events",
      "path": "foundations/probability-and-random-variables/experiments-outcomes-sample-spaces-and-events",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F06",
        "family": "Probability and Random Variables",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-and-random-variables/experiments-outcomes-sample-spaces-and-events",
        "entry": "experimentsOutcomesSampleSpacesAndEvents",
        "params": [
          "input"
        ],
        "exports": [
          "experimentsOutcomesSampleSpacesAndEvents"
        ],
        "archetype": "record-transform",
        "signature": "experimentsOutcomesSampleSpacesAndEvents(input)"
      },
      "api": {
        "summary": "Sizes a sample space and a candidate event, and checks that every outcome named in the event actually appears in the sample space.",
        "params": [
          {
            "name": "input",
            "type": "{ pA: number; pB: number; pAB: number; outcomes: unknown[]; event: unknown[] }",
            "required": true,
            "description": "`outcomes` lists the sample space and `event` the subset being examined; membership is tested with strict equality, so outcomes are usually strings or numbers. The family-wide probabilities `pA`, `pB`, and `pAB` are validated on every call even though this topic does not use their values.",
            "constraints": {
              "pA": "0 <= pA <= 1",
              "pB": "0 <= pB <= 1",
              "pAB": "0 <= pAB <= min(pA, pB)"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ sampleSpaceSize: number; eventSize: number; eventIsSubset: boolean }",
          "description": "`sampleSpaceSize` and `eventSize` are the two list lengths, and `eventIsSubset` is `true` only when every element of `event` is present in `outcomes`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`pA`, `pB`, or `pAB` falls outside [0, 1], or `pAB` exceeds `min(pA, pB)`",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(events * outcomes)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F06-A01.json",
        "call": "experimentsOutcomesSampleSpacesAndEvents({\"pA\":0.6,\"pB\":0.5,\"pAB\":0.3,\"outcomes\":[\"up\",\"flat\",\"down\"],\"event\":[\"up\",\"flat\"],\"prior\":0.01,\"sensitivity\":0.9,\"falsePositiveRate\":0.05,\"randomValues\":[0,1,2],\"probabilities\":[0.2,0.5,0.3],\"randomVariableKind\":\"discrete\",\"joint\":[{\"x\":0,\"y\":0,\"p\":0.3},{\"x\":0,\"y\":1,\"p\":0.2},{\"x\":1,\"y\":0,\"p\":0.1}],\"conditionY\":1})",
        "args": [
          {
            "value": {
              "pA": 0.6,
              "pB": 0.5,
              "pAB": 0.3,
              "outcomes": [
                "up",
                "flat",
                "down"
              ],
              "event": [
                "up",
                "flat"
              ],
              "prior": 0.01,
              "sensitivity": 0.9,
              "falsePositiveRate": 0.05,
              "randomValues": [
                0,
                1,
                2
              ],
              "probabilities": [
                0.2,
                0.5,
                0.3
              ],
              "randomVariableKind": "discrete",
              "joint": [
                {
                  "x": 0,
                  "y": 0,
                  "p": 0.3
                },
                {
                  "x": 0,
                  "y": 1,
                  "p": 0.2
                },
                {
                  "x": 1,
                  "y": 0,
                  "p": 0.1
                }
              ],
              "conditionY": 1
            },
            "elided": null
          }
        ],
        "output": {
          "sampleSpaceSize": 3,
          "eventSize": 2
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: sampleSpaceSize, eventSize"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a01/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a01/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a01/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a01/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a01/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a01/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F06-A01",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Experiments, Outcomes, Sample Spaces, and Events\"]\n    D --> E[\"Formula: event A⊆Ω; P(Ω)=1\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-and-random-variables/experiments-outcomes-sample-spaces-and-events/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-and-random-variables/experiments-outcomes-sample-spaces-and-events/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F06-A02",
      "name": "Probability Rules, Complements, Unions, and Intersections",
      "headline": null,
      "slug": "probability-rules-complements-unions-and-intersections",
      "path": "foundations/probability-and-random-variables/probability-rules-complements-unions-and-intersections",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F06",
        "family": "Probability and Random Variables",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-and-random-variables/probability-rules-complements-unions-and-intersections",
        "entry": "probabilityRulesComplementsUnionsAndIntersections",
        "params": [
          "input"
        ],
        "exports": [
          "probabilityRulesComplementsUnionsAndIntersections"
        ],
        "archetype": "record-transform",
        "signature": "probabilityRulesComplementsUnionsAndIntersections(input)"
      },
      "api": {
        "summary": "Applies the complement and addition rules to a pair of events, deriving the probability that A does not happen and the probability that at least one of A or B happens.",
        "params": [
          {
            "name": "input",
            "type": "{ pA: number; pB: number; pAB: number }",
            "required": true,
            "description": "`pA` and `pB` are the marginal probabilities of the two events and `pAB` the probability of both together. The joint probability is taken as given, not inferred, so it must be consistent with the two marginals.",
            "constraints": {
              "pA": "0 <= pA <= 1",
              "pB": "0 <= pB <= 1",
              "pAB": "0 <= pAB <= min(pA, pB)"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ complementA: number; union: number; intersection: number }",
          "description": "`complementA` is `1 - pA`, `union` is `pA + pB - pAB`, and `intersection` echoes the supplied `pAB` so all three rule terms sit side by side."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`pA`, `pB`, or `pAB` falls outside [0, 1], or `pAB` exceeds `min(pA, pB)`",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F06-A02.json",
        "call": "probabilityRulesComplementsUnionsAndIntersections({\"pA\":0.6,\"pB\":0.5,\"pAB\":0.3,\"outcomes\":[\"up\",\"flat\",\"down\"],\"event\":[\"up\",\"flat\"],\"prior\":0.01,\"sensitivity\":0.9,\"falsePositiveRate\":0.05,\"randomValues\":[0,1,2],\"probabilities\":[0.2,0.5,0.3],\"randomVariableKind\":\"discrete\",\"joint\":[{\"x\":0,\"y\":0,\"p\":0.3},{\"x\":0,\"y\":1,\"p\":0.2},{\"x\":1,\"y\":0,\"p\":0.1}],\"conditionY\":1})",
        "args": [
          {
            "value": {
              "pA": 0.6,
              "pB": 0.5,
              "pAB": 0.3,
              "outcomes": [
                "up",
                "flat",
                "down"
              ],
              "event": [
                "up",
                "flat"
              ],
              "prior": 0.01,
              "sensitivity": 0.9,
              "falsePositiveRate": 0.05,
              "randomValues": [
                0,
                1,
                2
              ],
              "probabilities": [
                0.2,
                0.5,
                0.3
              ],
              "randomVariableKind": "discrete",
              "joint": [
                {
                  "x": 0,
                  "y": 0,
                  "p": 0.3
                },
                {
                  "x": 0,
                  "y": 1,
                  "p": 0.2
                },
                {
                  "x": 1,
                  "y": 0,
                  "p": 0.1
                }
              ],
              "conditionY": 1
            },
            "elided": null
          }
        ],
        "output": {
          "complementA": 0.4,
          "union": 0.8
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: complementA, union"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a02/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a02/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a02/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a02/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a02/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a02/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F06-A02",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Probability Rules, Complements, Unions, and Intersections\"]\n    D --> E[\"Formula: P(Aᶜ)=1−P(A); P(A∪B)=P(A)+P(B)−P(A∩B)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-and-random-variables/probability-rules-complements-unions-and-intersections/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-and-random-variables/probability-rules-complements-unions-and-intersections/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F06-A03",
      "name": "Conditional Probability",
      "headline": null,
      "slug": "conditional-probability",
      "path": "foundations/probability-and-random-variables/conditional-probability",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F06",
        "family": "Probability and Random Variables",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-and-random-variables/conditional-probability",
        "entry": "conditionalProbability",
        "params": [
          "input"
        ],
        "exports": [
          "conditionalProbability"
        ],
        "archetype": "record-transform",
        "signature": "conditionalProbability(input)"
      },
      "api": {
        "summary": "Rescales the joint probability of two events by each marginal in turn, giving the probability of A once B is known and the probability of B once A is known.",
        "params": [
          {
            "name": "input",
            "type": "{ pA: number; pB: number; pAB: number }",
            "required": true,
            "description": "`pA` and `pB` are the marginal probabilities and `pAB` the joint. Both marginals must be strictly positive, since each one is used as a denominator.",
            "constraints": {
              "pA": "0 <= pA <= 1",
              "pB": "0 <= pB <= 1",
              "pAB": "0 <= pAB <= min(pA, pB)",
              "conditioning": "pA and pB must both be strictly greater than 0"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ pAGivenB: number; pBGivenA: number }",
          "description": "`pAGivenB` is `pAB / pB` and `pBGivenA` is `pAB / pA`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`pA`, `pB`, or `pAB` falls outside [0, 1], or `pAB` exceeds `min(pA, pB)`",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`pA` or `pB` is exactly zero, which would divide by a zero-probability conditioning event",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F06-A03.json",
        "call": "conditionalProbability({\"pA\":0.6,\"pB\":0.5,\"pAB\":0.3,\"outcomes\":[\"up\",\"flat\",\"down\"],\"event\":[\"up\",\"flat\"],\"prior\":0.01,\"sensitivity\":0.9,\"falsePositiveRate\":0.05,\"randomValues\":[0,1,2],\"probabilities\":[0.2,0.5,0.3],\"randomVariableKind\":\"discrete\",\"joint\":[{\"x\":0,\"y\":0,\"p\":0.3},{\"x\":0,\"y\":1,\"p\":0.2},{\"x\":1,\"y\":0,\"p\":0.1}],\"conditionY\":1})",
        "args": [
          {
            "value": {
              "pA": 0.6,
              "pB": 0.5,
              "pAB": 0.3,
              "outcomes": [
                "up",
                "flat",
                "down"
              ],
              "event": [
                "up",
                "flat"
              ],
              "prior": 0.01,
              "sensitivity": 0.9,
              "falsePositiveRate": 0.05,
              "randomValues": [
                0,
                1,
                2
              ],
              "probabilities": [
                0.2,
                0.5,
                0.3
              ],
              "randomVariableKind": "discrete",
              "joint": [
                {
                  "x": 0,
                  "y": 0,
                  "p": 0.3
                },
                {
                  "x": 0,
                  "y": 1,
                  "p": 0.2
                },
                {
                  "x": 1,
                  "y": 0,
                  "p": 0.1
                }
              ],
              "conditionY": 1
            },
            "elided": null
          }
        ],
        "output": {
          "pAGivenB": 0.6,
          "pBGivenA": 0.5
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: pAGivenB, pBGivenA"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a03/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a03/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a03/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a03/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a03/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a03/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F06-A03",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Conditional Probability\"]\n    D --> E[\"Formula: P(A|B)=P(A∩B)/P(B), for P(B)>0\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-and-random-variables/conditional-probability/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-and-random-variables/conditional-probability/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F06-A04",
      "name": "Independence and Dependence",
      "headline": null,
      "slug": "independence-and-dependence",
      "path": "foundations/probability-and-random-variables/independence-and-dependence",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F06",
        "family": "Probability and Random Variables",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-and-random-variables/independence-and-dependence",
        "entry": "independenceAndDependence",
        "params": [
          "input"
        ],
        "exports": [
          "independenceAndDependence"
        ],
        "archetype": "record-transform",
        "signature": "independenceAndDependence(input)"
      },
      "api": {
        "summary": "Compares the observed joint probability of two events against the product of their marginals, and reports both the verdict and the size of the gap.",
        "params": [
          {
            "name": "input",
            "type": "{ pA: number; pB: number; pAB: number }",
            "required": true,
            "description": "`pA` and `pB` are the marginal probabilities and `pAB` the joint probability actually observed.",
            "constraints": {
              "pA": "0 <= pA <= 1",
              "pB": "0 <= pB <= 1",
              "pAB": "0 <= pAB <= min(pA, pB)"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ independent: boolean; dependenceGap: number }",
          "description": "`independent` is `true` when `|pAB - pA * pB|` is under 1e-12, and `dependenceGap` is the signed difference `pAB - pA * pB`, positive when the events co-occur more often than independence would imply."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`pA`, `pB`, or `pAB` falls outside [0, 1], or `pAB` exceeds `min(pA, pB)`",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F06-A04.json",
        "call": "independenceAndDependence({\"pA\":0.6,\"pB\":0.5,\"pAB\":0.3,\"outcomes\":[\"up\",\"flat\",\"down\"],\"event\":[\"up\",\"flat\"],\"prior\":0.01,\"sensitivity\":0.9,\"falsePositiveRate\":0.05,\"randomValues\":[0,1,2],\"probabilities\":[0.2,0.5,0.3],\"randomVariableKind\":\"discrete\",\"joint\":[{\"x\":0,\"y\":0,\"p\":0.3},{\"x\":0,\"y\":1,\"p\":0.2},{\"x\":1,\"y\":0,\"p\":0.1}],\"conditionY\":1})",
        "args": [
          {
            "value": {
              "pA": 0.6,
              "pB": 0.5,
              "pAB": 0.3,
              "outcomes": [
                "up",
                "flat",
                "down"
              ],
              "event": [
                "up",
                "flat"
              ],
              "prior": 0.01,
              "sensitivity": 0.9,
              "falsePositiveRate": 0.05,
              "randomValues": [
                0,
                1,
                2
              ],
              "probabilities": [
                0.2,
                0.5,
                0.3
              ],
              "randomVariableKind": "discrete",
              "joint": [
                {
                  "x": 0,
                  "y": 0,
                  "p": 0.3
                },
                {
                  "x": 0,
                  "y": 1,
                  "p": 0.2
                },
                {
                  "x": 1,
                  "y": 0,
                  "p": 0.1
                }
              ],
              "conditionY": 1
            },
            "elided": null
          }
        ],
        "output": {
          "independent": true,
          "dependenceGap": 0
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: independent, dependenceGap"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a04/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a04/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a04/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a04/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a04/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a04/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F06-A04",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Independence and Dependence\"]\n    D --> E[\"Formula: A and B independent iff P(A∩B)=P(A)P(B)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-and-random-variables/independence-and-dependence/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-and-random-variables/independence-and-dependence/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F06-A05",
      "name": "Bayes' Theorem and Base Rates",
      "headline": null,
      "slug": "bayes-theorem-and-base-rates",
      "path": "foundations/probability-and-random-variables/bayes-theorem-and-base-rates",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F06",
        "family": "Probability and Random Variables",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-and-random-variables/bayes-theorem-and-base-rates",
        "entry": "bayesTheoremAndBaseRates",
        "params": [
          "input"
        ],
        "exports": [
          "bayesTheoremAndBaseRates"
        ],
        "archetype": "record-transform",
        "signature": "bayesTheoremAndBaseRates(input)"
      },
      "api": {
        "summary": "Turns a prior, a true-positive rate, and a false-positive rate into the posterior probability of the condition given a positive result, along with the unconditional probability of that result.",
        "params": [
          {
            "name": "input",
            "type": "{ prior: number; sensitivity: number; falsePositiveRate: number; pA?: number; pB?: number; pAB?: number }",
            "required": true,
            "description": "`prior` is the base rate of the condition, `sensitivity` the chance of a positive result when the condition holds, and `falsePositiveRate` the chance of a positive result when it does not. Those three fields are the whole input. The shared F06 branch also validates the family-wide `pA`, `pB` and `pAB` before any topic runs; Bayes uses none of them, so the topic facade fills them with zero when they are absent. They may still be supplied, and are validated when they are.",
            "constraints": {
              "prior": "0 <= prior <= 1",
              "sensitivity": "0 <= sensitivity <= 1",
              "falsePositiveRate": "0 <= falsePositiveRate <= 1",
              "pA": "optional; 0 <= pA <= 1 when supplied, otherwise 0",
              "pB": "optional; 0 <= pB <= 1 when supplied, otherwise 0",
              "pAB": "optional; 0 <= pAB <= min(pA, pB) when supplied, otherwise 0"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ posterior: number; evidenceProbability: number }",
          "description": "`evidenceProbability` is `sensitivity * prior + falsePositiveRate * (1 - prior)`, the total chance of a positive result, and `posterior` is `sensitivity * prior` divided by it."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "a supplied `pA`, `pB`, or `pAB` falls outside [0, 1], or `pAB` exceeds `min(pA, pB)`",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`prior`, `sensitivity`, or `falsePositiveRate` falls outside [0, 1]",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the evidence probability works out to exactly zero, leaving the posterior undefined",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F06-A05.json",
        "call": "bayesTheoremAndBaseRates({\"prior\":0.01,\"sensitivity\":0.9,\"falsePositiveRate\":0.05})",
        "args": [
          {
            "value": {
              "prior": 0.01,
              "sensitivity": 0.9,
              "falsePositiveRate": 0.05
            },
            "elided": null
          }
        ],
        "output": {
          "posterior": 0.15384615384615385,
          "evidenceProbability": 0.0585
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: posterior, evidenceProbability"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a05/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a05/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a05/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a05/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a05/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a05/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F06-A05",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Bayes' Theorem and Base Rates\"]\n    D --> E[\"Formula: P(H|E)=P(E|H)P(H)/[P(E|H)P(H)+P(E|¬H)P(¬H)]\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-and-random-variables/bayes-theorem-and-base-rates/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-and-random-variables/bayes-theorem-and-base-rates/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F06-A06",
      "name": "Discrete and Continuous Random Variables",
      "headline": null,
      "slug": "discrete-and-continuous-random-variables",
      "path": "foundations/probability-and-random-variables/discrete-and-continuous-random-variables",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F06",
        "family": "Probability and Random Variables",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-and-random-variables/discrete-and-continuous-random-variables",
        "entry": "discreteAndContinuousRandomVariables",
        "params": [
          "input"
        ],
        "exports": [
          "discreteAndContinuousRandomVariables"
        ],
        "archetype": "record-transform",
        "signature": "discreteAndContinuousRandomVariables(input)"
      },
      "api": {
        "summary": "Validates a discrete random variable given as a support and a matching probability vector, returning the confirmed kind, the support, and the total mass it carries. Continuous densities are explained in the article but are not evaluated here.",
        "params": [
          {
            "name": "input",
            "type": "{ randomValues: number[]; probabilities: number[]; randomVariableKind?: \"discrete\"; pA?: number; pB?: number; pAB?: number }",
            "required": true,
            "description": "`randomValues` is the support and `probabilities` the mass on each point, position by position. `randomVariableKind` declares which kind of random variable the caller is describing; the topic facade confirms it is `discrete` and defaults it to `discrete` when absent, because the calculation checks a probability mass function and has no continuous branch. The shared F06 branch also validates the family-wide `pA`, `pB` and `pAB` before any topic runs; they are unused here, so the facade fills them with zero when they are absent.",
            "constraints": {
              "probabilities": "same length as `randomValues`, every entry nonnegative, summing to 1 within 1e-12",
              "randomVariableKind": "optional; must be the string `discrete` when supplied",
              "pA": "optional; 0 <= pA <= 1 when supplied, otherwise 0",
              "pB": "optional; 0 <= pB <= 1 when supplied, otherwise 0",
              "pAB": "optional; 0 <= pAB <= min(pA, pB) when supplied, otherwise 0"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ kind: string; support: number[]; probabilityMass: number }",
          "description": "`kind` is the confirmed label, always `discrete`; `support` is the coerced `randomValues`; and `probabilityMass` is the sum of the probabilities, which the guard has already pinned to 1 within 1e-12."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "a supplied `pA`, `pB`, or `pAB` falls outside [0, 1], or `pAB` exceeds `min(pA, pB)`",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`randomVariableKind` is supplied as anything other than `discrete`",
            "behaviour": "throws RangeError in TypeScript and ValueError in Python"
          },
          {
            "when": "`randomValues` or `probabilities` is missing, empty, or holds a non-finite entry",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`randomValues` and `probabilities` differ in length, a probability is negative, or the probabilities do not sum to one within 1e-12",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F06-A06.json",
        "call": "discreteAndContinuousRandomVariables({\"randomValues\":[0,1,2],\"probabilities\":[0.2,0.5,0.3],\"randomVariableKind\":\"discrete\"})",
        "args": [
          {
            "value": {
              "randomValues": [
                0,
                1,
                2
              ],
              "probabilities": [
                0.2,
                0.5,
                0.3
              ],
              "randomVariableKind": "discrete"
            },
            "elided": null
          }
        ],
        "output": {
          "kind": "discrete",
          "support": [
            0,
            1,
            2
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: kind, support"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a06/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a06/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a06/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a06/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a06/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a06/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F06-A06",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Discrete and Continuous Random Variables\"]\n    D --> E[\"Formula: X:Ω→ℝ; Σp(x)=1 for discrete support\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-and-random-variables/discrete-and-continuous-random-variables/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-and-random-variables/discrete-and-continuous-random-variables/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F06-A07",
      "name": "Expected Value",
      "headline": null,
      "slug": "expected-value",
      "path": "foundations/probability-and-random-variables/expected-value",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F06",
        "family": "Probability and Random Variables",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-and-random-variables/expected-value",
        "entry": "expectedValue",
        "params": [
          "input"
        ],
        "exports": [
          "expectedValue"
        ],
        "archetype": "record-transform",
        "signature": "expectedValue(input)"
      },
      "api": {
        "summary": "Weights each value of a discrete random variable by its probability and sums the result, keeping the individual products so the total can be read term by term.",
        "params": [
          {
            "name": "input",
            "type": "{ pA: number; pB: number; pAB: number; randomValues: number[]; probabilities: number[] }",
            "required": true,
            "description": "`randomValues` is the support and `probabilities` the mass on each point, position by position. The family-wide `pA`, `pB`, and `pAB` are validated on every call even though this topic does not use their values.",
            "constraints": {
              "pA": "0 <= pA <= 1",
              "pB": "0 <= pB <= 1",
              "pAB": "0 <= pAB <= min(pA, pB)",
              "probabilities": "same length as `randomValues`, every entry nonnegative, summing to 1 within 1e-12"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ expectedValue: number; contributions: number[] }",
          "description": "`expectedValue` is the probability-weighted sum, and `contributions` holds each `value * probability` term in support order, so one outcome dominating the mean is visible rather than buried."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`pA`, `pB`, or `pAB` falls outside [0, 1], or `pAB` exceeds `min(pA, pB)`",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`randomValues` or `probabilities` is missing, empty, or holds a non-finite entry",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`randomValues` and `probabilities` differ in length, a probability is negative, or the probabilities do not sum to one within 1e-12",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F06-A07.json",
        "call": "expectedValue({\"pA\":0.6,\"pB\":0.5,\"pAB\":0.3,\"outcomes\":[\"up\",\"flat\",\"down\"],\"event\":[\"up\",\"flat\"],\"prior\":0.01,\"sensitivity\":0.9,\"falsePositiveRate\":0.05,\"randomValues\":[0,1,2],\"probabilities\":[0.2,0.5,0.3],\"randomVariableKind\":\"discrete\",\"joint\":[{\"x\":0,\"y\":0,\"p\":0.3},{\"x\":0,\"y\":1,\"p\":0.2},{\"x\":1,\"y\":0,\"p\":0.1}],\"conditionY\":1})",
        "args": [
          {
            "value": {
              "pA": 0.6,
              "pB": 0.5,
              "pAB": 0.3,
              "outcomes": [
                "up",
                "flat",
                "down"
              ],
              "event": [
                "up",
                "flat"
              ],
              "prior": 0.01,
              "sensitivity": 0.9,
              "falsePositiveRate": 0.05,
              "randomValues": [
                0,
                1,
                2
              ],
              "probabilities": [
                0.2,
                0.5,
                0.3
              ],
              "randomVariableKind": "discrete",
              "joint": [
                {
                  "x": 0,
                  "y": 0,
                  "p": 0.3
                },
                {
                  "x": 0,
                  "y": 1,
                  "p": 0.2
                },
                {
                  "x": 1,
                  "y": 0,
                  "p": 0.1
                }
              ],
              "conditionY": 1
            },
            "elided": null
          }
        ],
        "output": {
          "expectedValue": 1.1,
          "contributions": [
            0,
            0.5,
            0.6
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: expectedValue, contributions"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a07/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a07/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a07/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a07/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a07/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a07/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F06-A07",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Expected Value\"]\n    D --> E[\"Formula: E[X]=Σx·p(x) (discrete)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-and-random-variables/expected-value/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-and-random-variables/expected-value/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F06-A08",
      "name": "Variance, Moments, and Moment-Generating Intuition",
      "headline": null,
      "slug": "variance-moments-and-moment-generating-intuition",
      "path": "foundations/probability-and-random-variables/variance-moments-and-moment-generating-intuition",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F06",
        "family": "Probability and Random Variables",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-and-random-variables/variance-moments-and-moment-generating-intuition",
        "entry": "varianceMomentsAndMomentGeneratingIntuition",
        "params": [
          "input"
        ],
        "exports": [
          "varianceMomentsAndMomentGeneratingIntuition"
        ],
        "archetype": "record-transform",
        "signature": "varianceMomentsAndMomentGeneratingIntuition(input)"
      },
      "api": {
        "summary": "Computes the first two raw moments of a discrete random variable and derives its variance as the second raw moment less the square of the first.",
        "params": [
          {
            "name": "input",
            "type": "{ pA: number; pB: number; pAB: number; randomValues: number[]; probabilities: number[] }",
            "required": true,
            "description": "`randomValues` is the support and `probabilities` the mass on each point, position by position. The family-wide `pA`, `pB`, and `pAB` are validated on every call even though this topic does not use their values.",
            "constraints": {
              "pA": "0 <= pA <= 1",
              "pB": "0 <= pB <= 1",
              "pAB": "0 <= pAB <= min(pA, pB)",
              "probabilities": "same length as `randomValues`, every entry nonnegative, summing to 1 within 1e-12"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ firstRawMoment: number; secondRawMoment: number; variance: number }",
          "description": "`firstRawMoment` is the expected value, `secondRawMoment` is the probability-weighted sum of squares, and `variance` is `secondRawMoment - firstRawMoment ** 2`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`pA`, `pB`, or `pAB` falls outside [0, 1], or `pAB` exceeds `min(pA, pB)`",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`randomValues` or `probabilities` is missing, empty, or holds a non-finite entry",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`randomValues` and `probabilities` differ in length, a probability is negative, or the probabilities do not sum to one within 1e-12",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F06-A08.json",
        "call": "varianceMomentsAndMomentGeneratingIntuition({\"pA\":0.6,\"pB\":0.5,\"pAB\":0.3,\"outcomes\":[\"up\",\"flat\",\"down\"],\"event\":[\"up\",\"flat\"],\"prior\":0.01,\"sensitivity\":0.9,\"falsePositiveRate\":0.05,\"randomValues\":[0,1,2],\"probabilities\":[0.2,0.5,0.3],\"randomVariableKind\":\"discrete\",\"joint\":[{\"x\":0,\"y\":0,\"p\":0.3},{\"x\":0,\"y\":1,\"p\":0.2},{\"x\":1,\"y\":0,\"p\":0.1}],\"conditionY\":1})",
        "args": [
          {
            "value": {
              "pA": 0.6,
              "pB": 0.5,
              "pAB": 0.3,
              "outcomes": [
                "up",
                "flat",
                "down"
              ],
              "event": [
                "up",
                "flat"
              ],
              "prior": 0.01,
              "sensitivity": 0.9,
              "falsePositiveRate": 0.05,
              "randomValues": [
                0,
                1,
                2
              ],
              "probabilities": [
                0.2,
                0.5,
                0.3
              ],
              "randomVariableKind": "discrete",
              "joint": [
                {
                  "x": 0,
                  "y": 0,
                  "p": 0.3
                },
                {
                  "x": 0,
                  "y": 1,
                  "p": 0.2
                },
                {
                  "x": 1,
                  "y": 0,
                  "p": 0.1
                }
              ],
              "conditionY": 1
            },
            "elided": null
          }
        ],
        "output": {
          "firstRawMoment": 1.1,
          "secondRawMoment": 1.7
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: firstRawMoment, secondRawMoment"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a08/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a08/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a08/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a08/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a08/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a08/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F06-A08",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Variance, Moments, and Moment-Generating Intuition\"]\n    D --> E[\"Formula: E[X²]=Σx²p(x); Var(X)=E[X²]−E[X]²\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-and-random-variables/variance-moments-and-moment-generating-intuition/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-and-random-variables/variance-moments-and-moment-generating-intuition/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F06-A09",
      "name": "Joint, Marginal, and Conditional Distributions",
      "headline": null,
      "slug": "joint-marginal-and-conditional-distributions",
      "path": "foundations/probability-and-random-variables/joint-marginal-and-conditional-distributions",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F06",
        "family": "Probability and Random Variables",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-and-random-variables/joint-marginal-and-conditional-distributions",
        "entry": "jointMarginalAndConditionalDistributions",
        "params": [
          "input"
        ],
        "exports": [
          "jointMarginalAndConditionalDistributions"
        ],
        "archetype": "record-transform",
        "signature": "jointMarginalAndConditionalDistributions(input)"
      },
      "api": {
        "summary": "Collapses a joint probability table over each axis in turn to give the two marginal distributions, then renormalises one slice of it to give the conditional distribution of X at a chosen value of Y.",
        "params": [
          {
            "name": "input",
            "type": "{ pA: number; pB: number; pAB: number; randomValues: number[]; probabilities: number[]; joint: { x: number; y: number; p: number }[]; conditionY: number | string }",
            "required": true,
            "description": "`joint` is the probability table as a flat list of cells, each carrying an `x` level, a `y` level, and its probability `p`. `conditionY` selects the Y level to condition on and is matched by string form, so `1` and `\"1\"` select the same slice. The family-wide `pA`, `pB`, `pAB`, `randomValues`, and `probabilities` are validated on every call.",
            "constraints": {
              "pA": "0 <= pA <= 1",
              "pB": "0 <= pB <= 1",
              "pAB": "0 <= pAB <= min(pA, pB)",
              "joint": "non-empty, every `p` nonnegative, all `p` summing to 1 within 1e-12",
              "conditionY": "must name a Y level whose marginal probability is not zero"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ marginalX: Record<string, number>; marginalY: Record<string, number>; conditionalXGivenY: Record<string, number> }",
          "description": "`marginalX` and `marginalY` sum the cell probabilities by X level and by Y level, keyed by the level rendered as a string. `conditionalXGivenY` divides the cells at the selected Y level by that level's marginal, so its entries sum to 1."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`pA`, `pB`, or `pAB` falls outside [0, 1], or `pAB` exceeds `min(pA, pB)`",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`randomValues` or `probabilities` is missing, empty, or holds a non-finite entry",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`randomValues` and `probabilities` differ in length, a probability is negative, or the probabilities do not sum to one within 1e-12",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`joint` is empty, a cell probability is negative, or the cell probabilities do not sum to one within 1e-12",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`conditionY` names a Y level with zero or missing marginal probability",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F06-A09.json",
        "call": "jointMarginalAndConditionalDistributions({\"pA\":0.6,\"pB\":0.5,\"pAB\":0.3,\"outcomes\":[\"up\",\"flat\",\"down\"],\"event\":[\"up\",\"flat\"],\"prior\":0.01,\"sensitivity\":0.9,\"falsePositiveRate\":0.05,\"randomValues\":[0,1,2],\"probabilities\":[0.2,0.5,0.3],\"randomVariableKind\":\"discrete\",\"joint\":[{\"x\":0,\"y\":0,\"p\":0.3},{\"x\":0,\"y\":1,\"p\":0.2},{\"x\":1,\"y\":0,\"p\":0.1}],\"conditionY\":1})",
        "args": [
          {
            "value": {
              "pA": 0.6,
              "pB": 0.5,
              "pAB": 0.3,
              "outcomes": [
                "up",
                "flat",
                "down"
              ],
              "event": [
                "up",
                "flat"
              ],
              "prior": 0.01,
              "sensitivity": 0.9,
              "falsePositiveRate": 0.05,
              "randomValues": [
                0,
                1,
                2
              ],
              "probabilities": [
                0.2,
                0.5,
                0.3
              ],
              "randomVariableKind": "discrete",
              "joint": [
                {
                  "x": 0,
                  "y": 0,
                  "p": 0.3
                },
                {
                  "x": 0,
                  "y": 1,
                  "p": 0.2
                },
                {
                  "x": 1,
                  "y": 0,
                  "p": 0.1
                }
              ],
              "conditionY": 1
            },
            "elided": null
          }
        ],
        "output": {
          "marginalX": {
            "0": 0.5,
            "1": 0.5
          },
          "marginalY": {
            "0": 0.4,
            "1": 0.6000000000000001
          }
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: marginalX, marginalY"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a09/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a09/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a09/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a09/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a09/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a09/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F06-A09",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Joint, Marginal, and Conditional Distributions\"]\n    D --> E[\"Formula: P(X=x)=Σy P(x,y); P(X=x|Y=y)=P(x,y)/P(Y=y)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-and-random-variables/joint-marginal-and-conditional-distributions/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-and-random-variables/joint-marginal-and-conditional-distributions/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F06-A10",
      "name": "Covariance and Correlation of Random Variables",
      "headline": null,
      "slug": "covariance-and-correlation-of-random-variables",
      "path": "foundations/probability-and-random-variables/covariance-and-correlation-of-random-variables",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F06",
        "family": "Probability and Random Variables",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-and-random-variables/covariance-and-correlation-of-random-variables",
        "entry": "covarianceAndCorrelationOfRandomVariables",
        "params": [
          "input"
        ],
        "exports": [
          "covarianceAndCorrelationOfRandomVariables"
        ],
        "archetype": "record-transform",
        "signature": "covarianceAndCorrelationOfRandomVariables(input)"
      },
      "api": {
        "summary": "Computes the probability-weighted covariance of the two variables in a joint distribution table and divides it by the product of their standard deviations to give the correlation.",
        "params": [
          {
            "name": "input",
            "type": "{ pA: number; pB: number; pAB: number; randomValues: number[]; probabilities: number[]; joint: { x: number; y: number; p: number }[] }",
            "required": true,
            "description": "`joint` is the probability table as a flat list of cells, each carrying an `x` level, a `y` level, and its probability `p`. These are distributional moments taken over the table, not sample moments over observed data. The family-wide `pA`, `pB`, `pAB`, `randomValues`, and `probabilities` are validated on every call.",
            "constraints": {
              "pA": "0 <= pA <= 1",
              "pB": "0 <= pB <= 1",
              "pAB": "0 <= pAB <= min(pA, pB)",
              "joint": "non-empty, every `p` nonnegative, all `p` summing to 1 within 1e-12, and neither variable degenerate"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ covariance: number; correlation: number }",
          "description": "`covariance` is the probability-weighted sum of the cross-deviations from the two expected values, and `correlation` is that covariance divided by the square root of the product of the two variances."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`input` is null, an array, or not an object",
            "behaviour": "throws TypeError"
          },
          {
            "when": "`pA`, `pB`, or `pAB` falls outside [0, 1], or `pAB` exceeds `min(pA, pB)`",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`randomValues` or `probabilities` is missing, empty, or holds a non-finite entry",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`randomValues` and `probabilities` differ in length, a probability is negative, or the probabilities do not sum to one within 1e-12",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`joint` is empty, a cell probability is negative, or the cell probabilities do not sum to one within 1e-12",
            "behaviour": "throws RangeError"
          },
          {
            "when": "either variable has zero variance under the joint table, leaving the correlation denominator at zero",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F06-A10.json",
        "call": "covarianceAndCorrelationOfRandomVariables({\"pA\":0.6,\"pB\":0.5,\"pAB\":0.3,\"outcomes\":[\"up\",\"flat\",\"down\"],\"event\":[\"up\",\"flat\"],\"prior\":0.01,\"sensitivity\":0.9,\"falsePositiveRate\":0.05,\"randomValues\":[0,1,2],\"probabilities\":[0.2,0.5,0.3],\"randomVariableKind\":\"discrete\",\"joint\":[{\"x\":0,\"y\":0,\"p\":0.3},{\"x\":0,\"y\":1,\"p\":0.2},{\"x\":1,\"y\":0,\"p\":0.1}],\"conditionY\":1})",
        "args": [
          {
            "value": {
              "pA": 0.6,
              "pB": 0.5,
              "pAB": 0.3,
              "outcomes": [
                "up",
                "flat",
                "down"
              ],
              "event": [
                "up",
                "flat"
              ],
              "prior": 0.01,
              "sensitivity": 0.9,
              "falsePositiveRate": 0.05,
              "randomValues": [
                0,
                1,
                2
              ],
              "probabilities": [
                0.2,
                0.5,
                0.3
              ],
              "randomVariableKind": "discrete",
              "joint": [
                {
                  "x": 0,
                  "y": 0,
                  "p": 0.3
                },
                {
                  "x": 0,
                  "y": 1,
                  "p": 0.2
                },
                {
                  "x": 1,
                  "y": 0,
                  "p": 0.1
                }
              ],
              "conditionY": 1
            },
            "elided": null
          }
        ],
        "output": {
          "covariance": 0.1,
          "correlation": 0.4082482904638631
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: covariance, correlation"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a10/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a10/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a10/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a10/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a10/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f06-a10/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F06-A10",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Covariance and Correlation of Random Variables\"]\n    D --> E[\"Formula: Cov(X,Y)=E[(X−EX)(Y−EY)]; ρ=Cov/(σXσY)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-and-random-variables/covariance-and-correlation-of-random-variables/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-and-random-variables/covariance-and-correlation-of-random-variables/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F07-A01",
      "name": "PMF, PDF, CDF, Survival, and Quantile Functions",
      "headline": null,
      "slug": "pmf-pdf-cdf-survival-and-quantile-functions",
      "path": "foundations/probability-distributions-and-simulation-basics/pmf-pdf-cdf-survival-and-quantile-functions",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F07",
        "family": "Probability Distributions and Simulation Basics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-distributions-and-simulation-basics/pmf-pdf-cdf-survival-and-quantile-functions",
        "entry": "pmfPdfCdfSurvivalAndQuantileFunctions",
        "params": [
          "input"
        ],
        "exports": [
          "pmfPdfCdfSurvivalAndQuantileFunctions"
        ],
        "archetype": "record-transform",
        "signature": "pmfPdfCdfSurvivalAndQuantileFunctions(input)"
      },
      "api": {
        "summary": "Reads an empirical sample from `input.values` and reports where the threshold `input.x` sits inside it, plus the sample quantile at probability `input.p`.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record. `values` is the observed sample, `x` is the threshold to evaluate the empirical CDF and survival at, and `p` is the quantile probability. Other keys in the record are ignored.",
            "constraints": {
              "values": "non-empty list of finite numbers",
              "p": "between 0 and 1 inclusive"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `cdf` (share of `values` at or below `x`), `survival` (share strictly above `x`) and `quantile` (the linearly interpolated sample quantile at `p`)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "p is missing or outside 0 to 1 — this check runs for every topic in the family",
            "behaviour": "throws RangeError"
          },
          {
            "when": "values is missing, empty, or contains a non-finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F07-A01.json",
        "call": "pmfPdfCdfSurvivalAndQuantileFunctions({\"values\":[0.2,0.5,0.7,1,1.4],\"x\":1,\"p\":0.3,\"n\":5,\"k\":2,\"lambda\":2,\"seed\":42,\"sampleCount\":8,\"mu\":0,\"sigma\":1,\"df\":5,\"shape\":2,\"scale\":1.5,\"components\":[{\"weight\":0.7,\"mean\":0,\"sd\":1},{\"weight\":0.3,\"mean\":3,\"sd\":0.8}]})",
        "args": [
          {
            "value": {
              "values": [
                0.2,
                0.5,
                0.7,
                1,
                1.4
              ],
              "x": 1,
              "p": 0.3,
              "n": 5,
              "k": 2,
              "lambda": 2,
              "seed": 42,
              "sampleCount": 8,
              "mu": 0,
              "sigma": 1,
              "df": 5,
              "shape": 2,
              "scale": 1.5,
              "components": [
                {
                  "weight": 0.7,
                  "mean": 0,
                  "sd": 1
                },
                {
                  "weight": 0.3,
                  "mean": 3,
                  "sd": 0.8
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "cdf": 0.8,
          "survival": 0.2
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: cdf, survival"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a01/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a01/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a01/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a01/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a01/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a01/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F07-A01",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply PMF, PDF, CDF, Survival, and Quantile Functions\"]\n    D --> E[\"Formula: F(x)=P(X≤x); S(x)=1−F(x); Q(p)=inf{x:F(x)≥p}\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-distributions-and-simulation-basics/pmf-pdf-cdf-survival-and-quantile-functions/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-distributions-and-simulation-basics/pmf-pdf-cdf-survival-and-quantile-functions/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F07-A02",
      "name": "Bernoulli and Binomial Distributions",
      "headline": null,
      "slug": "bernoulli-and-binomial-distributions",
      "path": "foundations/probability-distributions-and-simulation-basics/bernoulli-and-binomial-distributions",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F07",
        "family": "Probability Distributions and Simulation Basics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-distributions-and-simulation-basics/bernoulli-and-binomial-distributions",
        "entry": "bernoulliAndBinomialDistributions",
        "params": [
          "input"
        ],
        "exports": [
          "bernoulliAndBinomialDistributions"
        ],
        "archetype": "record-transform",
        "signature": "bernoulliAndBinomialDistributions(input)"
      },
      "api": {
        "summary": "Computes the Bernoulli mean and the binomial probability mass and cumulative probability for `k` successes in `n` independent trials with success probability `p`.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record carrying `p` (success probability of a single trial), `n` (number of trials) and `k` (number of successes to evaluate).",
            "constraints": {
              "p": "between 0 and 1 inclusive",
              "n": "integer, zero or greater",
              "k": "integer, between 0 and n inclusive"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `bernoulliMean` (equal to `p`), `binomialPmf` (the mass at exactly `k`) and `binomialCdf` (the mass summed from zero through `k`)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "p is missing or outside 0 to 1 — this check runs for every topic in the family",
            "behaviour": "throws RangeError"
          },
          {
            "when": "n or k is not an integer, n is negative, k is negative, or k exceeds n",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n*k)",
          "space": "O(k)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F07-A02.json",
        "call": "bernoulliAndBinomialDistributions({\"values\":[0.2,0.5,0.7,1,1.4],\"x\":1,\"p\":0.3,\"n\":5,\"k\":2,\"lambda\":2,\"seed\":42,\"sampleCount\":8,\"mu\":0,\"sigma\":1,\"df\":5,\"shape\":2,\"scale\":1.5,\"components\":[{\"weight\":0.7,\"mean\":0,\"sd\":1},{\"weight\":0.3,\"mean\":3,\"sd\":0.8}]})",
        "args": [
          {
            "value": {
              "values": [
                0.2,
                0.5,
                0.7,
                1,
                1.4
              ],
              "x": 1,
              "p": 0.3,
              "n": 5,
              "k": 2,
              "lambda": 2,
              "seed": 42,
              "sampleCount": 8,
              "mu": 0,
              "sigma": 1,
              "df": 5,
              "shape": 2,
              "scale": 1.5,
              "components": [
                {
                  "weight": 0.7,
                  "mean": 0,
                  "sd": 1
                },
                {
                  "weight": 0.3,
                  "mean": 3,
                  "sd": 0.8
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "bernoulliMean": 0.3,
          "binomialPmf": 0.3086999999999999
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: bernoulliMean, binomialPmf"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a02/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a02/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a02/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a02/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a02/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a02/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F07-A02",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Bernoulli and Binomial Distributions\"]\n    D --> E[\"Formula: P(K=k)=C(n,k)pᵏ(1−p)^(n−k)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-distributions-and-simulation-basics/bernoulli-and-binomial-distributions/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-distributions-and-simulation-basics/bernoulli-and-binomial-distributions/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F07-A03",
      "name": "Poisson Distribution and Event Counts",
      "headline": null,
      "slug": "poisson-distribution-and-event-counts",
      "path": "foundations/probability-distributions-and-simulation-basics/poisson-distribution-and-event-counts",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F07",
        "family": "Probability Distributions and Simulation Basics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-distributions-and-simulation-basics/poisson-distribution-and-event-counts",
        "entry": "poissonDistributionAndEventCounts",
        "params": [
          "input"
        ],
        "exports": [
          "poissonDistributionAndEventCounts"
        ],
        "archetype": "record-transform",
        "signature": "poissonDistributionAndEventCounts(input)"
      },
      "api": {
        "summary": "Evaluates the Poisson probability of exactly `k` events, the cumulative probability of at most `k`, and the distribution's mean and variance, for a rate of `lambda` events per interval.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record carrying `lambda` (the expected event count per interval), `k` (the event count to evaluate) and `p`, which the family entry point validates before dispatching.",
            "constraints": {
              "lambda": "zero or greater",
              "k": "integer, zero or greater",
              "p": "between 0 and 1 inclusive"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `pmf` (probability of exactly `k` events), `cdf` (probability of at most `k`), and `mean` and `variance`, both equal to `lambda`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "p is missing or outside 0 to 1 — this check runs for every topic in the family",
            "behaviour": "throws RangeError"
          },
          {
            "when": "lambda is negative, or k is not an integer at or above zero",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(k^2)",
          "space": "O(k)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F07-A03.json",
        "call": "poissonDistributionAndEventCounts({\"values\":[0.2,0.5,0.7,1,1.4],\"x\":1,\"p\":0.3,\"n\":5,\"k\":2,\"lambda\":2,\"seed\":42,\"sampleCount\":8,\"mu\":0,\"sigma\":1,\"df\":5,\"shape\":2,\"scale\":1.5,\"components\":[{\"weight\":0.7,\"mean\":0,\"sd\":1},{\"weight\":0.3,\"mean\":3,\"sd\":0.8}]})",
        "args": [
          {
            "value": {
              "values": [
                0.2,
                0.5,
                0.7,
                1,
                1.4
              ],
              "x": 1,
              "p": 0.3,
              "n": 5,
              "k": 2,
              "lambda": 2,
              "seed": 42,
              "sampleCount": 8,
              "mu": 0,
              "sigma": 1,
              "df": 5,
              "shape": 2,
              "scale": 1.5,
              "components": [
                {
                  "weight": 0.7,
                  "mean": 0,
                  "sd": 1
                },
                {
                  "weight": 0.3,
                  "mean": 3,
                  "sd": 0.8
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "pmf": 0.2706705664732254,
          "cdf": 0.6766764161830635
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: pmf, cdf"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a03/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a03/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a03/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a03/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a03/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a03/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F07-A03",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Poisson Distribution and Event Counts\"]\n    D --> E[\"Formula: P(K=k)=e^(−λ)λᵏ/k!\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-distributions-and-simulation-basics/poisson-distribution-and-event-counts/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-distributions-and-simulation-basics/poisson-distribution-and-event-counts/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F07-A04",
      "name": "Uniform Distribution and Random Sampling",
      "headline": null,
      "slug": "uniform-distribution-and-random-sampling",
      "path": "foundations/probability-distributions-and-simulation-basics/uniform-distribution-and-random-sampling",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F07",
        "family": "Probability Distributions and Simulation Basics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-distributions-and-simulation-basics/uniform-distribution-and-random-sampling",
        "entry": "uniformDistributionAndRandomSampling",
        "params": [
          "input"
        ],
        "exports": [
          "uniformDistributionAndRandomSampling"
        ],
        "archetype": "record-transform",
        "signature": "uniformDistributionAndRandomSampling(input)"
      },
      "api": {
        "summary": "Draws `sampleCount` standard uniform values on the half-open unit interval from a seeded linear congruential generator and reports the draws with their support and realised mean. A general Uniform(a, b) draw is that output rescaled by the caller.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record carrying `seed` (the generator's starting state) and `sampleCount` (how many draws to produce). Those two fields are the whole input. The shared F07 branch also reads `x`, `p`, `n`, `k` and `lambda` before dispatching, and validates `p`; none of them affect this draw, so the topic facade fills them when they are absent. There are no `a` and `b` parameters: the generator produces standard uniform draws, which is Uniform(a, b) with a = 0 and b = 1.",
            "constraints": {
              "sampleCount": "1 or greater",
              "seed": "any integer; the generator masks it to 32 bits",
              "p": "optional; between 0 and 1 inclusive when supplied, otherwise 0"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `samples` (the draws, each in the half-open unit interval), `minimum` and `maximum` (the theoretical support, always 0 and 1) and `sampleMean` (the mean of the draws actually produced)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a supplied p falls outside 0 to 1 — this check runs for every topic in the family",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sampleCount is below 1",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F07-A04.json",
        "call": "uniformDistributionAndRandomSampling({\"seed\":42,\"sampleCount\":8})",
        "args": [
          {
            "value": {
              "seed": 42,
              "sampleCount": 8
            },
            "elided": null
          }
        ],
        "output": {
          "samples": [
            0.2523451747838408,
            0.08812504541128874,
            0.5772811982315034,
            0.22255426598712802,
            0.37566019711084664,
            0.02566390484571457
          ],
          "minimum": 0
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: samples, minimum"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a04/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a04/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a04/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a04/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a04/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a04/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F07-A04",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Uniform Distribution and Random Sampling\"]\n    D --> E[\"Formula: X∼Uniform(a,b); f(x)=1/(b−a)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-distributions-and-simulation-basics/uniform-distribution-and-random-sampling/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-distributions-and-simulation-basics/uniform-distribution-and-random-sampling/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F07-A05",
      "name": "Normal Distribution and Standard Normal",
      "headline": null,
      "slug": "normal-distribution-and-standard-normal",
      "path": "foundations/probability-distributions-and-simulation-basics/normal-distribution-and-standard-normal",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F07",
        "family": "Probability Distributions and Simulation Basics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-distributions-and-simulation-basics/normal-distribution-and-standard-normal",
        "entry": "normalDistributionAndStandardNormal",
        "params": [
          "input"
        ],
        "exports": [
          "normalDistributionAndStandardNormal"
        ],
        "archetype": "record-transform",
        "signature": "normalDistributionAndStandardNormal(input)"
      },
      "api": {
        "summary": "Evaluates the normal density and cumulative probability at `input.x` for a distribution with mean `mu` and standard deviation `sigma`, and returns the standardised score that maps `x` onto the standard normal.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record carrying `x` (the point to evaluate), `mu` and `sigma` (the distribution's mean and standard deviation). Those three fields are the whole input. The shared F07 branch also reads `p`, `n`, `k` and `lambda` before dispatching, and validates `p`; none of them affect the normal density, so the topic facade fills them when they are absent.",
            "constraints": {
              "sigma": "strictly positive",
              "p": "optional; between 0 and 1 inclusive when supplied, otherwise 0"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `pdf` (the density at `x`), `cdf` (the cumulative probability at `x`) and `z` (the standardised score). The two languages reach `cdf` differently: Python calls the platform error function and TypeScript uses the Abramowitz-Stegun 7.1.26 approximation, so compare them with a tolerance near 1e-7 rather than bit for bit. Neither is an exact integral."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a supplied p falls outside 0 to 1 — this check runs for every topic in the family",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sigma is zero or negative — this check runs for every topic from A05 onward",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F07-A05.json",
        "call": "normalDistributionAndStandardNormal({\"x\":1,\"mu\":0,\"sigma\":1})",
        "args": [
          {
            "value": {
              "x": 1,
              "mu": 0,
              "sigma": 1
            },
            "elided": null
          }
        ],
        "output": {
          "pdf": 0.24197072451914337,
          "cdf": 0.8413447460685428
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: pdf, cdf"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a05/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a05/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a05/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a05/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a05/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a05/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F07-A05",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Normal Distribution and Standard Normal\"]\n    D --> E[\"Formula: f(x)=exp(−z²/2)/(σ√(2π)); z=(x−μ)/σ\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-distributions-and-simulation-basics/normal-distribution-and-standard-normal/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-distributions-and-simulation-basics/normal-distribution-and-standard-normal/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F07-A06",
      "name": "Lognormal Distribution and Positive Quantities",
      "headline": null,
      "slug": "lognormal-distribution-and-positive-quantities",
      "path": "foundations/probability-distributions-and-simulation-basics/lognormal-distribution-and-positive-quantities",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F07",
        "family": "Probability Distributions and Simulation Basics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-distributions-and-simulation-basics/lognormal-distribution-and-positive-quantities",
        "entry": "lognormalDistributionAndPositiveQuantities",
        "params": [
          "input"
        ],
        "exports": [
          "lognormalDistributionAndPositiveQuantities"
        ],
        "archetype": "record-transform",
        "signature": "lognormalDistributionAndPositiveQuantities(input)"
      },
      "api": {
        "summary": "Evaluates the lognormal density and cumulative probability at `input.x` for a variable whose logarithm is normal with mean `mu` and standard deviation `sigma`, and returns the distribution's median.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record carrying `x` (the point to evaluate, on the original positive scale), `mu` and `sigma` (the mean and standard deviation of the underlying log scale), plus `p`, which the family entry point validates before dispatching.",
            "constraints": {
              "sigma": "strictly positive",
              "p": "between 0 and 1 inclusive"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `pdf`, `cdf` and `median`. The median is always `exp(mu)`. For `x` at or below zero the function returns `pdf` and `cdf` of zero rather than throwing, since the lognormal puts no mass there."
        },
        "warmup": null,
        "errors": [
          {
            "when": "p is missing or outside 0 to 1 — this check runs for every topic in the family",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sigma is zero or negative — this check runs for every topic from A05 onward",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F07-A06.json",
        "call": "lognormalDistributionAndPositiveQuantities({\"values\":[0.2,0.5,0.7,1,1.4],\"x\":1,\"p\":0.3,\"n\":5,\"k\":2,\"lambda\":2,\"seed\":42,\"sampleCount\":8,\"mu\":0,\"sigma\":1,\"df\":5,\"shape\":2,\"scale\":1.5,\"components\":[{\"weight\":0.7,\"mean\":0,\"sd\":1},{\"weight\":0.3,\"mean\":3,\"sd\":0.8}]})",
        "args": [
          {
            "value": {
              "values": [
                0.2,
                0.5,
                0.7,
                1,
                1.4
              ],
              "x": 1,
              "p": 0.3,
              "n": 5,
              "k": 2,
              "lambda": 2,
              "seed": 42,
              "sampleCount": 8,
              "mu": 0,
              "sigma": 1,
              "df": 5,
              "shape": 2,
              "scale": 1.5,
              "components": [
                {
                  "weight": 0.7,
                  "mean": 0,
                  "sd": 1
                },
                {
                  "weight": 0.3,
                  "mean": 3,
                  "sd": 0.8
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "pdf": 0.3989422804014327,
          "cdf": 0.5
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: pdf, cdf"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a06/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a06/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a06/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a06/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a06/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a06/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F07-A06",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Lognormal Distribution and Positive Quantities\"]\n    D --> E[\"Formula: if ln X∼N(μ,σ²), f(x)=exp[−(ln x−μ)²/(2σ²)]/(xσ√(2π)), x>0\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-distributions-and-simulation-basics/lognormal-distribution-and-positive-quantities/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-distributions-and-simulation-basics/lognormal-distribution-and-positive-quantities/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F07-A07",
      "name": "Student-t Distribution and Heavy Tails",
      "headline": null,
      "slug": "student-t-distribution-and-heavy-tails",
      "path": "foundations/probability-distributions-and-simulation-basics/student-t-distribution-and-heavy-tails",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F07",
        "family": "Probability Distributions and Simulation Basics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-distributions-and-simulation-basics/student-t-distribution-and-heavy-tails",
        "entry": "studentTDistributionAndHeavyTails",
        "params": [
          "input"
        ],
        "exports": [
          "studentTDistributionAndHeavyTails"
        ],
        "archetype": "record-transform",
        "signature": "studentTDistributionAndHeavyTails(input)"
      },
      "api": {
        "summary": "Evaluates the Student t density at `input.x` for `df` degrees of freedom and reports the distribution's variance, which only exists once `df` passes two.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record carrying `x` (the point to evaluate) and `df` (degrees of freedom), plus `p` and `sigma`, which the family entry point validates before dispatching.",
            "constraints": {
              "df": "strictly positive",
              "sigma": "strictly positive",
              "p": "between 0 and 1 inclusive"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `pdf` (the density at `x`, using a Lanczos gamma approximation for the normalising constant), `degreesOfFreedom` (echoes `df`) and `variance`, which is `df / (df - 2)` when `df` exceeds two and `null` otherwise."
        },
        "warmup": null,
        "errors": [
          {
            "when": "p is missing or outside 0 to 1 — this check runs for every topic in the family",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sigma is zero or negative — this check runs for every topic from A05 onward",
            "behaviour": "throws RangeError"
          },
          {
            "when": "df is zero or negative",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F07-A07.json",
        "call": "studentTDistributionAndHeavyTails({\"values\":[0.2,0.5,0.7,1,1.4],\"x\":1,\"p\":0.3,\"n\":5,\"k\":2,\"lambda\":2,\"seed\":42,\"sampleCount\":8,\"mu\":0,\"sigma\":1,\"df\":5,\"shape\":2,\"scale\":1.5,\"components\":[{\"weight\":0.7,\"mean\":0,\"sd\":1},{\"weight\":0.3,\"mean\":3,\"sd\":0.8}]})",
        "args": [
          {
            "value": {
              "values": [
                0.2,
                0.5,
                0.7,
                1,
                1.4
              ],
              "x": 1,
              "p": 0.3,
              "n": 5,
              "k": 2,
              "lambda": 2,
              "seed": 42,
              "sampleCount": 8,
              "mu": 0,
              "sigma": 1,
              "df": 5,
              "shape": 2,
              "scale": 1.5,
              "components": [
                {
                  "weight": 0.7,
                  "mean": 0,
                  "sd": 1
                },
                {
                  "weight": 0.3,
                  "mean": 3,
                  "sd": 0.8
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "pdf": 0.21967979735098053,
          "degreesOfFreedom": 5
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: pdf, degreesOfFreedom"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a07/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a07/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a07/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a07/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a07/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a07/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F07-A07",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Student-t Distribution and Heavy Tails\"]\n    D --> E[\"Formula: f(x)=Γ((ν+1)/2)/[√(νπ)Γ(ν/2)]·(1+x²/ν)^−(ν+1)/2\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-distributions-and-simulation-basics/student-t-distribution-and-heavy-tails/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-distributions-and-simulation-basics/student-t-distribution-and-heavy-tails/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F07-A08",
      "name": "Exponential, Gamma, and Weibull Waiting-Time Models",
      "headline": null,
      "slug": "exponential-gamma-and-weibull-waiting-time-models",
      "path": "foundations/probability-distributions-and-simulation-basics/exponential-gamma-and-weibull-waiting-time-models",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F07",
        "family": "Probability Distributions and Simulation Basics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-distributions-and-simulation-basics/exponential-gamma-and-weibull-waiting-time-models",
        "entry": "exponentialGammaAndWeibullWaitingTimeModels",
        "params": [
          "input"
        ],
        "exports": [
          "exponentialGammaAndWeibullWaitingTimeModels"
        ],
        "archetype": "record-transform",
        "signature": "exponentialGammaAndWeibullWaitingTimeModels(input)"
      },
      "api": {
        "summary": "Evaluates three waiting-time models at the same point `input.x`: the exponential survival function, the gamma density, and the Weibull survival function, all sharing `shape` and `scale`.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record carrying `x` (the waiting time to evaluate), `shape` (the gamma and Weibull shape parameter) and `scale` (the common scale), plus `p` and `sigma`, which the family entry point validates before dispatching.",
            "constraints": {
              "sigma": "strictly positive",
              "p": "between 0 and 1 inclusive"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `exponentialSurvival` (probability of waiting longer than `x` under an exponential with mean `scale`), `gammaPdf` (the gamma density at `x`) and `weibullSurvival` (the Weibull survival at `x`)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "p is missing or outside 0 to 1 — this check runs for every topic in the family",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sigma is zero or negative — this check runs for every topic from A05 onward",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F07-A08.json",
        "call": "exponentialGammaAndWeibullWaitingTimeModels({\"values\":[0.2,0.5,0.7,1,1.4],\"x\":1,\"p\":0.3,\"n\":5,\"k\":2,\"lambda\":2,\"seed\":42,\"sampleCount\":8,\"mu\":0,\"sigma\":1,\"df\":5,\"shape\":2,\"scale\":1.5,\"components\":[{\"weight\":0.7,\"mean\":0,\"sd\":1},{\"weight\":0.3,\"mean\":3,\"sd\":0.8}]})",
        "args": [
          {
            "value": {
              "values": [
                0.2,
                0.5,
                0.7,
                1,
                1.4
              ],
              "x": 1,
              "p": 0.3,
              "n": 5,
              "k": 2,
              "lambda": 2,
              "seed": 42,
              "sampleCount": 8,
              "mu": 0,
              "sigma": 1,
              "df": 5,
              "shape": 2,
              "scale": 1.5,
              "components": [
                {
                  "weight": 0.7,
                  "mean": 0,
                  "sd": 1
                },
                {
                  "weight": 0.3,
                  "mean": 3,
                  "sd": 0.8
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "exponentialSurvival": 0.513417119032592,
          "gammaPdf": 0.22818538623670756
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: exponentialSurvival, gammaPdf"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a08/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a08/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a08/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a08/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a08/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a08/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F07-A08",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Exponential, Gamma, and Weibull Waiting-Time Models\"]\n    D --> E[\"Formula: Sexp(x)=e^(−x/scale); SWeibull(x)=e^−(x/scale)^shape\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-distributions-and-simulation-basics/exponential-gamma-and-weibull-waiting-time-models/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-distributions-and-simulation-basics/exponential-gamma-and-weibull-waiting-time-models/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F07-A09",
      "name": "Mixture Distributions, Multimodality, and Fat Tails",
      "headline": null,
      "slug": "mixture-distributions-multimodality-and-fat-tails",
      "path": "foundations/probability-distributions-and-simulation-basics/mixture-distributions-multimodality-and-fat-tails",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F07",
        "family": "Probability Distributions and Simulation Basics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-distributions-and-simulation-basics/mixture-distributions-multimodality-and-fat-tails",
        "entry": "mixtureDistributionsMultimodalityAndFatTails",
        "params": [
          "input"
        ],
        "exports": [
          "mixtureDistributionsMultimodalityAndFatTails"
        ],
        "archetype": "record-transform",
        "signature": "mixtureDistributionsMultimodalityAndFatTails(input)"
      },
      "api": {
        "summary": "Evaluates a weighted mixture of normal components at `input.x`, which is how a single series can show more than one mode and fatter tails than any of its parts.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record carrying `x` (the point to evaluate) and `components`, a list where each entry has `weight`, `mean` and `sd`. `p` and `sigma` are validated by the family entry point before dispatching.",
            "constraints": {
              "components": "non-empty; every weight nonnegative, weights summing to one within 1e-12, every sd strictly positive",
              "sigma": "strictly positive",
              "p": "between 0 and 1 inclusive"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `mixturePdf` (the weighted sum of the component densities at `x`), `componentCount` and `weightSum`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "p is missing or outside 0 to 1 — this check runs for every topic in the family",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sigma is zero or negative — this check runs for every topic from A05 onward",
            "behaviour": "throws RangeError"
          },
          {
            "when": "components is empty, a weight is negative, the weights miss one by more than 1e-12, or a component sd is zero or negative",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(m)",
          "space": "O(m)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F07-A09.json",
        "call": "mixtureDistributionsMultimodalityAndFatTails({\"values\":[0.2,0.5,0.7,1,1.4],\"x\":1,\"p\":0.3,\"n\":5,\"k\":2,\"lambda\":2,\"seed\":42,\"sampleCount\":8,\"mu\":0,\"sigma\":1,\"df\":5,\"shape\":2,\"scale\":1.5,\"components\":[{\"weight\":0.7,\"mean\":0,\"sd\":1},{\"weight\":0.3,\"mean\":3,\"sd\":0.8}]})",
        "args": [
          {
            "value": {
              "values": [
                0.2,
                0.5,
                0.7,
                1,
                1.4
              ],
              "x": 1,
              "p": 0.3,
              "n": 5,
              "k": 2,
              "lambda": 2,
              "seed": 42,
              "sampleCount": 8,
              "mu": 0,
              "sigma": 1,
              "df": 5,
              "shape": 2,
              "scale": 1.5,
              "components": [
                {
                  "weight": 0.7,
                  "mean": 0,
                  "sd": 1
                },
                {
                  "weight": 0.3,
                  "mean": 3,
                  "sd": 0.8
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "mixturePdf": 0.17595261984848856,
          "componentCount": 2
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: mixturePdf, componentCount"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a09/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a09/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a09/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a09/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a09/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a09/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F07-A09",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Mixture Distributions, Multimodality, and Fat Tails\"]\n    D --> E[\"Formula: f(x)=Σwⱼfⱼ(x); wⱼ≥0; Σwⱼ=1\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-distributions-and-simulation-basics/mixture-distributions-multimodality-and-fat-tails/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-distributions-and-simulation-basics/mixture-distributions-multimodality-and-fat-tails/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F07-A10",
      "name": "Random Sampling and Monte Carlo Intuition",
      "headline": null,
      "slug": "random-sampling-and-monte-carlo-intuition",
      "path": "foundations/probability-distributions-and-simulation-basics/random-sampling-and-monte-carlo-intuition",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F07",
        "family": "Probability Distributions and Simulation Basics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/probability-distributions-and-simulation-basics/random-sampling-and-monte-carlo-intuition",
        "entry": "randomSamplingAndMonteCarloIntuition",
        "params": [
          "input"
        ],
        "exports": [
          "randomSamplingAndMonteCarloIntuition"
        ],
        "archetype": "record-transform",
        "signature": "randomSamplingAndMonteCarloIntuition(input)"
      },
      "api": {
        "summary": "Estimates the probability `p` by counting how many of `sampleCount` seeded uniform draws land at or below it, and reports how far that Monte Carlo estimate lands from the known answer.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record carrying `seed` and `sampleCount` for the draw, and `p`, which is both the probability being estimated and the target the estimate is scored against. `sigma` is validated by the family entry point before dispatching.",
            "constraints": {
              "sampleCount": "1 or greater",
              "sigma": "strictly positive",
              "p": "between 0 and 1 inclusive"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `estimate` (share of draws at or below `p`), `target` (echoes `p`), `absoluteError` (the gap between the two) and `sampleCount` (the number of draws actually used)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "p is missing or outside 0 to 1 — this check runs for every topic in the family",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sigma is zero or negative — this check runs for every topic from A05 onward",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sampleCount is below 1",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F07-A10.json",
        "call": "randomSamplingAndMonteCarloIntuition({\"values\":[0.2,0.5,0.7,1,1.4],\"x\":1,\"p\":0.3,\"n\":5,\"k\":2,\"lambda\":2,\"seed\":42,\"sampleCount\":8,\"mu\":0,\"sigma\":1,\"df\":5,\"shape\":2,\"scale\":1.5,\"components\":[{\"weight\":0.7,\"mean\":0,\"sd\":1},{\"weight\":0.3,\"mean\":3,\"sd\":0.8}]})",
        "args": [
          {
            "value": {
              "values": [
                0.2,
                0.5,
                0.7,
                1,
                1.4
              ],
              "x": 1,
              "p": 0.3,
              "n": 5,
              "k": 2,
              "lambda": 2,
              "seed": 42,
              "sampleCount": 8,
              "mu": 0,
              "sigma": 1,
              "df": 5,
              "shape": 2,
              "scale": 1.5,
              "components": [
                {
                  "weight": 0.7,
                  "mean": 0,
                  "sd": 1
                },
                {
                  "weight": 0.3,
                  "mean": 3,
                  "sd": 0.8
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "estimate": 0.625,
          "target": 0.3
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: estimate, target"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a10/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a10/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a10/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a10/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a10/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f07-a10/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F07-A10",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Random Sampling and Monte Carlo Intuition\"]\n    D --> E[\"Formula: estimate=(1/N)Σg(Uᵢ); sampling error usually shrinks on the order of 1/√N\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Probability Distributions",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda36.htm"
        },
        {
          "key": "SciPy User Guide",
          "title": "Probability Distributions",
          "author": "SciPy User Guide",
          "url": "https://docs.scipy.org/doc/scipy/tutorial/stats/probability_distributions.html"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/probability-distributions-and-simulation-basics/random-sampling-and-monte-carlo-intuition/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/probability-distributions-and-simulation-basics/random-sampling-and-monte-carlo-intuition/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F08-A01",
      "name": "Parameters, Statistics, Estimands, and Estimators",
      "headline": null,
      "slug": "parameters-statistics-estimands-and-estimators",
      "path": "foundations/sampling-estimation-and-statistical-inference/parameters-statistics-estimands-and-estimators",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F08",
        "family": "Sampling, Estimation, and Statistical Inference",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/sampling-estimation-and-statistical-inference/parameters-statistics-estimands-and-estimators",
        "entry": "parametersStatisticsEstimandsAndEstimators",
        "params": [
          "input"
        ],
        "exports": [
          "parametersStatisticsEstimandsAndEstimators"
        ],
        "archetype": "record-transform",
        "signature": "parametersStatisticsEstimandsAndEstimators(input)"
      },
      "api": {
        "summary": "Places the known population parameter from `input.populationMean` alongside the statistic computed from `input.sample`, and names which side is the estimand and which is the estimator.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record. `sample` is the observed data and `populationMean` is the parameter it is meant to estimate. `estimates` and `alpha` are validated for the whole family before dispatch, so they must be present and valid here too.",
            "constraints": {
              "sample": "non-empty list of finite numbers, at least two of them",
              "estimates": "non-empty list of finite numbers",
              "alpha": "strictly between 0 and 1"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `parameter` (echoes `populationMean`), `statistic` (the sample mean), and the fixed labels `estimand` and `estimator`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "sample or estimates is missing, empty, or contains a non-finite number — both are parsed for every topic in the family, whether or not the topic uses them",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sample holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "alpha is not strictly between zero and one",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n + m)",
          "space": "O(n + m)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F08-A01.json",
        "call": "parametersStatisticsEstimandsAndEstimators({\"sample\":[2,3,4,3,4],\"estimates\":[3,3.1,3.2,3.3,3.4],\"populationMean\":3.2,\"alpha\":0.05,\"mseBenchmark\":0.1,\"nullMean\":3,\"alternativeMean\":3.5,\"practicalThreshold\":0.1,\"comparisons\":5})",
        "args": [
          {
            "value": {
              "sample": [
                2,
                3,
                4,
                3,
                4
              ],
              "estimates": [
                3,
                3.1,
                3.2,
                3.3,
                3.4
              ],
              "populationMean": 3.2,
              "alpha": 0.05,
              "mseBenchmark": 0.1,
              "nullMean": 3,
              "alternativeMean": 3.5,
              "practicalThreshold": 0.1,
              "comparisons": 5
            },
            "elided": null
          }
        ],
        "output": {
          "parameter": 3.2,
          "statistic": 3.2
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: parameter, statistic"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a01/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a01/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a01/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a01/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a01/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a01/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F08-A01",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Parameters, Statistics, Estimands, and Estimators\"]\n    D --> E[\"Formula: parameter θ; estimator θ̂=T(sample); observed estimate=t(data)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Product and Process Comparisons",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc1.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Confidence Intervals",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc14.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/sampling-estimation-and-statistical-inference/parameters-statistics-estimands-and-estimators/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/sampling-estimation-and-statistical-inference/parameters-statistics-estimands-and-estimators/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F08-A02",
      "name": "Sampling Distributions",
      "headline": null,
      "slug": "sampling-distributions",
      "path": "foundations/sampling-estimation-and-statistical-inference/sampling-distributions",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F08",
        "family": "Sampling, Estimation, and Statistical Inference",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/sampling-estimation-and-statistical-inference/sampling-distributions",
        "entry": "samplingDistributions",
        "params": [
          "input"
        ],
        "exports": [
          "samplingDistributions"
        ],
        "archetype": "record-transform",
        "signature": "samplingDistributions(input)"
      },
      "api": {
        "summary": "Summarises the replicated estimates in `input.estimates` as a sampling distribution: where it centres, how wide it is, and how many replications produced it.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record. `estimates` holds one value per replication. `sample` and `alpha` are validated for the whole family before dispatch, so they must be present and valid here too.",
            "constraints": {
              "sample": "non-empty list of finite numbers, at least two of them",
              "estimates": "non-empty list of finite numbers",
              "alpha": "strictly between 0 and 1"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `samplingMean`, `samplingStandardDeviation` (the sample standard deviation across replications, n-1 denominator) and `replications`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "sample or estimates is missing, empty, or contains a non-finite number — both are parsed for every topic in the family, whether or not the topic uses them",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sample holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "alpha is not strictly between zero and one",
            "behaviour": "throws RangeError"
          },
          {
            "when": "estimates holds fewer than two values",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n + m)",
          "space": "O(n + m)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F08-A02.json",
        "call": "samplingDistributions({\"sample\":[2,3,4,3,4],\"estimates\":[3,3.1,3.2,3.3,3.4],\"populationMean\":3.2,\"alpha\":0.05,\"mseBenchmark\":0.1,\"nullMean\":3,\"alternativeMean\":3.5,\"practicalThreshold\":0.1,\"comparisons\":5})",
        "args": [
          {
            "value": {
              "sample": [
                2,
                3,
                4,
                3,
                4
              ],
              "estimates": [
                3,
                3.1,
                3.2,
                3.3,
                3.4
              ],
              "populationMean": 3.2,
              "alpha": 0.05,
              "mseBenchmark": 0.1,
              "nullMean": 3,
              "alternativeMean": 3.5,
              "practicalThreshold": 0.1,
              "comparisons": 5
            },
            "elided": null
          }
        ],
        "output": {
          "samplingMean": 3.2,
          "samplingStandardDeviation": 0.1581138830084189
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: samplingMean, samplingStandardDeviation"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a02/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a02/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a02/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a02/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a02/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a02/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F08-A02",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Sampling Distributions\"]\n    D --> E[\"Formula: distribution of θ̂ across repeated samples\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Product and Process Comparisons",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc1.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Confidence Intervals",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc14.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/sampling-estimation-and-statistical-inference/sampling-distributions/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/sampling-estimation-and-statistical-inference/sampling-distributions/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F08-A03",
      "name": "Estimator Bias, Consistency, Efficiency, and Robustness",
      "headline": null,
      "slug": "estimator-bias-consistency-efficiency-and-robustness",
      "path": "foundations/sampling-estimation-and-statistical-inference/estimator-bias-consistency-efficiency-and-robustness",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F08",
        "family": "Sampling, Estimation, and Statistical Inference",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/sampling-estimation-and-statistical-inference/estimator-bias-consistency-efficiency-and-robustness",
        "entry": "estimatorBiasConsistencyEfficiencyAndRobustness",
        "params": [
          "input"
        ],
        "exports": [
          "estimatorBiasConsistencyEfficiencyAndRobustness"
        ],
        "archetype": "record-transform",
        "signature": "estimatorBiasConsistencyEfficiencyAndRobustness(input)"
      },
      "api": {
        "summary": "Scores an estimator against a known truth: the average error of the replicated `estimates`, their mean squared error, a robust median estimate, and whether the mean squared error clears `mseBenchmark`.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record. `estimates` holds one value per replication, `populationMean` is the truth they are scored against, and `mseBenchmark` is the mean squared error a competing estimator achieves. `sample` and `alpha` are validated for the whole family before dispatch.",
            "constraints": {
              "sample": "non-empty list of finite numbers, at least two of them",
              "estimates": "non-empty list of finite numbers",
              "alpha": "strictly between 0 and 1"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `bias` (mean estimate minus `populationMean`), `mse`, `robustMedianEstimate` (the median of the estimates) and `efficient` (true when `mse` is at or below `mseBenchmark`)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "sample or estimates is missing, empty, or contains a non-finite number — both are parsed for every topic in the family, whether or not the topic uses them",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sample holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "alpha is not strictly between zero and one",
            "behaviour": "throws RangeError"
          },
          {
            "when": "estimates holds fewer than two values",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n + m log m)",
          "space": "O(n + m)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F08-A03.json",
        "call": "estimatorBiasConsistencyEfficiencyAndRobustness({\"sample\":[2,3,4,3,4],\"estimates\":[3,3.1,3.2,3.3,3.4],\"populationMean\":3.2,\"alpha\":0.05,\"mseBenchmark\":0.1,\"nullMean\":3,\"alternativeMean\":3.5,\"practicalThreshold\":0.1,\"comparisons\":5})",
        "args": [
          {
            "value": {
              "sample": [
                2,
                3,
                4,
                3,
                4
              ],
              "estimates": [
                3,
                3.1,
                3.2,
                3.3,
                3.4
              ],
              "populationMean": 3.2,
              "alpha": 0.05,
              "mseBenchmark": 0.1,
              "nullMean": 3,
              "alternativeMean": 3.5,
              "practicalThreshold": 0.1,
              "comparisons": 5
            },
            "elided": null
          }
        ],
        "output": {
          "bias": 0,
          "mse": 0.019999999999999983
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: bias, mse"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a03/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a03/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a03/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a03/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a03/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a03/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F08-A03",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Estimator Bias, Consistency, Efficiency, and Robustness\"]\n    D --> E[\"Formula: Bias(θ̂)=E[θ̂]−θ; MSE=Var(θ̂)+Bias²\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Product and Process Comparisons",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc1.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Confidence Intervals",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc14.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/sampling-estimation-and-statistical-inference/estimator-bias-consistency-efficiency-and-robustness/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/sampling-estimation-and-statistical-inference/estimator-bias-consistency-efficiency-and-robustness/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F08-A04",
      "name": "Law of Large Numbers",
      "headline": null,
      "slug": "law-of-large-numbers",
      "path": "foundations/sampling-estimation-and-statistical-inference/law-of-large-numbers",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F08",
        "family": "Sampling, Estimation, and Statistical Inference",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/sampling-estimation-and-statistical-inference/law-of-large-numbers",
        "entry": "lawOfLargeNumbers",
        "params": [
          "input"
        ],
        "exports": [
          "lawOfLargeNumbers"
        ],
        "archetype": "record-transform",
        "signature": "lawOfLargeNumbers(input)"
      },
      "api": {
        "summary": "Walks the running mean of `input.sample` one observation at a time and reports how far it has drifted from `input.populationMean` by the end.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record. `sample` is the observation stream in the order it arrives, and `populationMean` is the value the running mean should be converging on. `estimates` and `alpha` are validated for the whole family before dispatch.",
            "constraints": {
              "sample": "non-empty list of finite numbers, at least two of them",
              "estimates": "non-empty list of finite numbers",
              "alpha": "strictly between 0 and 1"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `cumulativeMeans` (one running mean per observation), `finalError` (absolute gap between the last running mean and `populationMean`) and `movesTowardTarget` (true when the final gap is no wider than the gap after the first observation)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "sample or estimates is missing, empty, or contains a non-finite number — both are parsed for every topic in the family, whether or not the topic uses them",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sample holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "alpha is not strictly between zero and one",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n^2 + m)",
          "space": "O(n + m)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F08-A04.json",
        "call": "lawOfLargeNumbers({\"sample\":[2,3,4,3,4],\"estimates\":[3,3.1,3.2,3.3,3.4],\"populationMean\":3.2,\"alpha\":0.05,\"mseBenchmark\":0.1,\"nullMean\":3,\"alternativeMean\":3.5,\"practicalThreshold\":0.1,\"comparisons\":5})",
        "args": [
          {
            "value": {
              "sample": [
                2,
                3,
                4,
                3,
                4
              ],
              "estimates": [
                3,
                3.1,
                3.2,
                3.3,
                3.4
              ],
              "populationMean": 3.2,
              "alpha": 0.05,
              "mseBenchmark": 0.1,
              "nullMean": 3,
              "alternativeMean": 3.5,
              "practicalThreshold": 0.1,
              "comparisons": 5
            },
            "elided": null
          }
        ],
        "output": {
          "cumulativeMeans": [
            2,
            2.5,
            3,
            3,
            3.2
          ],
          "finalError": 0
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: cumulativeMeans, finalError"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a04/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a04/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a04/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a04/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a04/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a04/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F08-A04",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Law of Large Numbers\"]\n    D --> E[\"Formula: x̄n=(1/n)Σᵢ≤n Xᵢ → E[X]\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Product and Process Comparisons",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc1.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Confidence Intervals",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc14.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/sampling-estimation-and-statistical-inference/law-of-large-numbers/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/sampling-estimation-and-statistical-inference/law-of-large-numbers/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F08-A05",
      "name": "Central Limit Theorem",
      "headline": null,
      "slug": "central-limit-theorem",
      "path": "foundations/sampling-estimation-and-statistical-inference/central-limit-theorem",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F08",
        "family": "Sampling, Estimation, and Statistical Inference",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/sampling-estimation-and-statistical-inference/central-limit-theorem",
        "entry": "centralLimitTheorem",
        "params": [
          "input"
        ],
        "exports": [
          "centralLimitTheorem"
        ],
        "archetype": "record-transform",
        "signature": "centralLimitTheorem(input)"
      },
      "api": {
        "summary": "Standardises the replicated estimates in `input.estimates` by subtracting `populationMean` and dividing by their spread, then checks how close the standardised values sit to zero.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record. `estimates` holds one sample mean per replication and `populationMean` is the value they are centred on. `sample` and `alpha` are validated for the whole family before dispatch.",
            "constraints": {
              "sample": "non-empty list of finite numbers, at least two of them",
              "estimates": "non-empty list of finite numbers",
              "alpha": "strictly between 0 and 1"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `standardizedMeans` (one per replication), `center` (their mean) and `approximatelyCentered` (true when `center` is within 0.5 of zero)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "sample or estimates is missing, empty, or contains a non-finite number — both are parsed for every topic in the family, whether or not the topic uses them",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sample holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "alpha is not strictly between zero and one",
            "behaviour": "throws RangeError"
          },
          {
            "when": "estimates holds fewer than two values",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n + m)",
          "space": "O(n + m)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F08-A05.json",
        "call": "centralLimitTheorem({\"sample\":[2,3,4,3,4],\"estimates\":[3,3.1,3.2,3.3,3.4],\"populationMean\":3.2,\"alpha\":0.05,\"mseBenchmark\":0.1,\"nullMean\":3,\"alternativeMean\":3.5,\"practicalThreshold\":0.1,\"comparisons\":5})",
        "args": [
          {
            "value": {
              "sample": [
                2,
                3,
                4,
                3,
                4
              ],
              "estimates": [
                3,
                3.1,
                3.2,
                3.3,
                3.4
              ],
              "populationMean": 3.2,
              "alpha": 0.05,
              "mseBenchmark": 0.1,
              "nullMean": 3,
              "alternativeMean": 3.5,
              "practicalThreshold": 0.1,
              "comparisons": 5
            },
            "elided": null
          }
        ],
        "output": {
          "standardizedMeans": [
            -1.2649110640673535,
            -0.6324555320336768,
            0,
            0.6324555320336739,
            1.2649110640673507
          ],
          "center": -1.1546319456101628e-15
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: standardizedMeans, center"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a05/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a05/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a05/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a05/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a05/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a05/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F08-A05",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Central Limit Theorem\"]\n    D --> E[\"Formula: (x̄−μ)/(σ/√n) ⇒ N(0,1)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Product and Process Comparisons",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc1.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Confidence Intervals",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc14.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/sampling-estimation-and-statistical-inference/central-limit-theorem/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/sampling-estimation-and-statistical-inference/central-limit-theorem/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F08-A06",
      "name": "Standard Error",
      "headline": null,
      "slug": "standard-error",
      "path": "foundations/sampling-estimation-and-statistical-inference/standard-error",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F08",
        "family": "Sampling, Estimation, and Statistical Inference",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/sampling-estimation-and-statistical-inference/standard-error",
        "entry": "standardError",
        "params": [
          "input"
        ],
        "exports": [
          "standardError"
        ],
        "archetype": "record-transform",
        "signature": "standardError(input)"
      },
      "api": {
        "summary": "Reports the standard error of the mean for `input.sample` — its sample standard deviation divided by the square root of the observation count.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record whose `sample` holds the observed data. `estimates` and `alpha` are validated for the whole family before dispatch, so they must be present and valid here too.",
            "constraints": {
              "sample": "non-empty list of finite numbers, at least two of them",
              "estimates": "non-empty list of finite numbers",
              "alpha": "strictly between 0 and 1"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `standardError`, `sampleSize` and `sampleStandardDeviation` (n-1 denominator)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "sample or estimates is missing, empty, or contains a non-finite number — both are parsed for every topic in the family, whether or not the topic uses them",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sample holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "alpha is not strictly between zero and one",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n + m)",
          "space": "O(n + m)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F08-A06.json",
        "call": "standardError({\"sample\":[2,3,4,3,4],\"estimates\":[3,3.1,3.2,3.3,3.4],\"populationMean\":3.2,\"alpha\":0.05,\"mseBenchmark\":0.1,\"nullMean\":3,\"alternativeMean\":3.5,\"practicalThreshold\":0.1,\"comparisons\":5})",
        "args": [
          {
            "value": {
              "sample": [
                2,
                3,
                4,
                3,
                4
              ],
              "estimates": [
                3,
                3.1,
                3.2,
                3.3,
                3.4
              ],
              "populationMean": 3.2,
              "alpha": 0.05,
              "mseBenchmark": 0.1,
              "nullMean": 3,
              "alternativeMean": 3.5,
              "practicalThreshold": 0.1,
              "comparisons": 5
            },
            "elided": null
          }
        ],
        "output": {
          "standardError": 0.3741657386773941,
          "sampleSize": 5
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: standardError, sampleSize"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a06/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a06/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a06/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a06/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a06/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a06/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F08-A06",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Standard Error\"]\n    D --> E[\"Formula: SE(x̄)=s/√n\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Product and Process Comparisons",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc1.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Confidence Intervals",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc14.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/sampling-estimation-and-statistical-inference/standard-error/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/sampling-estimation-and-statistical-inference/standard-error/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F08-A07",
      "name": "Confidence Intervals and Coverage",
      "headline": null,
      "slug": "confidence-intervals-and-coverage",
      "path": "foundations/sampling-estimation-and-statistical-inference/confidence-intervals-and-coverage",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F08",
        "family": "Sampling, Estimation, and Statistical Inference",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/sampling-estimation-and-statistical-inference/confidence-intervals-and-coverage",
        "entry": "confidenceIntervalsAndCoverage",
        "params": [
          "input"
        ],
        "exports": [
          "confidenceIntervalsAndCoverage"
        ],
        "archetype": "record-transform",
        "signature": "confidenceIntervalsAndCoverage(input)"
      },
      "api": {
        "summary": "Builds a two-sided interval around the mean of `input.sample` and reports whether `populationMean` falls inside it. The half-width always uses the fixed normal critical value 1.959963984540054; `alpha` is reported back but does not change the multiplier.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record. `sample` is the observed data, `populationMean` is the reference value coverage is checked against, and `alpha` sets the reported confidence level. `estimates` is validated for the whole family before dispatch.",
            "constraints": {
              "sample": "non-empty list of finite numbers, at least two of them",
              "estimates": "non-empty list of finite numbers",
              "alpha": "strictly between 0 and 1"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `lower` and `upper` (the interval bounds), `confidenceLevel` (1 minus `alpha`) and `containsReference` (true when `populationMean` lies between the bounds)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "sample or estimates is missing, empty, or contains a non-finite number — both are parsed for every topic in the family, whether or not the topic uses them",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sample holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "alpha is not strictly between zero and one",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n + m)",
          "space": "O(n + m)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F08-A07.json",
        "call": "confidenceIntervalsAndCoverage({\"sample\":[2,3,4,3,4],\"estimates\":[3,3.1,3.2,3.3,3.4],\"populationMean\":3.2,\"alpha\":0.05,\"mseBenchmark\":0.1,\"nullMean\":3,\"alternativeMean\":3.5,\"practicalThreshold\":0.1,\"comparisons\":5})",
        "args": [
          {
            "value": {
              "sample": [
                2,
                3,
                4,
                3,
                4
              ],
              "estimates": [
                3,
                3.1,
                3.2,
                3.3,
                3.4
              ],
              "populationMean": 3.2,
              "alpha": 0.05,
              "mseBenchmark": 0.1,
              "nullMean": 3,
              "alternativeMean": 3.5,
              "practicalThreshold": 0.1,
              "comparisons": 5
            },
            "elided": null
          }
        ],
        "output": {
          "lower": 2.4666486279434823,
          "upper": 3.933351372056518
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: lower, upper"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a07/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a07/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a07/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a07/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a07/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a07/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F08-A07",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Confidence Intervals and Coverage\"]\n    D --> E[\"Formula: x̄±z(1−α/2)·SE in this known-normal critical-value teaching convention\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Product and Process Comparisons",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc1.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Confidence Intervals",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc14.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/sampling-estimation-and-statistical-inference/confidence-intervals-and-coverage/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/sampling-estimation-and-statistical-inference/confidence-intervals-and-coverage/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F08-A08",
      "name": "Null and Alternative Hypotheses",
      "headline": null,
      "slug": "null-and-alternative-hypotheses",
      "path": "foundations/sampling-estimation-and-statistical-inference/null-and-alternative-hypotheses",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F08",
        "family": "Sampling, Estimation, and Statistical Inference",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/sampling-estimation-and-statistical-inference/null-and-alternative-hypotheses",
        "entry": "nullAndAlternativeHypotheses",
        "params": [
          "input"
        ],
        "exports": [
          "nullAndAlternativeHypotheses"
        ],
        "archetype": "record-transform",
        "signature": "nullAndAlternativeHypotheses(input)"
      },
      "api": {
        "summary": "States a two-sided test of the mean of `input.sample` against `input.nullMean`, and returns the z statistic with the reject-or-not decision taken at the fixed critical value 1.959963984540054.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record. `sample` is the observed data and `nullMean` is the value the null hypothesis asserts. `estimates` and `alpha` are validated for the whole family before dispatch.",
            "constraints": {
              "sample": "non-empty list of finite numbers, at least two of them",
              "estimates": "non-empty list of finite numbers",
              "alpha": "strictly between 0 and 1"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `null` (echoes `nullMean`), `alternative` (the written two-sided alternative), `zStatistic` (sample mean minus `nullMean`, over the standard error) and `reject` (true when the statistic exceeds the critical value in absolute size)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "sample or estimates is missing, empty, or contains a non-finite number — both are parsed for every topic in the family, whether or not the topic uses them",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sample holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "alpha is not strictly between zero and one",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n + m)",
          "space": "O(n + m)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F08-A08.json",
        "call": "nullAndAlternativeHypotheses({\"sample\":[2,3,4,3,4],\"estimates\":[3,3.1,3.2,3.3,3.4],\"populationMean\":3.2,\"alpha\":0.05,\"mseBenchmark\":0.1,\"nullMean\":3,\"alternativeMean\":3.5,\"practicalThreshold\":0.1,\"comparisons\":5})",
        "args": [
          {
            "value": {
              "sample": [
                2,
                3,
                4,
                3,
                4
              ],
              "estimates": [
                3,
                3.1,
                3.2,
                3.3,
                3.4
              ],
              "populationMean": 3.2,
              "alpha": 0.05,
              "mseBenchmark": 0.1,
              "nullMean": 3,
              "alternativeMean": 3.5,
              "practicalThreshold": 0.1,
              "comparisons": 5
            },
            "elided": null
          }
        ],
        "output": {
          "null": 3,
          "alternative": "mean != 3"
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: null, alternative"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a08/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a08/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a08/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a08/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a08/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a08/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F08-A08",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Null and Alternative Hypotheses\"]\n    D --> E[\"Formula: H₀:μ=μ₀; H₁:μ≠μ₀; z=(x̄−μ₀)/SE\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Product and Process Comparisons",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc1.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Confidence Intervals",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc14.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/sampling-estimation-and-statistical-inference/null-and-alternative-hypotheses/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/sampling-estimation-and-statistical-inference/null-and-alternative-hypotheses/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F08-A09",
      "name": "P-Values, Significance, Type I/II Errors, and Power",
      "headline": null,
      "slug": "p-values-significance-type-i-ii-errors-and-power",
      "path": "foundations/sampling-estimation-and-statistical-inference/p-values-significance-type-i-ii-errors-and-power",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F08",
        "family": "Sampling, Estimation, and Statistical Inference",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/sampling-estimation-and-statistical-inference/p-values-significance-type-i-ii-errors-and-power",
        "entry": "pValuesSignificanceTypeIIiErrorsAndPower",
        "params": [
          "input"
        ],
        "exports": [
          "pValuesSignificanceTypeIIiErrorsAndPower"
        ],
        "archetype": "record-transform",
        "signature": "pValuesSignificanceTypeIIiErrorsAndPower(input)"
      },
      "api": {
        "summary": "Turns the two-sided z statistic for `input.sample` against `input.nullMean` into a p-value, compares it with `alpha`, and approximates the test's power at `input.alternativeMean`.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record. `sample` is the observed data, `nullMean` is the value under the null, `alternativeMean` is the value power is evaluated at, and `alpha` is the type I error rate. `estimates` is validated for the whole family before dispatch.",
            "constraints": {
              "sample": "non-empty list of finite numbers, at least two of them",
              "estimates": "non-empty list of finite numbers",
              "alpha": "strictly between 0 and 1"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `pValue` (two-sided, from a normal approximation), `significant` (true when `pValue` is below `alpha`), `typeIErrorRate` (echoes `alpha`) and `powerApproximation` (normal-approximation power against `alternativeMean`)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "sample or estimates is missing, empty, or contains a non-finite number — both are parsed for every topic in the family, whether or not the topic uses them",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sample holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "alpha is not strictly between zero and one",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n + m)",
          "space": "O(n + m)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F08-A09.json",
        "call": "pValuesSignificanceTypeIIiErrorsAndPower({\"sample\":[2,3,4,3,4],\"estimates\":[3,3.1,3.2,3.3,3.4],\"populationMean\":3.2,\"alpha\":0.05,\"mseBenchmark\":0.1,\"nullMean\":3,\"alternativeMean\":3.5,\"practicalThreshold\":0.1,\"comparisons\":5})",
        "args": [
          {
            "value": {
              "sample": [
                2,
                3,
                4,
                3,
                4
              ],
              "estimates": [
                3,
                3.1,
                3.2,
                3.3,
                3.4
              ],
              "populationMean": 3.2,
              "alpha": 0.05,
              "mseBenchmark": 0.1,
              "nullMean": 3,
              "alternativeMean": 3.5,
              "practicalThreshold": 0.1,
              "comparisons": 5
            },
            "elided": null
          }
        ],
        "output": {
          "pValue": 0.5929800980174265,
          "significant": false
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: pValue, significant"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a09/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a09/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a09/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a09/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a09/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a09/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F08-A09",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply P-Values, Significance, Type I/II Errors, and Power\"]\n    D --> E[\"Formula: p=2[1−Φ(|z|)]; reject when p<α\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Product and Process Comparisons",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc1.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Confidence Intervals",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc14.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/sampling-estimation-and-statistical-inference/p-values-significance-type-i-ii-errors-and-power/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/sampling-estimation-and-statistical-inference/p-values-significance-type-i-ii-errors-and-power/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F08-A10",
      "name": "Effect Size, Practical Significance, and Multiple Comparisons",
      "headline": null,
      "slug": "effect-size-practical-significance-and-multiple-comparisons",
      "path": "foundations/sampling-estimation-and-statistical-inference/effect-size-practical-significance-and-multiple-comparisons",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F08",
        "family": "Sampling, Estimation, and Statistical Inference",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/sampling-estimation-and-statistical-inference/effect-size-practical-significance-and-multiple-comparisons",
        "entry": "effectSizePracticalSignificanceAndMultipleComparisons",
        "params": [
          "input"
        ],
        "exports": [
          "effectSizePracticalSignificanceAndMultipleComparisons"
        ],
        "archetype": "record-transform",
        "signature": "effectSizePracticalSignificanceAndMultipleComparisons(input)"
      },
      "api": {
        "summary": "Reports a standardised effect size for the gap between the mean of `input.sample` and `input.nullMean`, tests that gap against a practical threshold, and splits `alpha` across `input.comparisons` tests Bonferroni-style.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record. `sample` is the observed data, `nullMean` is the reference value, `practicalThreshold` is the smallest gap that matters in the caller's units, `comparisons` is how many tests the error budget is being split across, and `alpha` is that budget. `estimates` is validated for the whole family before dispatch.",
            "constraints": {
              "sample": "non-empty list of finite numbers, at least two of them",
              "estimates": "non-empty list of finite numbers",
              "alpha": "strictly between 0 and 1",
              "comparisons": "integer, 1 or greater"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `standardizedEffect` (the gap in sample standard deviations), `practicallySignificant` (true when the raw gap reaches `practicalThreshold`), `bonferroniAlpha` (`alpha` divided by `comparisons`) and `comparisons`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "sample or estimates is missing, empty, or contains a non-finite number — both are parsed for every topic in the family, whether or not the topic uses them",
            "behaviour": "throws RangeError"
          },
          {
            "when": "sample holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "alpha is not strictly between zero and one",
            "behaviour": "throws RangeError"
          },
          {
            "when": "comparisons is not an integer of at least one",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n + m)",
          "space": "O(n + m)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F08-A10.json",
        "call": "effectSizePracticalSignificanceAndMultipleComparisons({\"sample\":[2,3,4,3,4],\"estimates\":[3,3.1,3.2,3.3,3.4],\"populationMean\":3.2,\"alpha\":0.05,\"mseBenchmark\":0.1,\"nullMean\":3,\"alternativeMean\":3.5,\"practicalThreshold\":0.1,\"comparisons\":5})",
        "args": [
          {
            "value": {
              "sample": [
                2,
                3,
                4,
                3,
                4
              ],
              "estimates": [
                3,
                3.1,
                3.2,
                3.3,
                3.4
              ],
              "populationMean": 3.2,
              "alpha": 0.05,
              "mseBenchmark": 0.1,
              "nullMean": 3,
              "alternativeMean": 3.5,
              "practicalThreshold": 0.1,
              "comparisons": 5
            },
            "elided": null
          }
        ],
        "output": {
          "standardizedEffect": 0.23904572186687895,
          "practicallySignificant": true
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: standardizedEffect, practicallySignificant"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a10/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a10/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a10/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a10/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a10/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f08-a10/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F08-A10",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Effect Size, Practical Significance, and Multiple Comparisons\"]\n    D --> E[\"Formula: standardized effect=(x̄−μ₀)/s; Bonferroni α*=α/m\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Product and Process Comparisons",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc1.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Confidence Intervals",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/prc/section1/prc14.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/sampling-estimation-and-statistical-inference/effect-size-practical-significance-and-multiple-comparisons/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/sampling-estimation-and-statistical-inference/effect-size-practical-significance-and-multiple-comparisons/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F09-A01",
      "name": "Scatter Plots, Association, and Nonlinear Patterns",
      "headline": null,
      "slug": "scatter-plots-association-and-nonlinear-patterns",
      "path": "foundations/dependence-regression-and-model-foundations/scatter-plots-association-and-nonlinear-patterns",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F09",
        "family": "Dependence, Regression, and Model Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dependence-regression-and-model-foundations/scatter-plots-association-and-nonlinear-patterns",
        "entry": "scatterPlotsAssociationAndNonlinearPatterns",
        "params": [
          "input"
        ],
        "exports": [
          "scatterPlotsAssociationAndNonlinearPatterns"
        ],
        "archetype": "record-transform",
        "signature": "scatterPlotsAssociationAndNonlinearPatterns(input)"
      },
      "api": {
        "summary": "Pairs `input.x` and `input.y` into plottable points and reports the Pearson correlation over them along with its sign.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record holding the two aligned series `x` and `y`, one observation per position.",
            "constraints": {
              "x": "non-empty list of finite numbers, at least two, not all identical",
              "y": "finite numbers, same length as x"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `points` (one `{ x, y }` entry per observation), `pearson` (the correlation) and `monotonicDirection`, which reads `positive` when the correlation is above zero and `negative` otherwise."
        },
        "warmup": null,
        "errors": [
          {
            "when": "x or y is missing, empty, or contains a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x and y have different lengths, or fewer than two observations — the least-squares fit is computed for every topic in the family before the topic branch is taken",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x is constant, which leaves the regression slope undefined",
            "behaviour": "throws RangeError"
          },
          {
            "when": "y is constant, which leaves the correlation undefined",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F09-A01.json",
        "call": "scatterPlotsAssociationAndNonlinearPatterns({\"x\":[1,2,3,4,5,6],\"y\":[2,3,5,4,6,7],\"groups\":[\"A\",\"A\",\"A\",\"B\",\"B\",\"B\"],\"predictX\":7,\"otherPredictor\":[2,4,5,8,9,13]})",
        "args": [
          {
            "value": {
              "x": [
                1,
                2,
                3,
                4,
                5,
                6
              ],
              "y": [
                2,
                3,
                5,
                4,
                6,
                7
              ],
              "groups": [
                "A",
                "A",
                "A",
                "B",
                "B",
                "B"
              ],
              "predictX": 7,
              "otherPredictor": [
                2,
                4,
                5,
                8,
                9,
                13
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "points": [
            {
              "x": 1,
              "y": 2
            },
            {
              "x": 2,
              "y": 3
            },
            {
              "x": 3,
              "y": 5
            }
          ],
          "pearson": 0.9428571428571428
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: points, pearson"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a01/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a01/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a01/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a01/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a01/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a01/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F09-A01",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Scatter Plots, Association, and Nonlinear Patterns\"]\n    D --> E[\"Formula: paired points (xᵢ,yᵢ); Pearson r as one optional overlay\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Linear Least Squares Regression",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/pmd/section1/pmd141.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Correlation",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35c.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dependence-regression-and-model-foundations/scatter-plots-association-and-nonlinear-patterns/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dependence-regression-and-model-foundations/scatter-plots-association-and-nonlinear-patterns/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F09-A02",
      "name": "Sample Covariance Calculation and Interpretation",
      "headline": null,
      "slug": "sample-covariance-calculation-and-interpretation",
      "path": "foundations/dependence-regression-and-model-foundations/sample-covariance-calculation-and-interpretation",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F09",
        "family": "Dependence, Regression, and Model Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dependence-regression-and-model-foundations/sample-covariance-calculation-and-interpretation",
        "entry": "sampleCovarianceCalculationAndInterpretation",
        "params": [
          "input"
        ],
        "exports": [
          "sampleCovarianceCalculationAndInterpretation"
        ],
        "archetype": "record-transform",
        "signature": "sampleCovarianceCalculationAndInterpretation(input)"
      },
      "api": {
        "summary": "Computes the sample covariance between `input.x` and `input.y` using the n-1 denominator, and reports which way the two series move together.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record holding the two aligned series `x` and `y`, one observation per position.",
            "constraints": {
              "x": "non-empty list of finite numbers, at least two, not all identical",
              "y": "finite numbers, same length as x"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `sampleCovariance` and `direction`, which reads `positive` when the covariance is above zero and `negative` otherwise, exactly zero included."
        },
        "warmup": null,
        "errors": [
          {
            "when": "x or y is missing, empty, or contains a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x and y have different lengths, or fewer than two observations — the least-squares fit is computed for every topic in the family before the topic branch is taken",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x is constant, which leaves the regression slope undefined",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F09-A02.json",
        "call": "sampleCovarianceCalculationAndInterpretation({\"x\":[1,2,3,4,5,6],\"y\":[2,3,5,4,6,7],\"groups\":[\"A\",\"A\",\"A\",\"B\",\"B\",\"B\"],\"predictX\":7,\"otherPredictor\":[2,4,5,8,9,13]})",
        "args": [
          {
            "value": {
              "x": [
                1,
                2,
                3,
                4,
                5,
                6
              ],
              "y": [
                2,
                3,
                5,
                4,
                6,
                7
              ],
              "groups": [
                "A",
                "A",
                "A",
                "B",
                "B",
                "B"
              ],
              "predictX": 7,
              "otherPredictor": [
                2,
                4,
                5,
                8,
                9,
                13
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "sampleCovariance": 3.3,
          "direction": "positive"
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: sampleCovariance, direction"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a02/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a02/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a02/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a02/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a02/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a02/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F09-A02",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Sample Covariance Calculation and Interpretation\"]\n    D --> E[\"Formula: sxy=Σ(xᵢ−x̄)(yᵢ−ȳ)/(n−1)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Linear Least Squares Regression",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/pmd/section1/pmd141.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Correlation",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35c.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dependence-regression-and-model-foundations/sample-covariance-calculation-and-interpretation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dependence-regression-and-model-foundations/sample-covariance-calculation-and-interpretation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F09-A03",
      "name": "Pearson Correlation Calculation and Interpretation",
      "headline": null,
      "slug": "pearson-correlation-calculation-and-interpretation",
      "path": "foundations/dependence-regression-and-model-foundations/pearson-correlation-calculation-and-interpretation",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F09",
        "family": "Dependence, Regression, and Model Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dependence-regression-and-model-foundations/pearson-correlation-calculation-and-interpretation",
        "entry": "pearsonCorrelationCalculationAndInterpretation",
        "params": [
          "input"
        ],
        "exports": [
          "pearsonCorrelationCalculationAndInterpretation"
        ],
        "archetype": "record-transform",
        "signature": "pearsonCorrelationCalculationAndInterpretation(input)"
      },
      "api": {
        "summary": "Computes the Pearson correlation between `input.x` and `input.y` and its absolute value as a sign-free strength score.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record holding the two aligned series `x` and `y`, one observation per position.",
            "constraints": {
              "x": "non-empty list of finite numbers, at least two, not all identical",
              "y": "finite numbers, same length as x"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `pearsonCorrelation` (between -1 and 1) and `strength` (its absolute value)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "x or y is missing, empty, or contains a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x and y have different lengths, or fewer than two observations — the least-squares fit is computed for every topic in the family before the topic branch is taken",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x is constant, which leaves the regression slope undefined",
            "behaviour": "throws RangeError"
          },
          {
            "when": "y is constant, which leaves the correlation undefined",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F09-A03.json",
        "call": "pearsonCorrelationCalculationAndInterpretation({\"x\":[1,2,3,4,5,6],\"y\":[2,3,5,4,6,7],\"groups\":[\"A\",\"A\",\"A\",\"B\",\"B\",\"B\"],\"predictX\":7,\"otherPredictor\":[2,4,5,8,9,13]})",
        "args": [
          {
            "value": {
              "x": [
                1,
                2,
                3,
                4,
                5,
                6
              ],
              "y": [
                2,
                3,
                5,
                4,
                6,
                7
              ],
              "groups": [
                "A",
                "A",
                "A",
                "B",
                "B",
                "B"
              ],
              "predictX": 7,
              "otherPredictor": [
                2,
                4,
                5,
                8,
                9,
                13
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "pearsonCorrelation": 0.9428571428571428,
          "strength": 0.9428571428571428
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: pearsonCorrelation, strength"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a03/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a03/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a03/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a03/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a03/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a03/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F09-A03",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Pearson Correlation Calculation and Interpretation\"]\n    D --> E[\"Formula: r=sxy/(sx·sy)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Linear Least Squares Regression",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/pmd/section1/pmd141.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Correlation",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35c.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dependence-regression-and-model-foundations/pearson-correlation-calculation-and-interpretation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dependence-regression-and-model-foundations/pearson-correlation-calculation-and-interpretation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F09-A04",
      "name": "Spearman Rank Correlation and Kendall Tau",
      "headline": null,
      "slug": "spearman-rank-correlation-and-kendall-tau",
      "path": "foundations/dependence-regression-and-model-foundations/spearman-rank-correlation-and-kendall-tau",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F09",
        "family": "Dependence, Regression, and Model Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dependence-regression-and-model-foundations/spearman-rank-correlation-and-kendall-tau",
        "entry": "spearmanRankCorrelationAndKendallTau",
        "params": [
          "input"
        ],
        "exports": [
          "spearmanRankCorrelationAndKendallTau"
        ],
        "archetype": "record-transform",
        "signature": "spearmanRankCorrelationAndKendallTau(input)"
      },
      "api": {
        "summary": "Replaces `input.x` and `input.y` with their ranks, averaging ranks across ties, then reports the Spearman correlation of those ranks and Kendall's tau-a from the concordant and discordant pair counts.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record holding the two aligned series `x` and `y`, one observation per position.",
            "constraints": {
              "x": "non-empty list of finite numbers, at least two, not all identical",
              "y": "finite numbers, same length as x"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `spearman` (Pearson correlation of the two rank vectors), `kendallTauA` (concordant minus discordant pairs over the total pair count, with no tie correction) and `tiesPresent` (true when either series repeats a value)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "x or y is missing, empty, or contains a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x and y have different lengths, or fewer than two observations — the least-squares fit is computed for every topic in the family before the topic branch is taken",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x is constant, which leaves the regression slope undefined",
            "behaviour": "throws RangeError"
          },
          {
            "when": "either rank vector is constant, which leaves the Spearman correlation undefined",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n^2)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F09-A04.json",
        "call": "spearmanRankCorrelationAndKendallTau({\"x\":[1,2,3,4,5,6],\"y\":[2,3,5,4,6,7],\"groups\":[\"A\",\"A\",\"A\",\"B\",\"B\",\"B\"],\"predictX\":7,\"otherPredictor\":[2,4,5,8,9,13]})",
        "args": [
          {
            "value": {
              "x": [
                1,
                2,
                3,
                4,
                5,
                6
              ],
              "y": [
                2,
                3,
                5,
                4,
                6,
                7
              ],
              "groups": [
                "A",
                "A",
                "A",
                "B",
                "B",
                "B"
              ],
              "predictX": 7,
              "otherPredictor": [
                2,
                4,
                5,
                8,
                9,
                13
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "spearman": 0.9428571428571428,
          "kendallTauA": 0.8666666666666667
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: spearman, kendallTauA"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a04/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a04/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a04/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a04/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a04/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a04/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F09-A04",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Spearman Rank Correlation and Kendall Tau\"]\n    D --> E[\"Formula: ρs=correlation(rank x,rank y); τa=(C−D)/C(n,2)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Linear Least Squares Regression",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/pmd/section1/pmd141.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Correlation",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35c.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dependence-regression-and-model-foundations/spearman-rank-correlation-and-kendall-tau/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dependence-regression-and-model-foundations/spearman-rank-correlation-and-kendall-tau/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F09-A05",
      "name": "Correlation, Causation, Confounding, and Spurious Relationships",
      "headline": null,
      "slug": "correlation-causation-confounding-and-spurious-relationships",
      "path": "foundations/dependence-regression-and-model-foundations/correlation-causation-confounding-and-spurious-relationships",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F09",
        "family": "Dependence, Regression, and Model Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dependence-regression-and-model-foundations/correlation-causation-confounding-and-spurious-relationships",
        "entry": "correlationCausationConfoundingAndSpuriousRelationships",
        "params": [
          "input"
        ],
        "exports": [
          "correlationCausationConfoundingAndSpuriousRelationships"
        ],
        "archetype": "record-transform",
        "signature": "correlationCausationConfoundingAndSpuriousRelationships(input)"
      },
      "api": {
        "summary": "Contrasts the pooled correlation of `input.x` and `input.y` with the correlation recomputed inside each label in `input.groups`, which is where a confounded or reversed relationship shows itself.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record holding the aligned series `x` and `y` plus `groups`, a parallel list of group labels, one per observation.",
            "constraints": {
              "x": "non-empty list of finite numbers, at least two, not all identical",
              "y": "finite numbers, same length as x"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `rawCorrelation` (over all observations), `withinGroupCorrelations` (a map keyed by group label, whose value is `null` for any group with fewer than three members) and `causalClaimSupported`, which is always `false`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "x or y is missing, empty, or contains a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x and y have different lengths, or fewer than two observations — the least-squares fit is computed for every topic in the family before the topic branch is taken",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x is constant, which leaves the regression slope undefined",
            "behaviour": "throws RangeError"
          },
          {
            "when": "y is constant, or a group with three or more members has a constant x or y within it",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n*g)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F09-A05.json",
        "call": "correlationCausationConfoundingAndSpuriousRelationships({\"x\":[1,2,3,4,5,6],\"y\":[12,11,11,10,20,19],\"groups\":[\"A\",\"A\",\"A\",\"A\",\"B\",\"B\"],\"predictX\":9,\"otherPredictor\":[2,4,5,8,9,13]})",
        "args": [
          {
            "value": {
              "x": [
                1,
                2,
                3,
                4,
                5,
                6
              ],
              "y": [
                12,
                11,
                11,
                10,
                20,
                19
              ],
              "groups": [
                "A",
                "A",
                "A",
                "A",
                "B",
                "B"
              ],
              "predictX": 9,
              "otherPredictor": [
                2,
                4,
                5,
                8,
                9,
                13
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "rawCorrelation": 0.7789621985578676,
          "withinGroupCorrelations": {
            "A": -0.9486832980505138,
            "B": -0.9486832980505138
          }
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: rawCorrelation, withinGroupCorrelations"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a05/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a05/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a05/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a05/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a05/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a05/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F09-A05",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Correlation, Causation, Confounding, and Spurious Relationships\"]\n    D --> E[\"Formula: raw association versus within-group association; causalClaimSupported=false\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Linear Least Squares Regression",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/pmd/section1/pmd141.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Correlation",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35c.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dependence-regression-and-model-foundations/correlation-causation-confounding-and-spurious-relationships/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dependence-regression-and-model-foundations/correlation-causation-confounding-and-spurious-relationships/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F09-A06",
      "name": "Simple Ordinary Least Squares Regression",
      "headline": null,
      "slug": "simple-ordinary-least-squares-regression",
      "path": "foundations/dependence-regression-and-model-foundations/simple-ordinary-least-squares-regression",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F09",
        "family": "Dependence, Regression, and Model Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dependence-regression-and-model-foundations/simple-ordinary-least-squares-regression",
        "entry": "simpleOrdinaryLeastSquaresRegression",
        "params": [
          "input"
        ],
        "exports": [
          "simpleOrdinaryLeastSquaresRegression"
        ],
        "archetype": "record-transform",
        "signature": "simpleOrdinaryLeastSquaresRegression(input)"
      },
      "api": {
        "summary": "Fits a single-predictor ordinary least squares line of `input.y` on `input.x` and returns the fitted coefficients with the in-sample fitted values.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record holding the predictor series `x` and the outcome series `y`, aligned position by position.",
            "constraints": {
              "x": "non-empty list of finite numbers, at least two, not all identical",
              "y": "finite numbers, same length as x"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `intercept`, `slope` (covariance over the predictor's sample variance) and `predictions` (the fitted value at each observed `x`)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "x or y is missing, empty, or contains a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x and y have different lengths, or fewer than two observations — the least-squares fit is computed for every topic in the family before the topic branch is taken",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x is constant, which leaves the regression slope undefined",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F09-A06.json",
        "call": "simpleOrdinaryLeastSquaresRegression({\"x\":[1,2,3,4,5,6],\"y\":[2,3,5,4,6,7],\"groups\":[\"A\",\"A\",\"A\",\"B\",\"B\",\"B\"],\"predictX\":7,\"otherPredictor\":[2,4,5,8,9,13]})",
        "args": [
          {
            "value": {
              "x": [
                1,
                2,
                3,
                4,
                5,
                6
              ],
              "y": [
                2,
                3,
                5,
                4,
                6,
                7
              ],
              "groups": [
                "A",
                "A",
                "A",
                "B",
                "B",
                "B"
              ],
              "predictX": 7,
              "otherPredictor": [
                2,
                4,
                5,
                8,
                9,
                13
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "intercept": 1.2000000000000002,
          "slope": 0.9428571428571428
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: intercept, slope"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a06/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a06/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a06/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a06/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a06/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a06/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F09-A06",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Simple Ordinary Least Squares Regression\"]\n    D --> E[\"Formula: b1=Σ(x−x̄)(y−ȳ)/Σ(x−x̄)²; b0=ȳ−b1x̄\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Linear Least Squares Regression",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/pmd/section1/pmd141.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Correlation",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35c.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dependence-regression-and-model-foundations/simple-ordinary-least-squares-regression/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dependence-regression-and-model-foundations/simple-ordinary-least-squares-regression/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F09-A07",
      "name": "Intercepts, Slopes, Coefficients, and Predictions",
      "headline": null,
      "slug": "intercepts-slopes-coefficients-and-predictions",
      "path": "foundations/dependence-regression-and-model-foundations/intercepts-slopes-coefficients-and-predictions",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F09",
        "family": "Dependence, Regression, and Model Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dependence-regression-and-model-foundations/intercepts-slopes-coefficients-and-predictions",
        "entry": "interceptsSlopesCoefficientsAndPredictions",
        "params": [
          "input"
        ],
        "exports": [
          "interceptsSlopesCoefficientsAndPredictions"
        ],
        "archetype": "record-transform",
        "signature": "interceptsSlopesCoefficientsAndPredictions(input)"
      },
      "api": {
        "summary": "Fits the least squares line of `input.y` on `input.x` and evaluates it at one new predictor value, `input.predictX`.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record holding the predictor series `x`, the outcome series `y`, and `predictX`, the predictor value to forecast at.",
            "constraints": {
              "x": "non-empty list of finite numbers, at least two, not all identical",
              "y": "finite numbers, same length as x"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `intercept`, `slope`, `prediction` (the fitted line evaluated at `predictX`) and `predictor` (echoes `predictX` as a number)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "x or y is missing, empty, or contains a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x and y have different lengths, or fewer than two observations — the least-squares fit is computed for every topic in the family before the topic branch is taken",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x is constant, which leaves the regression slope undefined",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F09-A07.json",
        "call": "interceptsSlopesCoefficientsAndPredictions({\"x\":[1,2,3,4,5,6],\"y\":[2,3,5,4,6,7],\"groups\":[\"A\",\"A\",\"A\",\"B\",\"B\",\"B\"],\"predictX\":7,\"otherPredictor\":[2,4,5,8,9,13]})",
        "args": [
          {
            "value": {
              "x": [
                1,
                2,
                3,
                4,
                5,
                6
              ],
              "y": [
                2,
                3,
                5,
                4,
                6,
                7
              ],
              "groups": [
                "A",
                "A",
                "A",
                "B",
                "B",
                "B"
              ],
              "predictX": 7,
              "otherPredictor": [
                2,
                4,
                5,
                8,
                9,
                13
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "intercept": 1.2000000000000002,
          "slope": 0.9428571428571428
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: intercept, slope"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a07/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a07/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a07/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a07/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a07/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a07/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F09-A07",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Intercepts, Slopes, Coefficients, and Predictions\"]\n    D --> E[\"Formula: ŷ=b0+b1x\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Linear Least Squares Regression",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/pmd/section1/pmd141.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Correlation",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35c.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dependence-regression-and-model-foundations/intercepts-slopes-coefficients-and-predictions/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dependence-regression-and-model-foundations/intercepts-slopes-coefficients-and-predictions/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F09-A08",
      "name": "Residuals, MAE, MSE, and RMSE",
      "headline": null,
      "slug": "residuals-mae-mse-and-rmse",
      "path": "foundations/dependence-regression-and-model-foundations/residuals-mae-mse-and-rmse",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F09",
        "family": "Dependence, Regression, and Model Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dependence-regression-and-model-foundations/residuals-mae-mse-and-rmse",
        "entry": "residualsMaeMseAndRmse",
        "params": [
          "input"
        ],
        "exports": [
          "residualsMaeMseAndRmse"
        ],
        "archetype": "record-transform",
        "signature": "residualsMaeMseAndRmse(input)"
      },
      "api": {
        "summary": "Returns the least squares residuals of `input.y` on `input.x` together with the three usual summaries of their size.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record holding the predictor series `x` and the outcome series `y`, aligned position by position.",
            "constraints": {
              "x": "non-empty list of finite numbers, at least two, not all identical",
              "y": "finite numbers, same length as x"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `residuals` (observed minus fitted, one per observation), `mae`, `mse` and `rmse`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "x or y is missing, empty, or contains a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x and y have different lengths, or fewer than two observations — the least-squares fit is computed for every topic in the family before the topic branch is taken",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x is constant, which leaves the regression slope undefined",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F09-A08.json",
        "call": "residualsMaeMseAndRmse({\"x\":[1,2,3,4,5,6],\"y\":[2,3,5,4,6,7],\"groups\":[\"A\",\"A\",\"A\",\"B\",\"B\",\"B\"],\"predictX\":7,\"otherPredictor\":[2,4,5,8,9,13]})",
        "args": [
          {
            "value": {
              "x": [
                1,
                2,
                3,
                4,
                5,
                6
              ],
              "y": [
                2,
                3,
                5,
                4,
                6,
                7
              ],
              "groups": [
                "A",
                "A",
                "A",
                "B",
                "B",
                "B"
              ],
              "predictX": 7,
              "otherPredictor": [
                2,
                4,
                5,
                8,
                9,
                13
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "residuals": [
            -0.14285714285714324,
            -0.08571428571428585,
            0.9714285714285715,
            -0.9714285714285715,
            0.08571428571428541,
            0.14285714285714324
          ],
          "mae": 0.40000000000000013
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: residuals, mae"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a08/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a08/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a08/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a08/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a08/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a08/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F09-A08",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Residuals, MAE, MSE, and RMSE\"]\n    D --> E[\"Formula: eᵢ=yᵢ−ŷᵢ; MAE=mean|e|; MSE=mean e²; RMSE=√MSE\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Linear Least Squares Regression",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/pmd/section1/pmd141.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Correlation",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35c.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dependence-regression-and-model-foundations/residuals-mae-mse-and-rmse/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dependence-regression-and-model-foundations/residuals-mae-mse-and-rmse/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F09-A09",
      "name": "R-Squared and Adjusted R-Squared",
      "headline": null,
      "slug": "r-squared-and-adjusted-r-squared",
      "path": "foundations/dependence-regression-and-model-foundations/r-squared-and-adjusted-r-squared",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F09",
        "family": "Dependence, Regression, and Model Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dependence-regression-and-model-foundations/r-squared-and-adjusted-r-squared",
        "entry": "rSquaredAndAdjustedRSquared",
        "params": [
          "input"
        ],
        "exports": [
          "rSquaredAndAdjustedRSquared"
        ],
        "archetype": "record-transform",
        "signature": "rSquaredAndAdjustedRSquared(input)"
      },
      "api": {
        "summary": "Reports the share of the variation in `input.y` that the least squares fit on `input.x` accounts for, and the same figure adjusted for the one estimated slope.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record holding the predictor series `x` and the outcome series `y`, aligned position by position.",
            "constraints": {
              "x": "non-empty list of finite numbers, at least two, not all identical",
              "y": "finite numbers, same length as x"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `rSquared` (one minus residual sum of squares over total sum of squares) and `adjustedRSquared` (the same, penalised with an n-2 denominator)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "x or y is missing, empty, or contains a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x and y have different lengths, or fewer than two observations — the least-squares fit is computed for every topic in the family before the topic branch is taken",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x is constant, which leaves the regression slope undefined",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F09-A09.json",
        "call": "rSquaredAndAdjustedRSquared({\"x\":[1,2,3,4,5,6],\"y\":[2,3,5,4,6,7],\"groups\":[\"A\",\"A\",\"A\",\"B\",\"B\",\"B\"],\"predictX\":7,\"otherPredictor\":[2,4,5,8,9,13]})",
        "args": [
          {
            "value": {
              "x": [
                1,
                2,
                3,
                4,
                5,
                6
              ],
              "y": [
                2,
                3,
                5,
                4,
                6,
                7
              ],
              "groups": [
                "A",
                "A",
                "A",
                "B",
                "B",
                "B"
              ],
              "predictX": 7,
              "otherPredictor": [
                2,
                4,
                5,
                8,
                9,
                13
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "rSquared": 0.8889795918367347,
          "adjustedRSquared": 0.8612244897959184
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: rSquared, adjustedRSquared"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a09/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a09/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a09/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a09/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a09/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a09/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F09-A09",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply R-Squared and Adjusted R-Squared\"]\n    D --> E[\"Formula: R²=1−SSE/SST; adjusted R²=1−(1−R²)(n−1)/(n−p−1)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Linear Least Squares Regression",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/pmd/section1/pmd141.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Correlation",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35c.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dependence-regression-and-model-foundations/r-squared-and-adjusted-r-squared/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dependence-regression-and-model-foundations/r-squared-and-adjusted-r-squared/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F09-A10",
      "name": "Regression Assumptions, Heteroskedasticity, and Multicollinearity",
      "headline": null,
      "slug": "regression-assumptions-heteroskedasticity-and-multicollinearity",
      "path": "foundations/dependence-regression-and-model-foundations/regression-assumptions-heteroskedasticity-and-multicollinearity",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F09",
        "family": "Dependence, Regression, and Model Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/dependence-regression-and-model-foundations/regression-assumptions-heteroskedasticity-and-multicollinearity",
        "entry": "regressionAssumptionsHeteroskedasticityAndMulticollinearity",
        "params": [
          "input"
        ],
        "exports": [
          "regressionAssumptionsHeteroskedasticityAndMulticollinearity"
        ],
        "archetype": "record-transform",
        "signature": "regressionAssumptionsHeteroskedasticityAndMulticollinearity(input)"
      },
      "api": {
        "summary": "Runs three diagnostics on the least squares fit of `input.y` on `input.x`: the mean residual, a correlation between fitted values and absolute residuals standing in for non-constant error variance, and the correlation with `input.otherPredictor` standing in for collinearity.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "One record holding the predictor series `x`, the outcome series `y`, and `otherPredictor`, a second candidate predictor aligned with `x`.",
            "constraints": {
              "x": "non-empty list of finite numbers, at least two, not all identical",
              "y": "finite numbers, same length as x",
              "otherPredictor": "non-empty list of finite numbers, same length as x, not all identical"
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "An object with `residualMean`, `heteroskedasticityProxy` (correlation of fitted values with absolute residuals, or 0 when every absolute residual is identical), `predictorCorrelation` (between `x` and `otherPredictor`), `vifProxy` (one over one minus that correlation squared) and `warnings`, a list naming `heteroskedasticity` when its proxy exceeds 0.5 in absolute size and `multicollinearity` when the predictor correlation exceeds 0.8 in absolute size."
        },
        "warmup": null,
        "errors": [
          {
            "when": "x or y is missing, empty, or contains a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x and y have different lengths, or fewer than two observations — the least-squares fit is computed for every topic in the family before the topic branch is taken",
            "behaviour": "throws RangeError"
          },
          {
            "when": "x is constant, which leaves the regression slope undefined",
            "behaviour": "throws RangeError"
          },
          {
            "when": "otherPredictor is missing, empty, holds a non-finite number, does not align with x, or is constant",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the fitted values are constant, meaning a zero slope, while the absolute residuals still vary, which leaves the heteroskedasticity proxy undefined",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F09-A10.json",
        "call": "regressionAssumptionsHeteroskedasticityAndMulticollinearity({\"x\":[1,2,3,4,5,6],\"y\":[2,3,5,4,6,7],\"groups\":[\"A\",\"A\",\"A\",\"B\",\"B\",\"B\"],\"predictX\":7,\"otherPredictor\":[2,4,5,8,9,13]})",
        "args": [
          {
            "value": {
              "x": [
                1,
                2,
                3,
                4,
                5,
                6
              ],
              "y": [
                2,
                3,
                5,
                4,
                6,
                7
              ],
              "groups": [
                "A",
                "A",
                "A",
                "B",
                "B",
                "B"
              ],
              "predictX": 7,
              "otherPredictor": [
                2,
                4,
                5,
                8,
                9,
                13
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "residualMean": -7.401486830834377e-17,
          "heteroskedasticityProxy": -1.9874588747770088e-16
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: residualMean, heteroskedasticityProxy"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a10/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a10/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a10/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a10/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a10/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f09-a10/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F09-A10",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Regression Assumptions, Heteroskedasticity, and Multicollinearity\"]\n    D --> E[\"Formula: residual pattern proxy; VIF=1/(1−Rj²)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Linear Least Squares Regression",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/pmd/section1/pmd141.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Correlation",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35c.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/dependence-regression-and-model-foundations/regression-assumptions-heteroskedasticity-and-multicollinearity/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/dependence-regression-and-model-foundations/regression-assumptions-heteroskedasticity-and-multicollinearity/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F10-A01",
      "name": "Time Order, Frequency, Regularity, and Financial Calendars",
      "headline": null,
      "slug": "time-order-frequency-regularity-and-financial-calendars",
      "path": "foundations/financial-time-series-foundations/time-order-frequency-regularity-and-financial-calendars",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F10",
        "family": "Financial Time-Series Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-time-series-foundations/time-order-frequency-regularity-and-financial-calendars",
        "entry": "timeOrderFrequencyRegularityAndFinancialCalendars",
        "params": [
          "input"
        ],
        "exports": [
          "timeOrderFrequencyRegularityAndFinancialCalendars"
        ],
        "archetype": "record-transform",
        "signature": "timeOrderFrequencyRegularityAndFinancialCalendars(input)"
      },
      "api": {
        "summary": "Checks whether a timestamped series runs in chronological order and whether its observations are evenly spaced, reporting the common spacing in seconds when there is one.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `timestamps`, a list of parseable date-time strings, and `values`, a non-empty list of finite numbers of the same length. Only the timestamps drive this calculation; the values supply the count.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`ordered` is true when no timestamp precedes the one before it, `regular` is true when every consecutive gap is identical, `observations` is the series length, and `frequencySeconds` is that common gap in seconds or `null` when the spacing varies."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`timestamps` and `values` have different lengths",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the series holds fewer than two observations",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F10-A01.json",
        "call": "timeOrderFrequencyRegularityAndFinancialCalendars({\"timestamps\":[\"2025-01-01T00:00:00Z\",\"2025-01-02T00:00:00Z\",\"2025-01-03T00:00:00Z\",\"2025-01-04T00:00:00Z\",\"2025-01-05T00:00:00Z\",\"2025-01-06T00:00:00Z\"],\"values\":[100,102,101,104,106,105],\"lag\":1,\"window\":3,\"resampleSize\":2,\"period\":3,\"stationarityTolerance\":3,\"alpha\":0.4,\"splitIndex\":4})",
        "args": [
          {
            "value": {
              "timestamps": [
                "2025-01-01T00:00:00Z",
                "2025-01-02T00:00:00Z",
                "2025-01-03T00:00:00Z",
                "2025-01-04T00:00:00Z",
                "2025-01-05T00:00:00Z",
                "2025-01-06T00:00:00Z"
              ],
              "values": [
                100,
                102,
                101,
                104,
                106,
                105
              ],
              "lag": 1,
              "window": 3,
              "resampleSize": 2,
              "period": 3,
              "stationarityTolerance": 3,
              "alpha": 0.4,
              "splitIndex": 4
            },
            "elided": null
          }
        ],
        "output": {
          "ordered": true,
          "regular": true,
          "observations": 6,
          "frequencySeconds": 86400
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: ordered, regular, observations, frequencySeconds"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a01/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a01/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a01/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a01/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a01/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a01/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F10-A01",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Time Order, Frequency, Regularity, and Financial Calendars\"]\n    D --> E[\"Formula: ordered if t₁≤t₂≤…; regular if every adjacent UTC gap is identical\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Time Series Plot",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/timeseri.htm"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-time-series-foundations/time-order-frequency-regularity-and-financial-calendars/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-time-series-foundations/time-order-frequency-regularity-and-financial-calendars/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F10-A02",
      "name": "Levels, Changes, Differences, and Returns",
      "headline": null,
      "slug": "levels-changes-differences-and-returns",
      "path": "foundations/financial-time-series-foundations/levels-changes-differences-and-returns",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F10",
        "family": "Financial Time-Series Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-time-series-foundations/levels-changes-differences-and-returns",
        "entry": "levelsChangesDifferencesAndReturns",
        "params": [
          "input"
        ],
        "exports": [
          "levelsChangesDifferencesAndReturns"
        ],
        "archetype": "record-transform",
        "signature": "levelsChangesDifferencesAndReturns(input)"
      },
      "api": {
        "summary": "Converts a level series into its period-over-period differences and its simple returns, keeping the original levels alongside them.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `values`, a non-empty list of finite levels, and `timestamps`, a list of parseable date-time strings of the same length.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`levels` echoes the input series. `changes` and `differences` are the same list of consecutive first differences, one shorter than the input. `returns` divides each level by its predecessor and subtracts one."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`timestamps` and `values` have different lengths",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the series holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "any level other than the last one is zero, which would leave a return undefined",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F10-A02.json",
        "call": "levelsChangesDifferencesAndReturns({\"timestamps\":[\"2025-01-01T00:00:00Z\",\"2025-01-02T00:00:00Z\",\"2025-01-03T00:00:00Z\",\"2025-01-04T00:00:00Z\",\"2025-01-05T00:00:00Z\",\"2025-01-06T00:00:00Z\"],\"values\":[100,102,101,104,106,105],\"lag\":1,\"window\":3,\"resampleSize\":2,\"period\":3,\"stationarityTolerance\":3,\"alpha\":0.4,\"splitIndex\":4})",
        "args": [
          {
            "value": {
              "timestamps": [
                "2025-01-01T00:00:00Z",
                "2025-01-02T00:00:00Z",
                "2025-01-03T00:00:00Z",
                "2025-01-04T00:00:00Z",
                "2025-01-05T00:00:00Z",
                "2025-01-06T00:00:00Z"
              ],
              "values": [
                100,
                102,
                101,
                104,
                106,
                105
              ],
              "lag": 1,
              "window": 3,
              "resampleSize": 2,
              "period": 3,
              "stationarityTolerance": 3,
              "alpha": 0.4,
              "splitIndex": 4
            },
            "elided": null
          }
        ],
        "output": {
          "levels": [
            100,
            102,
            101,
            104,
            106,
            105
          ],
          "changes": [
            2,
            -1,
            3,
            2,
            -1
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: levels, changes"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a02/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a02/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a02/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a02/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a02/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a02/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F10-A02",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Levels, Changes, Differences, and Returns\"]\n    D --> E[\"Formula: Δxₜ=xₜ−xₜ₋₁; rₜ=xₜ/xₜ₋₁−1\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Time Series Plot",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/timeseri.htm"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-time-series-foundations/levels-changes-differences-and-returns/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-time-series-foundations/levels-changes-differences-and-returns/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F10-A03",
      "name": "Lags, Leads, and Temporal Dependence",
      "headline": null,
      "slug": "lags-leads-and-temporal-dependence",
      "path": "foundations/financial-time-series-foundations/lags-leads-and-temporal-dependence",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F10",
        "family": "Financial Time-Series Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-time-series-foundations/lags-leads-and-temporal-dependence",
        "entry": "lagsLeadsAndTemporalDependence",
        "params": [
          "input"
        ],
        "exports": [
          "lagsLeadsAndTemporalDependence"
        ],
        "archetype": "record-transform",
        "signature": "lagsLeadsAndTemporalDependence(input)"
      },
      "api": {
        "summary": "Pairs every observation with the value `lag` positions behind it, and exposes the same series shifted forward as the lead.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `values`, a non-empty list of finite numbers, `timestamps` of the same length, and `lag`, the whole number of positions to shift by.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`laggedPairs` holds one object per shiftable position with `current` and `lagged`, `leadValues` is the series with its first `lag` entries dropped, and `lag` is echoed back."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`timestamps` and `values` have different lengths",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the series holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`lag` is not an integer between one and the observation count minus one",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F10-A03.json",
        "call": "lagsLeadsAndTemporalDependence({\"timestamps\":[\"2025-01-01T00:00:00Z\",\"2025-01-02T00:00:00Z\",\"2025-01-03T00:00:00Z\",\"2025-01-04T00:00:00Z\",\"2025-01-05T00:00:00Z\",\"2025-01-06T00:00:00Z\"],\"values\":[100,102,101,104,106,105],\"lag\":1,\"window\":3,\"resampleSize\":2,\"period\":3,\"stationarityTolerance\":3,\"alpha\":0.4,\"splitIndex\":4})",
        "args": [
          {
            "value": {
              "timestamps": [
                "2025-01-01T00:00:00Z",
                "2025-01-02T00:00:00Z",
                "2025-01-03T00:00:00Z",
                "2025-01-04T00:00:00Z",
                "2025-01-05T00:00:00Z",
                "2025-01-06T00:00:00Z"
              ],
              "values": [
                100,
                102,
                101,
                104,
                106,
                105
              ],
              "lag": 1,
              "window": 3,
              "resampleSize": 2,
              "period": 3,
              "stationarityTolerance": 3,
              "alpha": 0.4,
              "splitIndex": 4
            },
            "elided": null
          }
        ],
        "output": {
          "laggedPairs": [
            {
              "current": 102,
              "lagged": 100
            },
            {
              "current": 101,
              "lagged": 102
            },
            {
              "current": 104,
              "lagged": 101
            }
          ],
          "leadValues": [
            102,
            101,
            104,
            106,
            105
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: laggedPairs, leadValues"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a03/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a03/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a03/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a03/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a03/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a03/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F10-A03",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Lags, Leads, and Temporal Dependence\"]\n    D --> E[\"Formula: lag-k pair=(xₜ,xₜ₋ₖ); lead-k=xₜ₊ₖ\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Time Series Plot",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/timeseri.htm"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-time-series-foundations/lags-leads-and-temporal-dependence/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-time-series-foundations/lags-leads-and-temporal-dependence/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F10-A04",
      "name": "Rolling and Expanding Windows",
      "headline": null,
      "slug": "rolling-and-expanding-windows",
      "path": "foundations/financial-time-series-foundations/rolling-and-expanding-windows",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F10",
        "family": "Financial Time-Series Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-time-series-foundations/rolling-and-expanding-windows",
        "entry": "rollingAndExpandingWindows",
        "params": [
          "input"
        ],
        "exports": [
          "rollingAndExpandingWindows"
        ],
        "archetype": "record-transform",
        "signature": "rollingAndExpandingWindows(input)"
      },
      "api": {
        "summary": "Computes a fixed-length rolling mean of the series next to its expanding mean, so a window that forgets can be compared with one that never does.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `values`, a non-empty list of finite numbers, `timestamps` of the same length, and `window`, the number of observations each rolling average covers.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`rollingMean` has one entry per observation and is `null` at every position with fewer than `window` observations behind it. `expandingMean` averages everything up to and including each position. `window` is echoed back."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`timestamps` and `values` have different lengths",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the series holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`window` is not an integer between one and the observation count",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n^2)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F10-A04.json",
        "call": "rollingAndExpandingWindows({\"timestamps\":[\"2025-01-01T00:00:00Z\",\"2025-01-02T00:00:00Z\",\"2025-01-03T00:00:00Z\",\"2025-01-04T00:00:00Z\",\"2025-01-05T00:00:00Z\",\"2025-01-06T00:00:00Z\"],\"values\":[100,102,101,104,106,105],\"lag\":1,\"window\":3,\"resampleSize\":2,\"period\":3,\"stationarityTolerance\":3,\"alpha\":0.4,\"splitIndex\":4})",
        "args": [
          {
            "value": {
              "timestamps": [
                "2025-01-01T00:00:00Z",
                "2025-01-02T00:00:00Z",
                "2025-01-03T00:00:00Z",
                "2025-01-04T00:00:00Z",
                "2025-01-05T00:00:00Z",
                "2025-01-06T00:00:00Z"
              ],
              "values": [
                100,
                102,
                101,
                104,
                106,
                105
              ],
              "lag": 1,
              "window": 3,
              "resampleSize": 2,
              "period": 3,
              "stationarityTolerance": 3,
              "alpha": 0.4,
              "splitIndex": 4
            },
            "elided": null
          }
        ],
        "output": {
          "rollingMean": [
            null,
            null,
            101,
            102.33333333333333,
            103.66666666666667,
            105
          ],
          "expandingMean": [
            100,
            101,
            101,
            101.75,
            102.6,
            103
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: rollingMean, expandingMean"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a04/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a04/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a04/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a04/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a04/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a04/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F10-A04",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Rolling and Expanding Windows\"]\n    D --> E[\"Formula: rolling meanₜ=(1/w)Σᵢ₌ₜ₋w+1ᵗxᵢ; expanding meanₜ=(1/t)Σᵢ≤t xᵢ\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Time Series Plot",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/timeseri.htm"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-time-series-foundations/rolling-and-expanding-windows/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-time-series-foundations/rolling-and-expanding-windows/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F10-A05",
      "name": "Resampling, Aggregation, and Time Alignment",
      "headline": null,
      "slug": "resampling-aggregation-and-time-alignment",
      "path": "foundations/financial-time-series-foundations/resampling-aggregation-and-time-alignment",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F10",
        "family": "Financial Time-Series Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-time-series-foundations/resampling-aggregation-and-time-alignment",
        "entry": "resamplingAggregationAndTimeAlignment",
        "params": [
          "input"
        ],
        "exports": [
          "resamplingAggregationAndTimeAlignment"
        ],
        "archetype": "record-transform",
        "signature": "resamplingAggregationAndTimeAlignment(input)"
      },
      "api": {
        "summary": "Cuts the series into consecutive fixed-size buckets and averages each one, coarsening the sampling frequency.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `values`, a non-empty list of finite numbers, `timestamps` of the same length, and `resampleSize`, the number of observations per bucket.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`aggregatedMeans` holds one mean per bucket and `bucketSizes` their lengths, the last of which is short when the series does not divide evenly. `alignment` is the fixed label `left-closed sequential buckets`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`timestamps` and `values` have different lengths",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the series holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`resampleSize` is not a positive integer",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n^2)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F10-A05.json",
        "call": "resamplingAggregationAndTimeAlignment({\"timestamps\":[\"2025-01-01T00:00:00Z\",\"2025-01-02T00:00:00Z\",\"2025-01-03T00:00:00Z\",\"2025-01-04T00:00:00Z\",\"2025-01-05T00:00:00Z\",\"2025-01-06T00:00:00Z\"],\"values\":[100,102,101,104,106,105],\"lag\":1,\"window\":3,\"resampleSize\":2,\"period\":3,\"stationarityTolerance\":3,\"alpha\":0.4,\"splitIndex\":4})",
        "args": [
          {
            "value": {
              "timestamps": [
                "2025-01-01T00:00:00Z",
                "2025-01-02T00:00:00Z",
                "2025-01-03T00:00:00Z",
                "2025-01-04T00:00:00Z",
                "2025-01-05T00:00:00Z",
                "2025-01-06T00:00:00Z"
              ],
              "values": [
                100,
                102,
                101,
                104,
                106,
                105
              ],
              "lag": 1,
              "window": 3,
              "resampleSize": 2,
              "period": 3,
              "stationarityTolerance": 3,
              "alpha": 0.4,
              "splitIndex": 4
            },
            "elided": null
          }
        ],
        "output": {
          "aggregatedMeans": [
            101,
            102.5,
            105.5
          ],
          "bucketSizes": [
            2,
            2,
            2
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: aggregatedMeans, bucketSizes"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a05/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a05/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a05/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a05/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a05/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a05/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F10-A05",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Resampling, Aggregation, and Time Alignment\"]\n    D --> E[\"Formula: bucket statistic=aggregate{xₜ:t in declared interval}\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Time Series Plot",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/timeseri.htm"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-time-series-foundations/resampling-aggregation-and-time-alignment/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-time-series-foundations/resampling-aggregation-and-time-alignment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F10-A06",
      "name": "Trend, Seasonality, Cycles, and Remainder",
      "headline": null,
      "slug": "trend-seasonality-cycles-and-remainder",
      "path": "foundations/financial-time-series-foundations/trend-seasonality-cycles-and-remainder",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F10",
        "family": "Financial Time-Series Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-time-series-foundations/trend-seasonality-cycles-and-remainder",
        "entry": "trendSeasonalityCyclesAndRemainder",
        "params": [
          "input"
        ],
        "exports": [
          "trendSeasonalityCyclesAndRemainder"
        ],
        "archetype": "record-transform",
        "signature": "trendSeasonalityCyclesAndRemainder(input)"
      },
      "api": {
        "summary": "Separates a series into a rolling-mean trend, a seasonal difference taken `period` steps back, and the remainder left once the trend is removed.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `values`, a non-empty list of finite numbers, `timestamps` of the same length, `window` for the trend average, and `period` for the seasonal difference.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`trend` is the rolling mean, `null` at positions with fewer than `window` observations behind them. `seasonalDifference` subtracts the value `period` positions earlier and is `null` for the first `period` entries. `remainder` is the value minus the trend, `null` wherever the trend is. `period` is echoed back."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`timestamps` and `values` have different lengths",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the series holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`window` is not an integer between one and the observation count",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`period` is not an integer between one and the observation count minus one",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n^2)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F10-A06.json",
        "call": "trendSeasonalityCyclesAndRemainder({\"timestamps\":[\"2025-01-01T00:00:00Z\",\"2025-01-02T00:00:00Z\",\"2025-01-03T00:00:00Z\",\"2025-01-04T00:00:00Z\",\"2025-01-05T00:00:00Z\",\"2025-01-06T00:00:00Z\"],\"values\":[100,102,101,104,106,105],\"lag\":1,\"window\":3,\"resampleSize\":2,\"period\":3,\"stationarityTolerance\":3,\"alpha\":0.4,\"splitIndex\":4})",
        "args": [
          {
            "value": {
              "timestamps": [
                "2025-01-01T00:00:00Z",
                "2025-01-02T00:00:00Z",
                "2025-01-03T00:00:00Z",
                "2025-01-04T00:00:00Z",
                "2025-01-05T00:00:00Z",
                "2025-01-06T00:00:00Z"
              ],
              "values": [
                100,
                102,
                101,
                104,
                106,
                105
              ],
              "lag": 1,
              "window": 3,
              "resampleSize": 2,
              "period": 3,
              "stationarityTolerance": 3,
              "alpha": 0.4,
              "splitIndex": 4
            },
            "elided": null
          }
        ],
        "output": {
          "trend": [
            null,
            null,
            101,
            102.33333333333333,
            103.66666666666667,
            105
          ],
          "seasonalDifference": [
            null,
            null,
            null,
            4,
            4,
            4
          ],
          "remainder": [
            null,
            null,
            0,
            1.6666666666666714,
            2.3333333333333286,
            0
          ],
          "period": 3
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: trend, seasonalDifference, remainder, period"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a06/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a06/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a06/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a06/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a06/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a06/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F10-A06",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Trend, Seasonality, Cycles, and Remainder\"]\n    D --> E[\"Formula: trendₜ=mean(xₜ₋w₊₁…xₜ); seasonalDifferenceₜ=xₜ−xₜ₋ₚ; remainderₜ=xₜ−trendₜ\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Time Series Plot",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/timeseri.htm"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-time-series-foundations/trend-seasonality-cycles-and-remainder/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-time-series-foundations/trend-seasonality-cycles-and-remainder/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F10-A07",
      "name": "Autocovariance and Autocorrelation",
      "headline": null,
      "slug": "autocovariance-and-autocorrelation",
      "path": "foundations/financial-time-series-foundations/autocovariance-and-autocorrelation",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F10",
        "family": "Financial Time-Series Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-time-series-foundations/autocovariance-and-autocorrelation",
        "entry": "autocovarianceAndAutocorrelation",
        "params": [
          "input"
        ],
        "exports": [
          "autocovarianceAndAutocorrelation"
        ],
        "archetype": "record-transform",
        "signature": "autocovarianceAndAutocorrelation(input)"
      },
      "api": {
        "summary": "Measures how far a series moves with its own past at a given lag, using the population convention that divides by the full observation count.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `values`, a non-empty list of finite numbers, `timestamps` of the same length, and `lag`, the whole number of positions to look back.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`autocovariance` is the mean product of deviations `lag` apart, `autocorrelation` is that figure divided by the population variance, and `lag` is echoed back."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`timestamps` and `values` have different lengths",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the series holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`lag` is not an integer between one and the observation count minus one",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the series is constant, so its population variance is zero",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n^2)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F10-A07.json",
        "call": "autocovarianceAndAutocorrelation({\"timestamps\":[\"2025-01-01T00:00:00Z\",\"2025-01-02T00:00:00Z\",\"2025-01-03T00:00:00Z\",\"2025-01-04T00:00:00Z\",\"2025-01-05T00:00:00Z\",\"2025-01-06T00:00:00Z\"],\"values\":[100,102,101,104,106,105],\"lag\":1,\"window\":3,\"resampleSize\":2,\"period\":3,\"stationarityTolerance\":3,\"alpha\":0.4,\"splitIndex\":4})",
        "args": [
          {
            "value": {
              "timestamps": [
                "2025-01-01T00:00:00Z",
                "2025-01-02T00:00:00Z",
                "2025-01-03T00:00:00Z",
                "2025-01-04T00:00:00Z",
                "2025-01-05T00:00:00Z",
                "2025-01-06T00:00:00Z"
              ],
              "values": [
                100,
                102,
                101,
                104,
                106,
                105
              ],
              "lag": 1,
              "window": 3,
              "resampleSize": 2,
              "period": 3,
              "stationarityTolerance": 3,
              "alpha": 0.4,
              "splitIndex": 4
            },
            "elided": null
          }
        ],
        "output": {
          "autocovariance": 2,
          "autocorrelation": 0.42857142857142855
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: autocovariance, autocorrelation"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a07/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a07/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a07/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a07/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a07/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a07/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F10-A07",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Autocovariance and Autocorrelation\"]\n    D --> E[\"Formula: γk=(1/n)Σₜ₌k(xₜ−x̄)(xₜ₋ₖ−x̄); ρk=γk/γ0\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Time Series Plot",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/timeseri.htm"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-time-series-foundations/autocovariance-and-autocorrelation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-time-series-foundations/autocovariance-and-autocorrelation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F10-A08",
      "name": "Stationarity and Differencing Intuition",
      "headline": null,
      "slug": "stationarity-and-differencing-intuition",
      "path": "foundations/financial-time-series-foundations/stationarity-and-differencing-intuition",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F10",
        "family": "Financial Time-Series Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-time-series-foundations/stationarity-and-differencing-intuition",
        "entry": "stationarityAndDifferencingIntuition",
        "params": [
          "input"
        ],
        "exports": [
          "stationarityAndDifferencingIntuition"
        ],
        "archetype": "record-transform",
        "signature": "stationarityAndDifferencingIntuition(input)"
      },
      "api": {
        "summary": "Compares the average level of the second half of a series with the first half, and reports the first differences, as a rough read on whether the level drifts.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `values`, a non-empty list of finite numbers, `timestamps` of the same length, and `stationarityTolerance`, the size of mean shift still treated as flat.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`meanShift` is the second-half mean minus the first-half mean, `firstDifferences` the consecutive changes, `differenceMean` their average, and `levelLikelyStationary` is true when the absolute mean shift is within `stationarityTolerance`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`timestamps` and `values` have different lengths",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the series holds fewer than two observations",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n^2)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F10-A08.json",
        "call": "stationarityAndDifferencingIntuition({\"timestamps\":[\"2025-01-01T00:00:00Z\",\"2025-01-02T00:00:00Z\",\"2025-01-03T00:00:00Z\",\"2025-01-04T00:00:00Z\",\"2025-01-05T00:00:00Z\",\"2025-01-06T00:00:00Z\"],\"values\":[100,102,101,104,106,105],\"lag\":1,\"window\":3,\"resampleSize\":2,\"period\":3,\"stationarityTolerance\":3,\"alpha\":0.4,\"splitIndex\":4})",
        "args": [
          {
            "value": {
              "timestamps": [
                "2025-01-01T00:00:00Z",
                "2025-01-02T00:00:00Z",
                "2025-01-03T00:00:00Z",
                "2025-01-04T00:00:00Z",
                "2025-01-05T00:00:00Z",
                "2025-01-06T00:00:00Z"
              ],
              "values": [
                100,
                102,
                101,
                104,
                106,
                105
              ],
              "lag": 1,
              "window": 3,
              "resampleSize": 2,
              "period": 3,
              "stationarityTolerance": 3,
              "alpha": 0.4,
              "splitIndex": 4
            },
            "elided": null
          }
        ],
        "output": {
          "meanShift": 4,
          "firstDifferences": [
            2,
            -1,
            3,
            2,
            -1
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: meanShift, firstDifferences"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a08/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a08/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a08/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a08/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a08/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a08/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F10-A08",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Stationarity and Differencing Intuition\"]\n    D --> E[\"Formula: Δxₜ=xₜ−xₜ₋₁; compare early and late means as a diagnostic\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Time Series Plot",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/timeseri.htm"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-time-series-foundations/stationarity-and-differencing-intuition/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-time-series-foundations/stationarity-and-differencing-intuition/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F10-A09",
      "name": "Smoothing, Baselines, and Naive Forecasts",
      "headline": null,
      "slug": "smoothing-baselines-and-naive-forecasts",
      "path": "foundations/financial-time-series-foundations/smoothing-baselines-and-naive-forecasts",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F10",
        "family": "Financial Time-Series Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-time-series-foundations/smoothing-baselines-and-naive-forecasts",
        "entry": "smoothingBaselinesAndNaiveForecasts",
        "params": [
          "input"
        ],
        "exports": [
          "smoothingBaselinesAndNaiveForecasts"
        ],
        "archetype": "record-transform",
        "signature": "smoothingBaselinesAndNaiveForecasts(input)"
      },
      "api": {
        "summary": "Runs simple exponential smoothing over the series and reports both the naive last-value forecast and the smoothed one.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `values`, a non-empty list of finite numbers, `timestamps` of the same length, and `alpha`, the weight placed on the newest observation.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`smoothed` is the same length as the input and starts at its first value. `naiveNext` is the last observed level and `smoothedNext` the last smoothed one."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`timestamps` and `values` have different lengths",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the series holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`alpha` is outside the closed interval from zero to one",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n^2)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F10-A09.json",
        "call": "smoothingBaselinesAndNaiveForecasts({\"timestamps\":[\"2025-01-01T00:00:00Z\",\"2025-01-02T00:00:00Z\",\"2025-01-03T00:00:00Z\",\"2025-01-04T00:00:00Z\",\"2025-01-05T00:00:00Z\",\"2025-01-06T00:00:00Z\"],\"values\":[100,102,101,104,106,105],\"lag\":1,\"window\":3,\"resampleSize\":2,\"period\":3,\"stationarityTolerance\":3,\"alpha\":0.4,\"splitIndex\":4})",
        "args": [
          {
            "value": {
              "timestamps": [
                "2025-01-01T00:00:00Z",
                "2025-01-02T00:00:00Z",
                "2025-01-03T00:00:00Z",
                "2025-01-04T00:00:00Z",
                "2025-01-05T00:00:00Z",
                "2025-01-06T00:00:00Z"
              ],
              "values": [
                100,
                102,
                101,
                104,
                106,
                105
              ],
              "lag": 1,
              "window": 3,
              "resampleSize": 2,
              "period": 3,
              "stationarityTolerance": 3,
              "alpha": 0.4,
              "splitIndex": 4
            },
            "elided": null
          }
        ],
        "output": {
          "smoothed": [
            100,
            100.80000000000001,
            100.88000000000001,
            102.12800000000001,
            103.67680000000001,
            104.20608000000001
          ],
          "naiveNext": 105
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: smoothed, naiveNext"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a09/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a09/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a09/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a09/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a09/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a09/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F10-A09",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Smoothing, Baselines, and Naive Forecasts\"]\n    D --> E[\"Formula: sₜ=αxₜ+(1−α)sₜ₋₁; naive x̂ₜ₊₁=xₜ\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Time Series Plot",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/timeseri.htm"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-time-series-foundations/smoothing-baselines-and-naive-forecasts/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-time-series-foundations/smoothing-baselines-and-naive-forecasts/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F10-A10",
      "name": "Look-Ahead Leakage and Time-Aware Data Splits",
      "headline": null,
      "slug": "look-ahead-leakage-and-time-aware-data-splits",
      "path": "foundations/financial-time-series-foundations/look-ahead-leakage-and-time-aware-data-splits",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F10",
        "family": "Financial Time-Series Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-time-series-foundations/look-ahead-leakage-and-time-aware-data-splits",
        "entry": "lookAheadLeakageAndTimeAwareDataSplits",
        "params": [
          "input"
        ],
        "exports": [
          "lookAheadLeakageAndTimeAwareDataSplits"
        ],
        "archetype": "record-transform",
        "signature": "lookAheadLeakageAndTimeAwareDataSplits(input)"
      },
      "api": {
        "summary": "Splits a timestamped series at a given position and reports whether the training block reaches into the testing block's time range.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `values`, a non-empty list of finite numbers, `timestamps` of the same length, and `splitIndex`, the position where testing begins.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`trainCount` and `testCount` size the two blocks, `leakage` is true when the latest training timestamp is at or after the earliest testing one, and `trainEnd` and `testStart` are the boundary timestamps exactly as supplied."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`timestamps` and `values` have different lengths",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the series holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`splitIndex` is not an integer that leaves both blocks non-empty",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n^2)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F10-A10.json",
        "call": "lookAheadLeakageAndTimeAwareDataSplits({\"timestamps\":[\"2025-01-01T00:00:00Z\",\"2025-01-02T00:00:00Z\",\"2025-01-03T00:00:00Z\",\"2025-01-04T00:00:00Z\",\"2025-01-05T00:00:00Z\",\"2025-01-06T00:00:00Z\"],\"values\":[100,102,101,104,106,105],\"lag\":1,\"window\":3,\"resampleSize\":2,\"period\":3,\"stationarityTolerance\":3,\"alpha\":0.4,\"splitIndex\":4})",
        "args": [
          {
            "value": {
              "timestamps": [
                "2025-01-01T00:00:00Z",
                "2025-01-02T00:00:00Z",
                "2025-01-03T00:00:00Z",
                "2025-01-04T00:00:00Z",
                "2025-01-05T00:00:00Z",
                "2025-01-06T00:00:00Z"
              ],
              "values": [
                100,
                102,
                101,
                104,
                106,
                105
              ],
              "lag": 1,
              "window": 3,
              "resampleSize": 2,
              "period": 3,
              "stationarityTolerance": 3,
              "alpha": 0.4,
              "splitIndex": 4
            },
            "elided": null
          }
        ],
        "output": {
          "trainCount": 4,
          "testCount": 2,
          "leakage": false,
          "trainEnd": "2025-01-04T00:00:00Z",
          "testStart": "2025-01-05T00:00:00Z"
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: trainCount, testCount, leakage, trainEnd, testStart"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a10/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a10/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a10/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a10/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a10/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f10-a10/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F10-A10",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Look-Ahead Leakage and Time-Aware Data Splits\"]\n    D --> E[\"Formula: max(train time)<min(test time)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Time Series Plot",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/timeseri.htm"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-time-series-foundations/look-ahead-leakage-and-time-aware-data-splits/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-time-series-foundations/look-ahead-leakage-and-time-aware-data-splits/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F11-A01",
      "name": "Volatility and Annualized Volatility",
      "headline": null,
      "slug": "volatility-and-annualized-volatility",
      "path": "foundations/financial-risk-and-performance-statistics/volatility-and-annualized-volatility",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F11",
        "family": "Financial Risk and Performance Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-risk-and-performance-statistics/volatility-and-annualized-volatility",
        "entry": "volatilityAndAnnualizedVolatility",
        "params": [
          "input"
        ],
        "exports": [
          "volatilityAndAnnualizedVolatility"
        ],
        "archetype": "record-transform",
        "signature": "volatilityAndAnnualizedVolatility(input)"
      },
      "api": {
        "summary": "Takes the sample standard deviation of a return series and rescales it to an annual horizon by the square root of the observations per year.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `returns` and `benchmark`, two aligned non-empty lists of finite periodic returns, and `frequency`, the number of periods per year. Only `returns` and `frequency` enter this calculation; `benchmark` is still validated.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`periodicVolatility` is the per-period sample standard deviation and `annualizedVolatility` is that figure times the square root of `frequency`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`returns` or `benchmark` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`returns` and `benchmark` differ in length, or hold fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`frequency` is zero or negative",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F11-A01.json",
        "call": "volatilityAndAnnualizedVolatility({\"returns\":[0.01,-0.02,0.015,-0.01,0.03],\"benchmark\":[0.008,-0.01,0.012,-0.006,0.02],\"frequency\":252,\"target\":0,\"confidence\":0.8,\"riskFree\":0.0001,\"weights\":[0.6,0.4],\"covarianceMatrix\":[[0.04,0.01],[0.01,0.09]]})",
        "args": [
          {
            "value": {
              "returns": [
                0.01,
                -0.02,
                0.015,
                -0.01,
                0.03
              ],
              "benchmark": [
                0.008,
                -0.01,
                0.012,
                -0.006,
                0.02
              ],
              "frequency": 252,
              "target": 0,
              "confidence": 0.8,
              "riskFree": 0.0001,
              "weights": [
                0.6,
                0.4
              ],
              "covarianceMatrix": [
                [
                  0.04,
                  0.01
                ],
                [
                  0.01,
                  0.09
                ]
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "periodicVolatility": 0.02,
          "annualizedVolatility": 0.3174901573277509
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: periodicVolatility, annualizedVolatility"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a01/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a01/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a01/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a01/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a01/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a01/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F11-A01",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Volatility and Annualized Volatility\"]\n    D --> E[\"Formula: periodic vol=s(returns); annualized vol=periodic vol·√frequency\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Basel Framework MAR33",
          "title": "Expected Shortfall",
          "author": "Basel Framework MAR33",
          "url": "https://www.bis.org/basel_framework/chapter/MAR/33.htm"
        },
        {
          "key": "William F. Sharpe",
          "title": "Mutual Fund Performance",
          "author": "William F. Sharpe",
          "url": "https://web.stanford.edu/~wfsharpe/art/mfpm/mfpm.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-risk-and-performance-statistics/volatility-and-annualized-volatility/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-risk-and-performance-statistics/volatility-and-annualized-volatility/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F11-A02",
      "name": "Downside Deviation and Target Shortfall",
      "headline": null,
      "slug": "downside-deviation-and-target-shortfall",
      "path": "foundations/financial-risk-and-performance-statistics/downside-deviation-and-target-shortfall",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F11",
        "family": "Financial Risk and Performance Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-risk-and-performance-statistics/downside-deviation-and-target-shortfall",
        "entry": "downsideDeviationAndTargetShortfall",
        "params": [
          "input"
        ],
        "exports": [
          "downsideDeviationAndTargetShortfall"
        ],
        "archetype": "record-transform",
        "signature": "downsideDeviationAndTargetShortfall(input)"
      },
      "api": {
        "summary": "Measures dispersion of returns below a target only, so upside swings do not count as risk.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `returns` and `benchmark`, two aligned non-empty lists of finite periodic returns, `frequency`, the number of periods per year, and `target`, the return level below which a period counts as a shortfall.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`downsideDeviation` is the root mean square of the shortfalls below `target`, averaged over every observation rather than only the shortfalls. `shortfallCount` counts the returns strictly below the target, and `target` is echoed back."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`returns` or `benchmark` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`returns` and `benchmark` differ in length, or hold fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`frequency` is zero or negative",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F11-A02.json",
        "call": "downsideDeviationAndTargetShortfall({\"returns\":[0.01,-0.02,0.015,-0.01,0.03],\"benchmark\":[0.008,-0.01,0.012,-0.006,0.02],\"frequency\":252,\"target\":0,\"confidence\":0.8,\"riskFree\":0.0001,\"weights\":[0.6,0.4],\"covarianceMatrix\":[[0.04,0.01],[0.01,0.09]]})",
        "args": [
          {
            "value": {
              "returns": [
                0.01,
                -0.02,
                0.015,
                -0.01,
                0.03
              ],
              "benchmark": [
                0.008,
                -0.01,
                0.012,
                -0.006,
                0.02
              ],
              "frequency": 252,
              "target": 0,
              "confidence": 0.8,
              "riskFree": 0.0001,
              "weights": [
                0.6,
                0.4
              ],
              "covarianceMatrix": [
                [
                  0.04,
                  0.01
                ],
                [
                  0.01,
                  0.09
                ]
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "downsideDeviation": 0.01,
          "shortfallCount": 2
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: downsideDeviation, shortfallCount"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a02/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a02/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a02/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a02/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a02/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a02/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F11-A02",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Downside Deviation and Target Shortfall\"]\n    D --> E[\"Formula: downside deviation=√mean[min(0,rₜ−target)²]\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Basel Framework MAR33",
          "title": "Expected Shortfall",
          "author": "Basel Framework MAR33",
          "url": "https://www.bis.org/basel_framework/chapter/MAR/33.htm"
        },
        {
          "key": "William F. Sharpe",
          "title": "Mutual Fund Performance",
          "author": "William F. Sharpe",
          "url": "https://web.stanford.edu/~wfsharpe/art/mfpm/mfpm.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-risk-and-performance-statistics/downside-deviation-and-target-shortfall/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-risk-and-performance-statistics/downside-deviation-and-target-shortfall/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F11-A03",
      "name": "Drawdown and Maximum Drawdown",
      "headline": null,
      "slug": "drawdown-and-maximum-drawdown",
      "path": "foundations/financial-risk-and-performance-statistics/drawdown-and-maximum-drawdown",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F11",
        "family": "Financial Risk and Performance Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-risk-and-performance-statistics/drawdown-and-maximum-drawdown",
        "entry": "drawdownAndMaximumDrawdown",
        "params": [
          "input"
        ],
        "exports": [
          "drawdownAndMaximumDrawdown"
        ],
        "archetype": "record-transform",
        "signature": "drawdownAndMaximumDrawdown(input)"
      },
      "api": {
        "summary": "Compounds a return series into a wealth path and tracks how far that path sits below its own running peak.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `returns` and `benchmark`, two aligned non-empty lists of finite periodic returns, and `frequency`, the number of periods per year. The wealth path is built from `returns` alone.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`drawdowns` gives one non-positive figure per period, each the fractional shortfall against the running peak. `maximumDrawdown` is the most negative of them and `endingWealth` is the final value of a path that starts at one."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`returns` or `benchmark` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`returns` and `benchmark` differ in length, or hold fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`frequency` is zero or negative",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F11-A03.json",
        "call": "drawdownAndMaximumDrawdown({\"returns\":[0.01,-0.02,0.015,-0.01,0.03],\"benchmark\":[0.008,-0.01,0.012,-0.006,0.02],\"frequency\":252,\"target\":0,\"confidence\":0.8,\"riskFree\":0.0001,\"weights\":[0.6,0.4],\"covarianceMatrix\":[[0.04,0.01],[0.01,0.09]]})",
        "args": [
          {
            "value": {
              "returns": [
                0.01,
                -0.02,
                0.015,
                -0.01,
                0.03
              ],
              "benchmark": [
                0.008,
                -0.01,
                0.012,
                -0.006,
                0.02
              ],
              "frequency": 252,
              "target": 0,
              "confidence": 0.8,
              "riskFree": 0.0001,
              "weights": [
                0.6,
                0.4
              ],
              "covarianceMatrix": [
                [
                  0.04,
                  0.01
                ],
                [
                  0.01,
                  0.09
                ]
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "drawdowns": [
            0,
            -0.020000000000000018,
            -0.0053000000000001934,
            -0.015247000000000233,
            0
          ],
          "maximumDrawdown": -0.020000000000000018
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: drawdowns, maximumDrawdown"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a03/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a03/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a03/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a03/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a03/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a03/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F11-A03",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Drawdown and Maximum Drawdown\"]\n    D --> E[\"Formula: wealthₜ=wealthₜ₋₁(1+rₜ); DDₜ=wealthₜ/peakₜ−1\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Basel Framework MAR33",
          "title": "Expected Shortfall",
          "author": "Basel Framework MAR33",
          "url": "https://www.bis.org/basel_framework/chapter/MAR/33.htm"
        },
        {
          "key": "William F. Sharpe",
          "title": "Mutual Fund Performance",
          "author": "William F. Sharpe",
          "url": "https://web.stanford.edu/~wfsharpe/art/mfpm/mfpm.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-risk-and-performance-statistics/drawdown-and-maximum-drawdown/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-risk-and-performance-statistics/drawdown-and-maximum-drawdown/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F11-A04",
      "name": "Loss Distributions and Loss Quantiles",
      "headline": null,
      "slug": "loss-distributions-and-loss-quantiles",
      "path": "foundations/financial-risk-and-performance-statistics/loss-distributions-and-loss-quantiles",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F11",
        "family": "Financial Risk and Performance Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-risk-and-performance-statistics/loss-distributions-and-loss-quantiles",
        "entry": "lossDistributionsAndLossQuantiles",
        "params": [
          "input"
        ],
        "exports": [
          "lossDistributionsAndLossQuantiles"
        ],
        "archetype": "record-transform",
        "signature": "lossDistributionsAndLossQuantiles(input)"
      },
      "api": {
        "summary": "Flips a return series into losses, sorts them, and reads off the quantile at the requested confidence by linear interpolation between neighbours.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `returns` and `benchmark`, two aligned non-empty lists of finite periodic returns, `frequency`, the number of periods per year, and `confidence`, the quantile level in the closed interval from zero to one.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`losses` is the sign-flipped return series sorted ascending, `lossQuantile` is the interpolated quantile at `confidence`, and `confidence` is echoed back."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`returns` or `benchmark` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`returns` and `benchmark` differ in length, or hold fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`frequency` is zero or negative",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`confidence` is outside the closed interval from zero to one",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`confidence` is absent, or outside the range zero to one — the engine reads it for every topic from A04 onward, including those that never use it",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F11-A04.json",
        "call": "lossDistributionsAndLossQuantiles({\"returns\":[0.01,-0.02,0.015,-0.01,0.03],\"benchmark\":[0.008,-0.01,0.012,-0.006,0.02],\"frequency\":252,\"target\":0,\"confidence\":0.8,\"riskFree\":0.0001,\"weights\":[0.6,0.4],\"covarianceMatrix\":[[0.04,0.01],[0.01,0.09]]})",
        "args": [
          {
            "value": {
              "returns": [
                0.01,
                -0.02,
                0.015,
                -0.01,
                0.03
              ],
              "benchmark": [
                0.008,
                -0.01,
                0.012,
                -0.006,
                0.02
              ],
              "frequency": 252,
              "target": 0,
              "confidence": 0.8,
              "riskFree": 0.0001,
              "weights": [
                0.6,
                0.4
              ],
              "covarianceMatrix": [
                [
                  0.04,
                  0.01
                ],
                [
                  0.01,
                  0.09
                ]
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "losses": [
            -0.03,
            -0.015,
            -0.01,
            0.01,
            0.02
          ],
          "lossQuantile": 0.012000000000000002
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: losses, lossQuantile"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a04/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a04/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a04/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a04/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a04/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a04/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F11-A04",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Loss Distributions and Loss Quantiles\"]\n    D --> E[\"Formula: loss=−return; loss quantile=Qconfidence(losses)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Basel Framework MAR33",
          "title": "Expected Shortfall",
          "author": "Basel Framework MAR33",
          "url": "https://www.bis.org/basel_framework/chapter/MAR/33.htm"
        },
        {
          "key": "William F. Sharpe",
          "title": "Mutual Fund Performance",
          "author": "William F. Sharpe",
          "url": "https://web.stanford.edu/~wfsharpe/art/mfpm/mfpm.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-risk-and-performance-statistics/loss-distributions-and-loss-quantiles/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-risk-and-performance-statistics/loss-distributions-and-loss-quantiles/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F11-A05",
      "name": "Value at Risk Intuition",
      "headline": null,
      "slug": "value-at-risk-intuition",
      "path": "foundations/financial-risk-and-performance-statistics/value-at-risk-intuition",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F11",
        "family": "Financial Risk and Performance Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-risk-and-performance-statistics/value-at-risk-intuition",
        "entry": "valueAtRiskIntuition",
        "params": [
          "input"
        ],
        "exports": [
          "valueAtRiskIntuition"
        ],
        "archetype": "record-transform",
        "signature": "valueAtRiskIntuition(input)"
      },
      "api": {
        "summary": "Reads historical value at risk straight off the sorted loss series and counts how many observed losses ran past it.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `returns` and `benchmark`, two aligned non-empty lists of finite periodic returns, `frequency`, the number of periods per year, and `confidence`, the quantile level in the closed interval from zero to one.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`valueAtRisk` is the interpolated loss quantile at `confidence`, `confidence` is echoed back, and `lossExceedsVaR` counts the losses strictly greater than that quantile."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`returns` or `benchmark` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`returns` and `benchmark` differ in length, or hold fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`frequency` is zero or negative",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`confidence` is outside the closed interval from zero to one",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`confidence` is absent, or outside the range zero to one — the engine reads it for every topic from A04 onward, including those that never use it",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F11-A05.json",
        "call": "valueAtRiskIntuition({\"returns\":[0.01,-0.02,0.015,-0.01,0.03],\"benchmark\":[0.008,-0.01,0.012,-0.006,0.02],\"frequency\":252,\"target\":0,\"confidence\":0.8,\"riskFree\":0.0001,\"weights\":[0.6,0.4],\"covarianceMatrix\":[[0.04,0.01],[0.01,0.09]]})",
        "args": [
          {
            "value": {
              "returns": [
                0.01,
                -0.02,
                0.015,
                -0.01,
                0.03
              ],
              "benchmark": [
                0.008,
                -0.01,
                0.012,
                -0.006,
                0.02
              ],
              "frequency": 252,
              "target": 0,
              "confidence": 0.8,
              "riskFree": 0.0001,
              "weights": [
                0.6,
                0.4
              ],
              "covarianceMatrix": [
                [
                  0.04,
                  0.01
                ],
                [
                  0.01,
                  0.09
                ]
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "valueAtRisk": 0.012000000000000002,
          "confidence": 0.8
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: valueAtRisk, confidence"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a05/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a05/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a05/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a05/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a05/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a05/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F11-A05",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Value at Risk Intuition\"]\n    D --> E[\"Formula: VaRα=Qα(loss)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Basel Framework MAR33",
          "title": "Expected Shortfall",
          "author": "Basel Framework MAR33",
          "url": "https://www.bis.org/basel_framework/chapter/MAR/33.htm"
        },
        {
          "key": "William F. Sharpe",
          "title": "Mutual Fund Performance",
          "author": "William F. Sharpe",
          "url": "https://web.stanford.edu/~wfsharpe/art/mfpm/mfpm.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-risk-and-performance-statistics/value-at-risk-intuition/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-risk-and-performance-statistics/value-at-risk-intuition/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F11-A06",
      "name": "Expected Shortfall Intuition",
      "headline": null,
      "slug": "expected-shortfall-intuition",
      "path": "foundations/financial-risk-and-performance-statistics/expected-shortfall-intuition",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F11",
        "family": "Financial Risk and Performance Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-risk-and-performance-statistics/expected-shortfall-intuition",
        "entry": "expectedShortfallIntuition",
        "params": [
          "input"
        ],
        "exports": [
          "expectedShortfallIntuition"
        ],
        "archetype": "record-transform",
        "signature": "expectedShortfallIntuition(input)"
      },
      "api": {
        "summary": "Averages the losses that sit at or beyond the value-at-risk threshold, describing the tail rather than only its edge.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `returns` and `benchmark`, two aligned non-empty lists of finite periodic returns, `frequency`, the number of periods per year, and `confidence`, the quantile level in the closed interval from zero to one.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`expectedShortfall` is the mean of the tail losses, `valueAtRisk` is the threshold they were selected against, and `tailObservations` counts how many losses were at or above it."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`returns` or `benchmark` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`returns` and `benchmark` differ in length, or hold fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`frequency` is zero or negative",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`confidence` is outside the closed interval from zero to one",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`confidence` is absent, or outside the range zero to one — the engine reads it for every topic from A04 onward, including those that never use it",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F11-A06.json",
        "call": "expectedShortfallIntuition({\"returns\":[0.01,-0.02,0.015,-0.01,0.03],\"benchmark\":[0.008,-0.01,0.012,-0.006,0.02],\"frequency\":252,\"target\":0,\"confidence\":0.8,\"riskFree\":0.0001,\"weights\":[0.6,0.4],\"covarianceMatrix\":[[0.04,0.01],[0.01,0.09]]})",
        "args": [
          {
            "value": {
              "returns": [
                0.01,
                -0.02,
                0.015,
                -0.01,
                0.03
              ],
              "benchmark": [
                0.008,
                -0.01,
                0.012,
                -0.006,
                0.02
              ],
              "frequency": 252,
              "target": 0,
              "confidence": 0.8,
              "riskFree": 0.0001,
              "weights": [
                0.6,
                0.4
              ],
              "covarianceMatrix": [
                [
                  0.04,
                  0.01
                ],
                [
                  0.01,
                  0.09
                ]
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "expectedShortfall": 0.02,
          "valueAtRisk": 0.012000000000000002
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: expectedShortfall, valueAtRisk"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a06/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a06/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a06/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a06/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a06/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a06/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F11-A06",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Expected Shortfall Intuition\"]\n    D --> E[\"Formula: ESα=mean{L:L≥VaRα}\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Basel Framework MAR33",
          "title": "Expected Shortfall",
          "author": "Basel Framework MAR33",
          "url": "https://www.bis.org/basel_framework/chapter/MAR/33.htm"
        },
        {
          "key": "William F. Sharpe",
          "title": "Mutual Fund Performance",
          "author": "William F. Sharpe",
          "url": "https://web.stanford.edu/~wfsharpe/art/mfpm/mfpm.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-risk-and-performance-statistics/expected-shortfall-intuition/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-risk-and-performance-statistics/expected-shortfall-intuition/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F11-A07",
      "name": "Beta and Market-Relative Risk",
      "headline": null,
      "slug": "beta-and-market-relative-risk",
      "path": "foundations/financial-risk-and-performance-statistics/beta-and-market-relative-risk",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F11",
        "family": "Financial Risk and Performance Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-risk-and-performance-statistics/beta-and-market-relative-risk",
        "entry": "betaAndMarketRelativeRisk",
        "params": [
          "input"
        ],
        "exports": [
          "betaAndMarketRelativeRisk"
        ],
        "archetype": "record-transform",
        "signature": "betaAndMarketRelativeRisk(input)"
      },
      "api": {
        "summary": "Divides the sample covariance between a return series and its benchmark by the benchmark's sample variance.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `returns` and `benchmark`, two aligned non-empty lists of finite periodic returns, `frequency`, the number of periods per year, and `confidence`, the quantile level used when the loss series is prepared.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`beta` is the covariance over the benchmark variance, `marketVariance` is the benchmark's sample variance, and `covariance` is the sample covariance of the two series."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`returns` or `benchmark` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`returns` and `benchmark` differ in length, or hold fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`frequency` is zero or negative",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the benchmark is constant, so its sample variance is zero",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`confidence` is absent, or outside the range zero to one — the engine reads it for every topic from A04 onward, including those that never use it",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F11-A07.json",
        "call": "betaAndMarketRelativeRisk({\"returns\":[0.01,-0.02,0.015,-0.01,0.03],\"benchmark\":[0.008,-0.01,0.012,-0.006,0.02],\"frequency\":252,\"target\":0,\"confidence\":0.8,\"riskFree\":0.0001,\"weights\":[0.6,0.4],\"covarianceMatrix\":[[0.04,0.01],[0.01,0.09]]})",
        "args": [
          {
            "value": {
              "returns": [
                0.01,
                -0.02,
                0.015,
                -0.01,
                0.03
              ],
              "benchmark": [
                0.008,
                -0.01,
                0.012,
                -0.006,
                0.02
              ],
              "frequency": 252,
              "target": 0,
              "confidence": 0.8,
              "riskFree": 0.0001,
              "weights": [
                0.6,
                0.4
              ],
              "covarianceMatrix": [
                [
                  0.04,
                  0.01
                ],
                [
                  0.01,
                  0.09
                ]
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "beta": 1.5903307888040712,
          "marketVariance": 0.0001572
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: beta, marketVariance"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a07/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a07/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a07/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a07/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a07/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a07/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F11-A07",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Beta and Market-Relative Risk\"]\n    D --> E[\"Formula: β=Cov(r,m)/Var(m)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Basel Framework MAR33",
          "title": "Expected Shortfall",
          "author": "Basel Framework MAR33",
          "url": "https://www.bis.org/basel_framework/chapter/MAR/33.htm"
        },
        {
          "key": "William F. Sharpe",
          "title": "Mutual Fund Performance",
          "author": "William F. Sharpe",
          "url": "https://web.stanford.edu/~wfsharpe/art/mfpm/mfpm.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-risk-and-performance-statistics/beta-and-market-relative-risk/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-risk-and-performance-statistics/beta-and-market-relative-risk/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F11-A08",
      "name": "Sharpe, Sortino, and Information Ratio Intuition",
      "headline": null,
      "slug": "sharpe-sortino-and-information-ratio-intuition",
      "path": "foundations/financial-risk-and-performance-statistics/sharpe-sortino-and-information-ratio-intuition",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F11",
        "family": "Financial Risk and Performance Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-risk-and-performance-statistics/sharpe-sortino-and-information-ratio-intuition",
        "entry": "sharpeSortinoAndInformationRatioIntuition",
        "params": [
          "input"
        ],
        "exports": [
          "sharpeSortinoAndInformationRatioIntuition"
        ],
        "archetype": "record-transform",
        "signature": "sharpeSortinoAndInformationRatioIntuition(input)"
      },
      "api": {
        "summary": "Computes three reward-per-unit-of-risk ratios from the same series, each dividing an average by a different notion of risk.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `returns` and `benchmark`, two aligned non-empty lists of finite periodic returns, `frequency`, the number of periods per year, `riskFree`, the per-period risk-free rate, `target`, the level below which downside is measured, and `confidence`, used when the loss series is prepared.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`sharpe` is the mean excess return over its own sample standard deviation, `sortino` swaps that denominator for the downside deviation around `target`, and `informationRatio` divides the mean active return against the benchmark by the sample standard deviation of that active series."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`returns` or `benchmark` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`returns` and `benchmark` differ in length, or hold fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`frequency` is zero or negative",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the excess-return volatility, the downside deviation, or the active volatility is zero",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`confidence` is absent, or outside the range zero to one — the engine reads it for every topic from A04 onward, including those that never use it",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F11-A08.json",
        "call": "sharpeSortinoAndInformationRatioIntuition({\"returns\":[0.01,-0.02,0.015,-0.01,0.03],\"benchmark\":[0.008,-0.01,0.012,-0.006,0.02],\"frequency\":252,\"target\":0,\"confidence\":0.8,\"riskFree\":0.0001,\"weights\":[0.6,0.4],\"covarianceMatrix\":[[0.04,0.01],[0.01,0.09]]})",
        "args": [
          {
            "value": {
              "returns": [
                0.01,
                -0.02,
                0.015,
                -0.01,
                0.03
              ],
              "benchmark": [
                0.008,
                -0.01,
                0.012,
                -0.006,
                0.02
              ],
              "frequency": 252,
              "target": 0,
              "confidence": 0.8,
              "riskFree": 0.0001,
              "weights": [
                0.6,
                0.4
              ],
              "covarianceMatrix": [
                [
                  0.04,
                  0.01
                ],
                [
                  0.01,
                  0.09
                ]
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "sharpe": 0.245,
          "sortino": 0.49
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: sharpe, sortino"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a08/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a08/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a08/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a08/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a08/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a08/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F11-A08",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Sharpe, Sortino, and Information Ratio Intuition\"]\n    D --> E[\"Formula: Sharpe=mean(r−rf)/s(r−rf); Sortino=mean(r−rf)/downside; IR=mean(r−b)/s(r−b)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Basel Framework MAR33",
          "title": "Expected Shortfall",
          "author": "Basel Framework MAR33",
          "url": "https://www.bis.org/basel_framework/chapter/MAR/33.htm"
        },
        {
          "key": "William F. Sharpe",
          "title": "Mutual Fund Performance",
          "author": "William F. Sharpe",
          "url": "https://web.stanford.edu/~wfsharpe/art/mfpm/mfpm.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-risk-and-performance-statistics/sharpe-sortino-and-information-ratio-intuition/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-risk-and-performance-statistics/sharpe-sortino-and-information-ratio-intuition/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F11-A09",
      "name": "Active Return and Tracking Error",
      "headline": null,
      "slug": "active-return-and-tracking-error",
      "path": "foundations/financial-risk-and-performance-statistics/active-return-and-tracking-error",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F11",
        "family": "Financial Risk and Performance Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-risk-and-performance-statistics/active-return-and-tracking-error",
        "entry": "activeReturnAndTrackingError",
        "params": [
          "input"
        ],
        "exports": [
          "activeReturnAndTrackingError"
        ],
        "archetype": "record-transform",
        "signature": "activeReturnAndTrackingError(input)"
      },
      "api": {
        "summary": "Subtracts the benchmark from the portfolio period by period, then reports the average and the annualized volatility of that difference.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `returns` and `benchmark`, two aligned non-empty lists of finite periodic returns, `frequency`, the number of periods per year, and `confidence`, used when the loss series is prepared.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`activeReturns` holds the per-period differences, `averageActiveReturn` their mean, and `trackingError` their sample standard deviation times the square root of `frequency`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`returns` or `benchmark` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`returns` and `benchmark` differ in length, or hold fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`frequency` is zero or negative",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`confidence` is absent, or outside the range zero to one — the engine reads it for every topic from A04 onward, including those that never use it",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F11-A09.json",
        "call": "activeReturnAndTrackingError({\"returns\":[0.01,-0.02,0.015,-0.01,0.03],\"benchmark\":[0.008,-0.01,0.012,-0.006,0.02],\"frequency\":252,\"target\":0,\"confidence\":0.8,\"riskFree\":0.0001,\"weights\":[0.6,0.4],\"covarianceMatrix\":[[0.04,0.01],[0.01,0.09]]})",
        "args": [
          {
            "value": {
              "returns": [
                0.01,
                -0.02,
                0.015,
                -0.01,
                0.03
              ],
              "benchmark": [
                0.008,
                -0.01,
                0.012,
                -0.006,
                0.02
              ],
              "frequency": 252,
              "target": 0,
              "confidence": 0.8,
              "riskFree": 0.0001,
              "weights": [
                0.6,
                0.4
              ],
              "covarianceMatrix": [
                [
                  0.04,
                  0.01
                ],
                [
                  0.01,
                  0.09
                ]
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "activeReturns": [
            0.002,
            -0.01,
            0.002999999999999999,
            -0.004,
            0.009999999999999998
          ],
          "averageActiveReturn": 0.0001999999999999995
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: activeReturns, averageActiveReturn"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a09/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a09/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a09/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a09/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a09/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a09/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F11-A09",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Active Return and Tracking Error\"]\n    D --> E[\"Formula: aₜ=rₜ−bₜ; TE=s(a)√frequency\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Basel Framework MAR33",
          "title": "Expected Shortfall",
          "author": "Basel Framework MAR33",
          "url": "https://www.bis.org/basel_framework/chapter/MAR/33.htm"
        },
        {
          "key": "William F. Sharpe",
          "title": "Mutual Fund Performance",
          "author": "William F. Sharpe",
          "url": "https://web.stanford.edu/~wfsharpe/art/mfpm/mfpm.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-risk-and-performance-statistics/active-return-and-tracking-error/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-risk-and-performance-statistics/active-return-and-tracking-error/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F11-A10",
      "name": "Covariance Matrices, Portfolio Variance, and Diversification",
      "headline": null,
      "slug": "covariance-matrices-portfolio-variance-and-diversification",
      "path": "foundations/financial-risk-and-performance-statistics/covariance-matrices-portfolio-variance-and-diversification",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F11",
        "family": "Financial Risk and Performance Statistics",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/financial-risk-and-performance-statistics/covariance-matrices-portfolio-variance-and-diversification",
        "entry": "covarianceMatricesPortfolioVarianceAndDiversification",
        "params": [
          "input"
        ],
        "exports": [
          "covarianceMatricesPortfolioVarianceAndDiversification"
        ],
        "archetype": "record-transform",
        "signature": "covarianceMatricesPortfolioVarianceAndDiversification(input)"
      },
      "api": {
        "summary": "Combines portfolio weights with a covariance matrix into portfolio variance, and isolates the share of it that comes from the off-diagonal terms.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `returns` and `benchmark`, two aligned non-empty lists of finite periodic returns, `frequency`, `confidence`, plus `weights`, the asset weights summing to one, and `covarianceMatrix`, a square matrix of the same order as `weights`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`portfolioVariance` is the quadratic form of the weights against the matrix, floored at zero, `portfolioVolatility` its square root, `covarianceContribution` the amount by which it exceeds the sum of the squared weights times the diagonal variances, and `weightsSum` the total of the supplied weights."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`returns` or `benchmark` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`returns` and `benchmark` differ in length, or hold fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`frequency` is zero or negative",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`weights` and `covarianceMatrix` are not square-aligned, or `weights` does not sum to one within 1e-12",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the quadratic form comes out below -1e-12, so the matrix is not positive semi-definite",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`confidence` is absent, or outside the range zero to one — the engine reads it for every topic from A04 onward, including those that never use it",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n log n + k^2)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F11-A10.json",
        "call": "covarianceMatricesPortfolioVarianceAndDiversification({\"returns\":[0.01,-0.02,0.015,-0.01,0.03],\"benchmark\":[0.008,-0.01,0.012,-0.006,0.02],\"frequency\":252,\"target\":0,\"confidence\":0.8,\"riskFree\":0.0001,\"weights\":[0.6,0.4],\"covarianceMatrix\":[[0.04,0.01],[0.01,0.09]]})",
        "args": [
          {
            "value": {
              "returns": [
                0.01,
                -0.02,
                0.015,
                -0.01,
                0.03
              ],
              "benchmark": [
                0.008,
                -0.01,
                0.012,
                -0.006,
                0.02
              ],
              "frequency": 252,
              "target": 0,
              "confidence": 0.8,
              "riskFree": 0.0001,
              "weights": [
                0.6,
                0.4
              ],
              "covarianceMatrix": [
                [
                  0.04,
                  0.01
                ],
                [
                  0.01,
                  0.09
                ]
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "portfolioVariance": 0.033600000000000005,
          "portfolioVolatility": 0.18330302779823363
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: portfolioVariance, portfolioVolatility"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a10/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a10/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a10/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a10/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a10/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f11-a10/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F11-A10",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Covariance Matrices, Portfolio Variance, and Diversification\"]\n    D --> E[\"Formula: σp²=wᵀΣw; σp=√(wᵀΣw)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Basel Framework MAR33",
          "title": "Expected Shortfall",
          "author": "Basel Framework MAR33",
          "url": "https://www.bis.org/basel_framework/chapter/MAR/33.htm"
        },
        {
          "key": "William F. Sharpe",
          "title": "Mutual Fund Performance",
          "author": "William F. Sharpe",
          "url": "https://web.stanford.edu/~wfsharpe/art/mfpm/mfpm.htm"
        },
        {
          "key": "NIST/SEMATECH e-Handbook",
          "title": "Measures of Scale",
          "author": "NIST/SEMATECH e-Handbook",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/financial-risk-and-performance-statistics/covariance-matrices-portfolio-variance-and-diversification/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/financial-risk-and-performance-statistics/covariance-matrices-portfolio-variance-and-diversification/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F12-A01",
      "name": "Floating-Point Representation, Overflow, and Underflow",
      "headline": null,
      "slug": "floating-point-representation-overflow-and-underflow",
      "path": "foundations/statistical-computing-and-reproducibility/floating-point-representation-overflow-and-underflow",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F12",
        "family": "Statistical Computing and Reproducibility",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/statistical-computing-and-reproducibility/floating-point-representation-overflow-and-underflow",
        "entry": "floatingPointRepresentationOverflowAndUnderflow",
        "params": [
          "input"
        ],
        "exports": [
          "floatingPointRepresentationOverflowAndUnderflow"
        ],
        "archetype": "record-transform",
        "signature": "floatingPointRepresentationOverflowAndUnderflow(input)"
      },
      "api": {
        "summary": "Inspects one double-precision number: whether it is finite, how large one representable step at its magnitude is, and whether squaring it would stay inside a stated magnitude ceiling.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `floatingValue`, the number under inspection, and `maxSafeMagnitude`, the largest magnitude the caller is willing to reach. A non-empty `values` list of finite numbers must also be present; it is validated but not used here.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`isFinite` reports whether `floatingValue` is a finite number, `nextUp` is the next representable double above it, `ulp` is the spacing between adjacent doubles at its magnitude, and `overflowGuard` is true when the magnitude is at most the square root of `maxSafeMagnitude`. `overflowGuard` bounds only the overflow side of a squaring step: a value small enough to pass the guard can still square to zero, so underflow needs its own check."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F12-A01.json",
        "call": "floatingPointRepresentationOverflowAndUnderflow({\"values\":[1,2,3,4,5],\"floatingValue\":0.1,\"maxSafeMagnitude\":1.7976931348623157e+308,\"window\":3,\"rawValues\":[1,null,2,\"bad\",3],\"invalidPolicy\":\"drop-and-report\",\"seed\":42,\"sampleCount\":5,\"leftVector\":[{\"index\":\"A\",\"value\":1},{\"index\":\"B\",\"value\":2}],\"rightVector\":[{\"index\":\"B\",\"value\":20},{\"index\":\"C\",\"value\":30}],\"train\":[10,12,14,16],\"test\":[18,20],\"actual\":[1,2.0000001,3],\"expected\":[1,2,3]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "floatingValue": 0.1,
              "maxSafeMagnitude": 1.7976931348623157e+308,
              "window": 3,
              "rawValues": [
                1,
                null,
                2,
                "bad",
                3
              ],
              "invalidPolicy": "drop-and-report",
              "seed": 42,
              "sampleCount": 5,
              "leftVector": [
                {
                  "index": "A",
                  "value": 1
                },
                {
                  "index": "B",
                  "value": 2
                }
              ],
              "rightVector": [
                {
                  "index": "B",
                  "value": 20
                },
                {
                  "index": "C",
                  "value": 30
                }
              ],
              "train": [
                10,
                12,
                14,
                16
              ],
              "test": [
                18,
                20
              ],
              "actual": [
                1,
                2.0000001,
                3
              ],
              "expected": [
                1,
                2,
                3
              ]
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 18
            }
          }
        ],
        "output": {
          "isFinite": true,
          "ulp": 1.3877787807814457e-17,
          "nextUp": 0.10000000000000002,
          "overflowGuard": true
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: isFinite, ulp, nextUp, overflowGuard"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a01/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a01/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a01/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a01/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a01/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a01/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F12-A01",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Floating-Point Representation, Overflow, and Underflow\"]\n    D --> E[\"Formula: ulp(x) = spacing between adjacent doubles at |x|; nextUp(x) = next double above x\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "IEEE 754-2019",
          "title": "Floating-Point Arithmetic",
          "author": "IEEE 754-2019",
          "url": "https://standards.ieee.org/ieee/754/6210/"
        },
        {
          "key": "Python Documentation",
          "title": "math.fsum",
          "author": "Python Documentation",
          "url": "https://docs.python.org/3/library/math.html#math.fsum"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/statistical-computing-and-reproducibility/floating-point-representation-overflow-and-underflow/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/statistical-computing-and-reproducibility/floating-point-representation-overflow-and-underflow/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F12-A02",
      "name": "Stable Summation and Mean Calculation",
      "headline": null,
      "slug": "stable-summation-and-mean-calculation",
      "path": "foundations/statistical-computing-and-reproducibility/stable-summation-and-mean-calculation",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F12",
        "family": "Statistical Computing and Reproducibility",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/statistical-computing-and-reproducibility/stable-summation-and-mean-calculation",
        "entry": "stableSummationAndMeanCalculation",
        "params": [
          "input"
        ],
        "exports": [
          "stableSummationAndMeanCalculation"
        ],
        "archetype": "record-transform",
        "signature": "stableSummationAndMeanCalculation(input)"
      },
      "api": {
        "summary": "Adds a list twice, once straight left to right and once carrying a running compensation term, so the two totals can be put side by side.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `values`, a non-empty list of finite numbers to be summed.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`naiveSum` is the plain running total, `stableSum` the compensated one, `stableMean` that compensated total divided by the observation count, and `difference` the compensated total minus the naive one."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F12-A02.json",
        "call": "stableSummationAndMeanCalculation({\"values\":[10000000000000000,1,-10000000000000000,3],\"floatingValue\":0.1,\"maxSafeMagnitude\":1.7976931348623157e+308,\"window\":3,\"rawValues\":[1,null,2,\"bad\",3],\"invalidPolicy\":\"drop-and-report\",\"seed\":42,\"sampleCount\":5,\"leftVector\":[{\"index\":\"A\",\"value\":1},{\"index\":\"B\",\"value\":2}],\"rightVector\":[{\"index\":\"B\",\"value\":20},{\"index\":\"C\",\"value\":30}],\"train\":[10,12,14,16],\"test\":[18,20],\"actual\":[1,2.0000001,3],\"expected\":[1,2,3]})",
        "args": [
          {
            "value": {
              "values": [
                10000000000000000,
                1,
                -10000000000000000,
                3
              ],
              "floatingValue": 0.1,
              "maxSafeMagnitude": 1.7976931348623157e+308,
              "window": 3,
              "rawValues": [
                1,
                null,
                2,
                "bad",
                3
              ],
              "invalidPolicy": "drop-and-report",
              "seed": 42,
              "sampleCount": 5,
              "leftVector": [
                {
                  "index": "A",
                  "value": 1
                },
                {
                  "index": "B",
                  "value": 2
                }
              ],
              "rightVector": [
                {
                  "index": "B",
                  "value": 20
                },
                {
                  "index": "C",
                  "value": 30
                }
              ],
              "train": [
                10,
                12,
                14,
                16
              ],
              "test": [
                18,
                20
              ],
              "actual": [
                1,
                2.0000001,
                3
              ],
              "expected": [
                1,
                2,
                3
              ]
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 18
            }
          }
        ],
        "output": {
          "naiveSum": 3,
          "stableSum": 4
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: naiveSum, stableSum"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a02/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a02/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a02/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a02/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a02/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a02/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F12-A02",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Stable Summation and Mean Calculation\"]\n    D --> E[\"Formula: compensated/accurate sum; stable mean=stable sum/n\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "IEEE 754-2019",
          "title": "Floating-Point Arithmetic",
          "author": "IEEE 754-2019",
          "url": "https://standards.ieee.org/ieee/754/6210/"
        },
        {
          "key": "Python Documentation",
          "title": "math.fsum",
          "author": "Python Documentation",
          "url": "https://docs.python.org/3/library/math.html#math.fsum"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/statistical-computing-and-reproducibility/stable-summation-and-mean-calculation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/statistical-computing-and-reproducibility/stable-summation-and-mean-calculation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F12-A03",
      "name": "Stable Online Variance and Welford's Algorithm",
      "headline": null,
      "slug": "stable-online-variance-and-welford-s-algorithm",
      "path": "foundations/statistical-computing-and-reproducibility/stable-online-variance-and-welford-s-algorithm",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F12",
        "family": "Statistical Computing and Reproducibility",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/statistical-computing-and-reproducibility/stable-online-variance-and-welford-s-algorithm",
        "entry": "stableOnlineVarianceAndWelfordsAlgorithm",
        "params": [
          "input"
        ],
        "exports": [
          "stableOnlineVarianceAndWelfordsAlgorithm"
        ],
        "archetype": "record-transform",
        "signature": "stableOnlineVarianceAndWelfordsAlgorithm(input)"
      },
      "api": {
        "summary": "Runs Welford's single-pass update to produce the mean and sample variance without ever accumulating a sum of raw squares.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `values`, a list of at least two finite numbers.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`count` is the number of observations consumed, `mean` the running mean after the last of them, `m2` the accumulated sum of squared deviations, and `sampleVariance` that sum divided by `count` minus one."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`values` holds fewer than two observations",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F12-A03.json",
        "call": "stableOnlineVarianceAndWelfordsAlgorithm({\"values\":[1,2,3,4,5],\"floatingValue\":0.1,\"maxSafeMagnitude\":1.7976931348623157e+308,\"window\":3,\"rawValues\":[1,null,2,\"bad\",3],\"invalidPolicy\":\"drop-and-report\",\"seed\":42,\"sampleCount\":5,\"leftVector\":[{\"index\":\"A\",\"value\":1},{\"index\":\"B\",\"value\":2}],\"rightVector\":[{\"index\":\"B\",\"value\":20},{\"index\":\"C\",\"value\":30}],\"train\":[10,12,14,16],\"test\":[18,20],\"actual\":[1,2.0000001,3],\"expected\":[1,2,3]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "floatingValue": 0.1,
              "maxSafeMagnitude": 1.7976931348623157e+308,
              "window": 3,
              "rawValues": [
                1,
                null,
                2,
                "bad",
                3
              ],
              "invalidPolicy": "drop-and-report",
              "seed": 42,
              "sampleCount": 5,
              "leftVector": [
                {
                  "index": "A",
                  "value": 1
                },
                {
                  "index": "B",
                  "value": 2
                }
              ],
              "rightVector": [
                {
                  "index": "B",
                  "value": 20
                },
                {
                  "index": "C",
                  "value": 30
                }
              ],
              "train": [
                10,
                12,
                14,
                16
              ],
              "test": [
                18,
                20
              ],
              "actual": [
                1,
                2.0000001,
                3
              ],
              "expected": [
                1,
                2,
                3
              ]
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 18
            }
          }
        ],
        "output": {
          "count": 5,
          "mean": 3,
          "m2": 10,
          "sampleVariance": 2.5
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: count, mean, m2, sampleVariance"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a03/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a03/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a03/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a03/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a03/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a03/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F12-A03",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Stable Online Variance and Welford's Algorithm\"]\n    D --> E[\"Formula: n←n+1; δ=x−mean; mean←mean+δ/n; M2←M2+δ(x−mean)\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "IEEE 754-2019",
          "title": "Floating-Point Arithmetic",
          "author": "IEEE 754-2019",
          "url": "https://standards.ieee.org/ieee/754/6210/"
        },
        {
          "key": "Python Documentation",
          "title": "math.fsum",
          "author": "Python Documentation",
          "url": "https://docs.python.org/3/library/math.html#math.fsum"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/statistical-computing-and-reproducibility/stable-online-variance-and-welford-s-algorithm/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/statistical-computing-and-reproducibility/stable-online-variance-and-welford-s-algorithm/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F12-A04",
      "name": "Batch, Rolling, and Streaming Statistic Equivalence",
      "headline": null,
      "slug": "batch-rolling-and-streaming-statistic-equivalence",
      "path": "foundations/statistical-computing-and-reproducibility/batch-rolling-and-streaming-statistic-equivalence",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F12",
        "family": "Statistical Computing and Reproducibility",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/statistical-computing-and-reproducibility/batch-rolling-and-streaming-statistic-equivalence",
        "entry": "batchRollingAndStreamingStatisticEquivalence",
        "params": [
          "input"
        ],
        "exports": [
          "batchRollingAndStreamingStatisticEquivalence"
        ],
        "archetype": "record-transform",
        "signature": "batchRollingAndStreamingStatisticEquivalence(input)"
      },
      "api": {
        "summary": "Computes the same fixed-window mean two ways, by re-averaging each window slice and by a running add-and-drop sum, then checks that they agree.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `values`, a non-empty list of finite numbers, and `window`, the number of observations each average covers.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`batchMean` averages the whole series. `rollingMeans` recomputes each window from its slice and `streamingMeans` maintains a running sum; `equivalent` is true when every matching pair agrees to within 1e-12."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`window` is not an integer between one and the observation count",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n * w)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F12-A04.json",
        "call": "batchRollingAndStreamingStatisticEquivalence({\"values\":[1,2,3,4,5],\"floatingValue\":0.1,\"maxSafeMagnitude\":1.7976931348623157e+308,\"window\":3,\"rawValues\":[1,null,2,\"bad\",3],\"invalidPolicy\":\"drop-and-report\",\"seed\":42,\"sampleCount\":5,\"leftVector\":[{\"index\":\"A\",\"value\":1},{\"index\":\"B\",\"value\":2}],\"rightVector\":[{\"index\":\"B\",\"value\":20},{\"index\":\"C\",\"value\":30}],\"train\":[10,12,14,16],\"test\":[18,20],\"actual\":[1,2.0000001,3],\"expected\":[1,2,3]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "floatingValue": 0.1,
              "maxSafeMagnitude": 1.7976931348623157e+308,
              "window": 3,
              "rawValues": [
                1,
                null,
                2,
                "bad",
                3
              ],
              "invalidPolicy": "drop-and-report",
              "seed": 42,
              "sampleCount": 5,
              "leftVector": [
                {
                  "index": "A",
                  "value": 1
                },
                {
                  "index": "B",
                  "value": 2
                }
              ],
              "rightVector": [
                {
                  "index": "B",
                  "value": 20
                },
                {
                  "index": "C",
                  "value": 30
                }
              ],
              "train": [
                10,
                12,
                14,
                16
              ],
              "test": [
                18,
                20
              ],
              "actual": [
                1,
                2.0000001,
                3
              ],
              "expected": [
                1,
                2,
                3
              ]
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 18
            }
          }
        ],
        "output": {
          "batchMean": 3,
          "rollingMeans": [
            2,
            3,
            4
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: batchMean, rollingMeans"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a04/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a04/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a04/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a04/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a04/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a04/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F12-A04",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Batch, Rolling, and Streaming Statistic Equivalence\"]\n    D --> E[\"Formula: rollingₜ=aggregate(xₜ₋w+1…xₜ); compare outputs within tolerance\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "IEEE 754-2019",
          "title": "Floating-Point Arithmetic",
          "author": "IEEE 754-2019",
          "url": "https://standards.ieee.org/ieee/754/6210/"
        },
        {
          "key": "Python Documentation",
          "title": "math.fsum",
          "author": "Python Documentation",
          "url": "https://docs.python.org/3/library/math.html#math.fsum"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/statistical-computing-and-reproducibility/batch-rolling-and-streaming-statistic-equivalence/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/statistical-computing-and-reproducibility/batch-rolling-and-streaming-statistic-equivalence/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F12-A05",
      "name": "Missing, Infinite, Invalid, and Unsupported-State Policies",
      "headline": null,
      "slug": "missing-infinite-invalid-and-unsupported-state-policies",
      "path": "foundations/statistical-computing-and-reproducibility/missing-infinite-invalid-and-unsupported-state-policies",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F12",
        "family": "Statistical Computing and Reproducibility",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/statistical-computing-and-reproducibility/missing-infinite-invalid-and-unsupported-state-policies",
        "entry": "missingInfiniteInvalidAndUnsupportedStatePolicies",
        "params": [
          "input"
        ],
        "exports": [
          "missingInfiniteInvalidAndUnsupportedStatePolicies"
        ],
        "archetype": "record-transform",
        "signature": "missingInfiniteInvalidAndUnsupportedStatePolicies(input)"
      },
      "api": {
        "summary": "Screens a mixed raw list down to the entries that are genuinely finite numbers and reports how many were turned away.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `rawValues`, the unscreened list which may hold nulls, strings or non-finite numbers, and `invalidPolicy`, a label describing what the caller intends to do about them. A non-empty `values` list of finite numbers must also be present; it is validated but not screened.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`accepted` holds the surviving finite numbers in their original order, `rejectedCount` how many were dropped, `policy` echoes `invalidPolicy`, and `status` is `ok` when anything survived and `unsupported` when nothing did."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F12-A05.json",
        "call": "missingInfiniteInvalidAndUnsupportedStatePolicies({\"values\":[1,2,3,4,5],\"floatingValue\":0.1,\"maxSafeMagnitude\":1.7976931348623157e+308,\"window\":3,\"rawValues\":[1,null,2,\"bad\",3],\"invalidPolicy\":\"drop-and-report\",\"seed\":42,\"sampleCount\":5,\"leftVector\":[{\"index\":\"A\",\"value\":1},{\"index\":\"B\",\"value\":2}],\"rightVector\":[{\"index\":\"B\",\"value\":20},{\"index\":\"C\",\"value\":30}],\"train\":[10,12,14,16],\"test\":[18,20],\"actual\":[1,2.0000001,3],\"expected\":[1,2,3]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "floatingValue": 0.1,
              "maxSafeMagnitude": 1.7976931348623157e+308,
              "window": 3,
              "rawValues": [
                1,
                null,
                2,
                "bad",
                3
              ],
              "invalidPolicy": "drop-and-report",
              "seed": 42,
              "sampleCount": 5,
              "leftVector": [
                {
                  "index": "A",
                  "value": 1
                },
                {
                  "index": "B",
                  "value": 2
                }
              ],
              "rightVector": [
                {
                  "index": "B",
                  "value": 20
                },
                {
                  "index": "C",
                  "value": 30
                }
              ],
              "train": [
                10,
                12,
                14,
                16
              ],
              "test": [
                18,
                20
              ],
              "actual": [
                1,
                2.0000001,
                3
              ],
              "expected": [
                1,
                2,
                3
              ]
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 18
            }
          }
        ],
        "output": {
          "accepted": [
            1,
            2,
            3
          ],
          "rejectedCount": 2
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: accepted, rejectedCount"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a05/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a05/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a05/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a05/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a05/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a05/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F12-A05",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Missing, Infinite, Invalid, and Unsupported-State Policies\"]\n    D --> E[\"Formula: accept finite numeric values under the package policy; otherwise reject with reason\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "IEEE 754-2019",
          "title": "Floating-Point Arithmetic",
          "author": "IEEE 754-2019",
          "url": "https://standards.ieee.org/ieee/754/6210/"
        },
        {
          "key": "Python Documentation",
          "title": "math.fsum",
          "author": "Python Documentation",
          "url": "https://docs.python.org/3/library/math.html#math.fsum"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/statistical-computing-and-reproducibility/missing-infinite-invalid-and-unsupported-state-policies/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/statistical-computing-and-reproducibility/missing-infinite-invalid-and-unsupported-state-policies/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F12-A06",
      "name": "Pseudorandom Numbers, Seeds, and Reproducibility",
      "headline": null,
      "slug": "pseudorandom-numbers-seeds-and-reproducibility",
      "path": "foundations/statistical-computing-and-reproducibility/pseudorandom-numbers-seeds-and-reproducibility",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F12",
        "family": "Statistical Computing and Reproducibility",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/statistical-computing-and-reproducibility/pseudorandom-numbers-seeds-and-reproducibility",
        "entry": "pseudorandomNumbersSeedsAndReproducibility",
        "params": [
          "input"
        ],
        "exports": [
          "pseudorandomNumbersSeedsAndReproducibility"
        ],
        "archetype": "record-transform",
        "signature": "pseudorandomNumbersSeedsAndReproducibility(input)"
      },
      "api": {
        "summary": "Draws a run of unit-interval numbers from a seeded linear congruential generator, so the same seed always replays the same stream.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `seed`, the 32-bit starting state, and `sampleCount`, how many draws to take. A non-empty `values` list of finite numbers must also be present; it is validated but not used here.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`samples` holds the draws, each in the half-open interval from zero to one, `seed` is echoed back, `finalState` is the generator state left after the last draw, and `reproducible` is always true."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`sampleCount` is below one",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F12-A06.json",
        "call": "pseudorandomNumbersSeedsAndReproducibility({\"values\":[1,2,3,4,5],\"floatingValue\":0.1,\"maxSafeMagnitude\":1.7976931348623157e+308,\"window\":3,\"rawValues\":[1,null,2,\"bad\",3],\"invalidPolicy\":\"drop-and-report\",\"seed\":42,\"sampleCount\":5,\"leftVector\":[{\"index\":\"A\",\"value\":1},{\"index\":\"B\",\"value\":2}],\"rightVector\":[{\"index\":\"B\",\"value\":20},{\"index\":\"C\",\"value\":30}],\"train\":[10,12,14,16],\"test\":[18,20],\"actual\":[1,2.0000001,3],\"expected\":[1,2,3]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "floatingValue": 0.1,
              "maxSafeMagnitude": 1.7976931348623157e+308,
              "window": 3,
              "rawValues": [
                1,
                null,
                2,
                "bad",
                3
              ],
              "invalidPolicy": "drop-and-report",
              "seed": 42,
              "sampleCount": 5,
              "leftVector": [
                {
                  "index": "A",
                  "value": 1
                },
                {
                  "index": "B",
                  "value": 2
                }
              ],
              "rightVector": [
                {
                  "index": "B",
                  "value": 20
                },
                {
                  "index": "C",
                  "value": 30
                }
              ],
              "train": [
                10,
                12,
                14,
                16
              ],
              "test": [
                18,
                20
              ],
              "actual": [
                1,
                2.0000001,
                3
              ],
              "expected": [
                1,
                2,
                3
              ]
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 18
            }
          }
        ],
        "output": {
          "samples": [
            0.2523451747838408,
            0.08812504541128874,
            0.5772811982315034,
            0.22255426598712802,
            0.37566019711084664
          ],
          "seed": 42
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: samples, seed"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a06/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a06/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a06/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a06/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a06/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a06/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F12-A06",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Pseudorandom Numbers, Seeds, and Reproducibility\"]\n    D --> E[\"Formula: LCG stateₜ₊₁=(1664525·stateₜ+1013904223) mod 2³²\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "IEEE 754-2019",
          "title": "Floating-Point Arithmetic",
          "author": "IEEE 754-2019",
          "url": "https://standards.ieee.org/ieee/754/6210/"
        },
        {
          "key": "Python Documentation",
          "title": "math.fsum",
          "author": "Python Documentation",
          "url": "https://docs.python.org/3/library/math.html#math.fsum"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/statistical-computing-and-reproducibility/pseudorandom-numbers-seeds-and-reproducibility/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/statistical-computing-and-reproducibility/pseudorandom-numbers-seeds-and-reproducibility/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F12-A07",
      "name": "Vectorization, Index Alignment, and Shape Safety",
      "headline": null,
      "slug": "vectorization-index-alignment-and-shape-safety",
      "path": "foundations/statistical-computing-and-reproducibility/vectorization-index-alignment-and-shape-safety",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F12",
        "family": "Statistical Computing and Reproducibility",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/statistical-computing-and-reproducibility/vectorization-index-alignment-and-shape-safety",
        "entry": "vectorizationIndexAlignmentAndShapeSafety",
        "params": [
          "input"
        ],
        "exports": [
          "vectorizationIndexAlignmentAndShapeSafety"
        ],
        "archetype": "record-transform",
        "signature": "vectorizationIndexAlignmentAndShapeSafety(input)"
      },
      "api": {
        "summary": "Inner-joins two labelled vectors on their index field and reports what each side lost in the process.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `leftVector` and `rightVector`, each a list of records carrying an `index` label and a numeric `value`. A non-empty `values` list of finite numbers must also be present; it is validated but not joined.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`aligned` holds one record per shared label with `index`, `left` and `right`, keeping the left vector's order. `alignedCount` sizes it, and `droppedLeft` and `droppedRight` are each side's length minus that count."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F12-A07.json",
        "call": "vectorizationIndexAlignmentAndShapeSafety({\"values\":[1,2,3,4,5],\"floatingValue\":0.1,\"maxSafeMagnitude\":1.7976931348623157e+308,\"window\":3,\"rawValues\":[1,null,2,\"bad\",3],\"invalidPolicy\":\"drop-and-report\",\"seed\":42,\"sampleCount\":5,\"leftVector\":[{\"index\":\"A\",\"value\":1},{\"index\":\"B\",\"value\":2}],\"rightVector\":[{\"index\":\"B\",\"value\":20},{\"index\":\"C\",\"value\":30}],\"train\":[10,12,14,16],\"test\":[18,20],\"actual\":[1,2.0000001,3],\"expected\":[1,2,3]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "floatingValue": 0.1,
              "maxSafeMagnitude": 1.7976931348623157e+308,
              "window": 3,
              "rawValues": [
                1,
                null,
                2,
                "bad",
                3
              ],
              "invalidPolicy": "drop-and-report",
              "seed": 42,
              "sampleCount": 5,
              "leftVector": [
                {
                  "index": "A",
                  "value": 1
                },
                {
                  "index": "B",
                  "value": 2
                }
              ],
              "rightVector": [
                {
                  "index": "B",
                  "value": 20
                },
                {
                  "index": "C",
                  "value": 30
                }
              ],
              "train": [
                10,
                12,
                14,
                16
              ],
              "test": [
                18,
                20
              ],
              "actual": [
                1,
                2.0000001,
                3
              ],
              "expected": [
                1,
                2,
                3
              ]
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 18
            }
          }
        ],
        "output": {
          "aligned": [
            {
              "index": "B",
              "left": 2,
              "right": 20
            }
          ],
          "alignedCount": 1
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: aligned, alignedCount"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a07/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a07/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a07/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a07/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a07/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a07/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F12-A07",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Vectorization, Index Alignment, and Shape Safety\"]\n    D --> E[\"Formula: align by declared index; calculate only matched pairs; report dropped labels\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "IEEE 754-2019",
          "title": "Floating-Point Arithmetic",
          "author": "IEEE 754-2019",
          "url": "https://standards.ieee.org/ieee/754/6210/"
        },
        {
          "key": "Python Documentation",
          "title": "math.fsum",
          "author": "Python Documentation",
          "url": "https://docs.python.org/3/library/math.html#math.fsum"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/statistical-computing-and-reproducibility/vectorization-index-alignment-and-shape-safety/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/statistical-computing-and-reproducibility/vectorization-index-alignment-and-shape-safety/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F12-A08",
      "name": "Leakage-Free Fitting, Scaling, and Preprocessing",
      "headline": null,
      "slug": "leakage-free-fitting-scaling-and-preprocessing",
      "path": "foundations/statistical-computing-and-reproducibility/leakage-free-fitting-scaling-and-preprocessing",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F12",
        "family": "Statistical Computing and Reproducibility",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/statistical-computing-and-reproducibility/leakage-free-fitting-scaling-and-preprocessing",
        "entry": "leakageFreeFittingScalingAndPreprocessing",
        "params": [
          "input"
        ],
        "exports": [
          "leakageFreeFittingScalingAndPreprocessing"
        ],
        "archetype": "record-transform",
        "signature": "leakageFreeFittingScalingAndPreprocessing(input)"
      },
      "api": {
        "summary": "Fits a standardizing centre and scale on the training split alone, then applies that one transform to both splits.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `train`, at least two finite numbers to fit on, and `test`, the held-out finite numbers to transform. A non-empty `values` list of finite numbers must also be present; it is validated but not used here.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`fittedMean` and `fittedScale` are the training mean and sample standard deviation, `transformedTrain` and `transformedTest` are both splits centred and scaled by those two figures, and `fitUsedTestData` is always false."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`train` holds fewer than two observations",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the training data is constant, so its sample standard deviation is zero",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F12-A08.json",
        "call": "leakageFreeFittingScalingAndPreprocessing({\"values\":[1,2,3,4,5],\"floatingValue\":0.1,\"maxSafeMagnitude\":1.7976931348623157e+308,\"window\":3,\"rawValues\":[1,null,2,\"bad\",3],\"invalidPolicy\":\"drop-and-report\",\"seed\":42,\"sampleCount\":5,\"leftVector\":[{\"index\":\"A\",\"value\":1},{\"index\":\"B\",\"value\":2}],\"rightVector\":[{\"index\":\"B\",\"value\":20},{\"index\":\"C\",\"value\":30}],\"train\":[10,12,14,16],\"test\":[18,20],\"actual\":[1,2.0000001,3],\"expected\":[1,2,3]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "floatingValue": 0.1,
              "maxSafeMagnitude": 1.7976931348623157e+308,
              "window": 3,
              "rawValues": [
                1,
                null,
                2,
                "bad",
                3
              ],
              "invalidPolicy": "drop-and-report",
              "seed": 42,
              "sampleCount": 5,
              "leftVector": [
                {
                  "index": "A",
                  "value": 1
                },
                {
                  "index": "B",
                  "value": 2
                }
              ],
              "rightVector": [
                {
                  "index": "B",
                  "value": 20
                },
                {
                  "index": "C",
                  "value": 30
                }
              ],
              "train": [
                10,
                12,
                14,
                16
              ],
              "test": [
                18,
                20
              ],
              "actual": [
                1,
                2.0000001,
                3
              ],
              "expected": [
                1,
                2,
                3
              ]
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 18
            }
          }
        ],
        "output": {
          "fittedMean": 13,
          "fittedScale": 2.581988897471611
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: fittedMean, fittedScale"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a08/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a08/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a08/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a08/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a08/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a08/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F12-A08",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Leakage-Free Fitting, Scaling, and Preprocessing\"]\n    D --> E[\"Formula: μtrain=mean(train); strain=sd(train); z=(x−μtrain)/strain\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "IEEE 754-2019",
          "title": "Floating-Point Arithmetic",
          "author": "IEEE 754-2019",
          "url": "https://standards.ieee.org/ieee/754/6210/"
        },
        {
          "key": "Python Documentation",
          "title": "math.fsum",
          "author": "Python Documentation",
          "url": "https://docs.python.org/3/library/math.html#math.fsum"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/statistical-computing-and-reproducibility/leakage-free-fitting-scaling-and-preprocessing/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/statistical-computing-and-reproducibility/leakage-free-fitting-scaling-and-preprocessing/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F12-A09",
      "name": "Fixtures, Numerical Tolerances, and Property Tests",
      "headline": null,
      "slug": "fixtures-numerical-tolerances-and-property-tests",
      "path": "foundations/statistical-computing-and-reproducibility/fixtures-numerical-tolerances-and-property-tests",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F12",
        "family": "Statistical Computing and Reproducibility",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/statistical-computing-and-reproducibility/fixtures-numerical-tolerances-and-property-tests",
        "entry": "fixturesNumericalTolerancesAndPropertyTests",
        "params": [
          "input"
        ],
        "exports": [
          "fixturesNumericalTolerancesAndPropertyTests"
        ],
        "archetype": "record-transform",
        "signature": "fixturesNumericalTolerancesAndPropertyTests(input)"
      },
      "api": {
        "summary": "Compares an actual vector against an expected one under an absolute tolerance, the way a fixture check does.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `actual` and `expected`, two aligned lists of finite numbers, and `tolerance`, the largest absolute error still counted as a match. A non-empty `values` list of finite numbers must also be present; it is validated but not compared.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`allClose` is true when every absolute error is within `tolerance`, `maximumError` is the largest of them, `tolerance` is echoed back, and `properties` carries `finite` and `sameLength`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`actual` and `expected` have different lengths",
            "behaviour": "throws RangeError"
          },
          {
            "when": "`tolerance` is negative",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F12-A09.json",
        "call": "fixturesNumericalTolerancesAndPropertyTests({\"values\":[1,2,3,4,5],\"floatingValue\":0.1,\"maxSafeMagnitude\":1.7976931348623157e+308,\"window\":3,\"rawValues\":[1,null,2,\"bad\",3],\"invalidPolicy\":\"drop-and-report\",\"seed\":42,\"sampleCount\":5,\"leftVector\":[{\"index\":\"A\",\"value\":1},{\"index\":\"B\",\"value\":2}],\"rightVector\":[{\"index\":\"B\",\"value\":20},{\"index\":\"C\",\"value\":30}],\"train\":[10,12,14,16],\"test\":[18,20],\"actual\":[1,2.0000001,3],\"expected\":[1,2,3]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "floatingValue": 0.1,
              "maxSafeMagnitude": 1.7976931348623157e+308,
              "window": 3,
              "rawValues": [
                1,
                null,
                2,
                "bad",
                3
              ],
              "invalidPolicy": "drop-and-report",
              "seed": 42,
              "sampleCount": 5,
              "leftVector": [
                {
                  "index": "A",
                  "value": 1
                },
                {
                  "index": "B",
                  "value": 2
                }
              ],
              "rightVector": [
                {
                  "index": "B",
                  "value": 20
                },
                {
                  "index": "C",
                  "value": 30
                }
              ],
              "train": [
                10,
                12,
                14,
                16
              ],
              "test": [
                18,
                20
              ],
              "actual": [
                1,
                2.0000001,
                3
              ],
              "expected": [
                1,
                2,
                3
              ]
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 18
            }
          }
        ],
        "output": {
          "allClose": true,
          "maximumError": 9.999999983634211e-8
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: allClose, maximumError"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a09/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a09/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a09/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a09/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a09/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a09/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F12-A09",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Fixtures, Numerical Tolerances, and Property Tests\"]\n    D --> E[\"Formula: allClose iff |actual−expected|≤tolerance for every aligned value\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "IEEE 754-2019",
          "title": "Floating-Point Arithmetic",
          "author": "IEEE 754-2019",
          "url": "https://standards.ieee.org/ieee/754/6210/"
        },
        {
          "key": "Python Documentation",
          "title": "math.fsum",
          "author": "Python Documentation",
          "url": "https://docs.python.org/3/library/math.html#math.fsum"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/statistical-computing-and-reproducibility/fixtures-numerical-tolerances-and-property-tests/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/statistical-computing-and-reproducibility/fixtures-numerical-tolerances-and-property-tests/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D00-F12-A10",
      "name": "Reproducible Analysis, Metadata, and Audit Trails",
      "headline": null,
      "slug": "reproducible-analysis-metadata-and-audit-trails",
      "path": "foundations/statistical-computing-and-reproducibility/reproducible-analysis-metadata-and-audit-trails",
      "taxonomy": {
        "domainId": "D00",
        "domain": "Financial Mathematics, Statistics, and Data Foundations",
        "familyId": "D00-F12",
        "family": "Statistical Computing and Reproducibility",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/foundations/statistical-computing-and-reproducibility/reproducible-analysis-metadata-and-audit-trails",
        "entry": "reproducibleAnalysisMetadataAndAuditTrails",
        "params": [
          "input"
        ],
        "exports": [
          "reproducibleAnalysisMetadataAndAuditTrails"
        ],
        "archetype": "record-transform",
        "signature": "reproducibleAnalysisMetadataAndAuditTrails(input)"
      },
      "api": {
        "summary": "Serializes a run's inputs, method, version and seed into a deterministic JSON string and fingerprints it with a 32-bit FNV-1a hash.",
        "params": [
          {
            "name": "input",
            "type": "D00Input",
            "required": true,
            "description": "Reads `auditInputs`, `method`, `version` and `seed`, the four fields that identify a run. A non-empty `values` list of finite numbers must also be present; it is validated but not recorded.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "D00Output",
          "description": "`canonicalJson` is the four fields serialized with their top-level keys in sorted order, and because that sorted key list is used as the serializer's replacer, nested objects such as `inputs` come out empty. `fnv1a32` is the hash of that string as eight lowercase hex digits, and `metadataComplete` is true when none of the four fields is null or undefined."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`values` is absent, empty, or holds a non-finite number",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D00-F12-A10.json",
        "call": "reproducibleAnalysisMetadataAndAuditTrails({\"values\":[1,2,3,4,5],\"floatingValue\":0.1,\"maxSafeMagnitude\":1.7976931348623157e+308,\"window\":3,\"rawValues\":[1,null,2,\"bad\",3],\"invalidPolicy\":\"drop-and-report\",\"seed\":42,\"sampleCount\":5,\"leftVector\":[{\"index\":\"A\",\"value\":1},{\"index\":\"B\",\"value\":2}],\"rightVector\":[{\"index\":\"B\",\"value\":20},{\"index\":\"C\",\"value\":30}],\"train\":[10,12,14,16],\"test\":[18,20],\"actual\":[1,2.0000001,3],\"expected\":[1,2,3]})",
        "args": [
          {
            "value": {
              "values": [
                1,
                2,
                3,
                4,
                5
              ],
              "floatingValue": 0.1,
              "maxSafeMagnitude": 1.7976931348623157e+308,
              "window": 3,
              "rawValues": [
                1,
                null,
                2,
                "bad",
                3
              ],
              "invalidPolicy": "drop-and-report",
              "seed": 42,
              "sampleCount": 5,
              "leftVector": [
                {
                  "index": "A",
                  "value": 1
                },
                {
                  "index": "B",
                  "value": 2
                }
              ],
              "rightVector": [
                {
                  "index": "B",
                  "value": 20
                },
                {
                  "index": "C",
                  "value": 30
                }
              ],
              "train": [
                10,
                12,
                14,
                16
              ],
              "test": [
                18,
                20
              ],
              "actual": [
                1,
                2.0000001,
                3
              ],
              "expected": [
                1,
                2,
                3
              ]
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 18
            }
          }
        ],
        "output": {
          "metadataComplete": true
        },
        "outputElided": null,
        "outputShape": "object with 1 field: metadataComplete"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a10/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a10/static/calculation-ledger.svg"
          },
          {
            "file": "concept-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a10/static/concept-anatomy.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a10/static/failure-boundary.svg"
          },
          {
            "file": "method-map.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a10/static/method-map.svg"
          },
          {
            "file": "scenario-contrast.svg",
            "url": "https://thefintechbuilder.com/content/d00-f12-a10/static/scenario-contrast.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning flow — D00-F12-A10",
            "source": "flowchart LR\n    A[\"Synthetic input + metadata\"] --> B{\"Contract valid?\"}\n    B -->|No| C[\"Reject or route with reason\"]\n    B -->|Yes| D[\"Apply Reproducible Analysis, Metadata, and Audit Trails\"]\n    D --> E[\"Formula: canonical JSON → FNV-1a 32-bit teaching checksum\"]\n    E --> F[\"Verified fixture output\"]\n    F --> G{\"Interpretation within boundary?\"}\n    G -->|Yes| H[\"Report value + convention + audit\"]\n    G -->|No| I[\"Add companion view or narrower claim\"]"
          }
        ]
      },
      "references": [
        {
          "key": "IEEE 754-2019",
          "title": "Floating-Point Arithmetic",
          "author": "IEEE 754-2019",
          "url": "https://standards.ieee.org/ieee/754/6210/"
        },
        {
          "key": "Python Documentation",
          "title": "math.fsum",
          "author": "Python Documentation",
          "url": "https://docs.python.org/3/library/math.html#math.fsum"
        },
        {
          "key": "NumPy Documentation",
          "title": "Random Sampling",
          "author": "NumPy Documentation",
          "url": "https://numpy.org/doc/stable/reference/random/index.html"
        },
        {
          "key": "scikit-learn",
          "title": "Common Pitfalls and Recommended Practices",
          "author": "scikit-learn",
          "url": "https://scikit-learn.org/stable/common_pitfalls.html"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/statistical-computing-and-reproducibility/reproducible-analysis-metadata-and-audit-trails/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/foundations/statistical-computing-and-reproducibility/reproducible-analysis-metadata-and-audit-trails/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "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. It is **not causal** — it uses a quote from after the target, so it belongs in research and never in a live path. No accuracy advantage over carry-forward is claimed or measured here.",
        "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, as a positive whole number of milliseconds. The boundary is inclusive: a bracket whose width equals the limit is eligible.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "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 not a positive integer (zero, negative, or fractional)",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n log n + m log n) in the Python reference: sorting each partition dominates ingest, and each target resolves its bracket by binary search. The TypeScript reference scans for the bracket instead, so it is O(n log n + m n).",
          "space": "O(n + 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. All-refresh sampling is one established construction for non-synchronous observations, not a neutral or sufficient remedy for correlation bias.",
        "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. At least two distinct non-empty names are required.",
            "constraints": {
              "min_distinct_names": 2
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "maxStalenessMs",
            "type": "number",
            "required": true,
            "description": "How old any instrument's selected event may be at a refresh time, as a non-negative whole number of milliseconds. Equality is accepted; a row above the limit is flagged `stale` rather than repaired or dropped.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "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 holds fewer than two distinct names, or any name is empty",
            "behaviour": "throws"
          },
          {
            "when": "maxStalenessMs is not a non-negative integer",
            "behaviour": "throws"
          },
          {
            "when": "an observation fails validation: missing field, unknown instrument, empty partition or record_id, negative or non-integer revision, non-finite value, event_time after available_at, non-contiguous or non-causal revision, or two record_ids sharing an instrument and event_time",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n log n) to validate and order n arrivals, plus O(r * n) for the barrier loop in these reference implementations, where r is the number of emitted rows; the loop re-filters the partition at each barrier for clarity. A production implementation using monotone cursors and indexed revision state can do the same work in linear passes.",
          "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",
          "evaluatedAt"
        ],
        "exports": [
          "classifyIntervalPair",
          "diagnoseAsynchronousReturnAlignment"
        ],
        "archetype": "row-classify",
        "signature": "classifyIntervalPair(left, right, evaluatedAt)"
      },
      "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
          },
          {
            "name": "evaluatedAt",
            "type": "string",
            "required": false,
            "description": "Decision time, ISO 8601. Omitted, no evaluation cutoff is applied and availability is reported without being judged against a moment.",
            "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",
          "validTime"
        ],
        "exports": [
          "asOfSnapshot",
          "leakageAudit"
        ],
        "archetype": "snapshot-evaluate",
        "signature": "asOfSnapshot(records, knowledgeTime, validTime)"
      },
      "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
          },
          {
            "name": "validTime",
            "type": "string",
            "required": false,
            "description": "Valid-time cutoff, ISO 8601. Defaults to `knowledgeTime`, which collapses the bitemporal query to a single instant on both axes.",
            "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": "verified",
        "via": "D"
      },
      "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": "verified",
        "via": "D"
      },
      "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": [
          {
            "file": "system-flow.md",
            "caption": "Trade-and-Quote Event Normalization system flow",
            "source": "flowchart LR\n    A[\"Preserve integer atoms and scale beside decimal prices.\"] --> B[\"Preserve supplied fields without inventing trade side.\"]\n    B --> C{\"Safe to publish?\"}\n    C -->|\"yes\"| D[\"Compute receive minus event time per record.\"]\n    C -->|\"no\"| E[\"Do not sort independent venues by timestamp and call the result exchange causality.\"]\n    D --> F[\"Publish versioned normalized events\"]\n    F --> G[\"Route to the named D11 measurement\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "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": [
          {
            "file": "system-flow.md",
            "caption": "Level-2 Snapshot-and-Delta Reconstruction system flow",
            "source": "flowchart LR\n    A[\"Start with the first sequence after the anchor.\"] --> B[\"Write absolute quantity at one side/price key.\"]\n    B --> C{\"Safe to publish?\"}\n    C -->|\"yes\"| D[\"Treat quantity zero as deletion.\"]\n    C -->|\"no\"| E[\"A sorted-looking book is not current if one sequence is missing.\"]\n    D --> F[\"Publish current sorted L2 book\"]\n    F --> G[\"Route to the named D11 measurement\"]"
          }
        ]
      },
      "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, so each visible order keeps its own identity and quantity through add, reduce, execute, delete, and replace. The emitted `priority_rank` is the insertion order of visible identities within the reconstructed stream. It is not a venue queue position and carries no information about hidden liquidity, participant identity, or exchange-internal priority changes that the feed does not report.",
        "params": [
          {
            "name": "snapshot_orders",
            "type": "L3Order[]",
            "required": true,
            "description": "Individual resting orders with their identifiers, side, integer price ticks and quantity. Snapshot order IDs must be non-empty and unique; their listed order fixes the initial insertion ranks. The second argument holds `snapshot_sequence`, the sequence number the snapshot is anchored at — events at or below it are skipped and the next event must be exactly one greater — and `events`, the contiguous run of lifecycle messages `add`, `reduce`, `execute`, `delete` and `replace`, each carrying a `sequence` and an `order_id`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ snapshot_sequence, last_sequence, order_count, event_count, action_counts, orders, bids, asks, state }",
          "description": "Surviving visible orders sorted by `priority_rank`, the price levels aggregated from them, per-action counters, and the sequence span covered. `state` is `current`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a reduce, execute, delete or replace references an order id not in the book",
            "behaviour": "throws"
          },
          {
            "when": "an event sequence skips the expected next value",
            "behaviour": "throws"
          },
          {
            "when": "a reduction exceeds the resting quantity, an add reuses a live order id, or the action is unrecognised",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(s + e + k log k), for s snapshot orders, e events and k surviving orders: one pass applies the stream, then the survivors are sorted by insertion rank and their price levels are sorted",
          "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": "verified",
        "via": "D"
      },
      "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": [
          {
            "file": "system-flow.md",
            "caption": "Level-3 Order-by-Order Reconstruction system flow",
            "source": "flowchart LR\n    A[\"Load unique snapshot identities.\"] --> B[\"Apply add/reduce/execute/delete to exact IDs.\"]\n    B --> C{\"Safe to publish?\"}\n    C -->|\"yes\"| D[\"Remove zero or deleted orders.\"]\n    C -->|\"no\"| E[\"Feed order identity is not participant identity or proof of hidden priority.\"]\n    D --> F[\"Publish current L3 orders plus derived L2\"]\n    F --> G[\"Route to the named D11 measurement\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "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": [
          {
            "file": "system-flow.md",
            "caption": "Sequence-Gap Detection and Recovery system flow",
            "source": "flowchart LR\n    A[\"Apply the expected sequence.\"] --> B[\"Buffer forward arrivals and expose the missing range.\"]\n    B --> C{\"Safe to publish?\"}\n    C -->|\"yes\"| D[\"Release the entire contiguous prefix after replay.\"]\n    C -->|\"no\"| E[\"Never apply a forward message merely because it arrived over reliable transport.\"]\n    D --> F[\"Publish contiguous applied prefix and recovery state\"]\n    F --> G[\"Route to the named D11 measurement\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "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": [
          {
            "file": "system-flow.md",
            "caption": "Price-Level Quantity Aggregation system flow",
            "source": "flowchart LR\n    A[\"Group exact side/price keys.\"] --> B[\"Sum quantity and count orders.\"]\n    B --> C{\"Safe to publish?\"}\n    C -->|\"yes\"| D[\"Calculate full totals before depth truncation.\"]\n    C -->|\"no\"| E[\"Depth truncation must not be reported as total visible liquidity.\"]\n    D --> F[\"Publish sorted L2 quantities and order counts\"]\n    F --> G[\"Route to the named D11 measurement\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "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": [
          {
            "file": "system-flow.md",
            "caption": "Snapshot/Incremental-Feed Reconciliation system flow",
            "source": "flowchart LR\n    A[\"Replay from the anchor through the checkpoint.\"] --> B[\"Keep later incrementals pending.\"]\n    B --> C{\"Safe to publish?\"}\n    C -->|\"yes\"| D[\"Outer-join every side/price key.\"]\n    C -->|\"no\"| E[\"Never compare different instruments, sequence domains, semantics, or knowledge times.\"]\n    D --> F[\"Publish price-level difference ledger\"]\n    F --> G[\"Route to the named D11 measurement\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "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": [
          {
            "file": "system-flow.md",
            "caption": "Multi-Venue Best-Quote and Book Consolidation system flow",
            "source": "flowchart LR\n    A[\"Select the latest record per venue at the as-of time.\"] --> B[\"Exclude future, stale, halted, ineligible, empty, or crossed books.\"]\n    B --> C{\"Safe to publish?\"}\n    C -->|\"yes\"| D[\"Aggregate every surviving side/price level.\"]\n    C -->|\"no\"| E[\"Do not label this receive-time local view NBBO or evidence of compliance.\"]\n    D --> F[\"Publish multi-level local consolidated book and best quote\"]\n    F --> G[\"Route to the named D11 measurement\"]"
          }
        ]
      },
      "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": "https://github.com/IslamBaraka90/Fintech-Backward-Split-Adjustment-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Forward-Split-Adjustment-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Cash-Dividend-Total-Return-Adjustment-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-CRSP-Cumulative-Price-Adjustment-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-CRSP-Cumulative-Share-Volume-Adjustment-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Rights-Issue-TERP-Adjustment-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Spin-Off-Price-Adjustment-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Stock-Dividend-Adjustment-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Special-Dividend-Adjustment-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Return-Of-Capital-Adjustment-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Permanent-Security-Identifier-Mapping-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Ticker-Change-Chain-Resolution-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Share-Class-Relationship-Mapping-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Merger-Predecessor-Successor-Mapping-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Delisting-Return-Reconstruction-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Historical-Constituent-Reconstruction-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Survivorship-Bias-Guard-Corporate-Actions-algorithm",
        "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 to a research system — not when it was listed, but whether every event type a named, versioned policy requires had become effective for the evaluated instant and known by the research cutoff. The answer is data-readiness evidence; it never establishes investability, tradability, liquidity, offering eligibility, or returns.",
        "params": [
          {
            "name": "data",
            "type": "{ query: Query; policies: Policy[]; records: EventRecord[]; identityLinks?: IdentityLink[] }",
            "required": true,
            "description": "`query` fixes the issuer/instrument/listing identity, the `effectiveAt` instant being evaluated, the `knownAt` research cutoff, and the `policyId`. Each `policies` revision names, in `requiredEventTypes`, which of the ten supported clocks must be present — from `issuer_filing` through `local_ingestion`. There is no minimum-trading-day, free-float, or liquidity threshold anywhere in the contract. `records` are immutable, revisioned event observations carrying both an `effectiveAt` and an `availableAt`. `identityLinks` is consulted only for a `de_spac` policy context.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ effectiveAt, knownAt, identity, policyId, status, policySatisfied, policy, effectiveGateAt, knowledgeGateAt, missingPolicy, missingEventTypes, pendingEffectiveEventTypes, ambiguousEventTypes, supplementalAmbiguousEventTypes, cancelledEventTypes, unsupportedReasons, identityContinuityStatus, identityContinuityEvidence, evidence, doesNotEstablish }",
          "description": "`status` is `resolved`, `incomplete`, `ambiguous`, or `unsupported`. `effectiveGateAt` and `knowledgeGateAt` are populated only when the status is `resolved`: the latest effective instant and the latest availability instant among the policy and its required events — the binding gates. The remaining lists name which event types were missing, future-effective, conflicting, or cancelled. `doesNotEstablish` is returned on every call."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the input is malformed: a missing or empty required string, a timestamp without a UTC offset, a non-positive or non-contiguous revision, an unknown event type, context, state or market phase, a clockOwner that does not own that event's clock, a revision that changes immutable identity, a revision whose availability does not increase, or a record reactivated after cancellation",
            "behaviour": "throws"
          },
          {
            "when": "the referenced policyId has no revision that is both effective for the evaluated instant and known by the cutoff",
            "behaviour": "returns status `incomplete` with `missingPolicy: true`; it does not throw"
          }
        ],
        "complexity": {
          "time": "O(r log r) for r records known at the cutoff: each event's revision chain is sorted before its current revision is taken, then a fixed set of ten event types is resolved from those current revisions",
          "space": "O(r)"
        }
      },
      "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": "https://github.com/IslamBaraka90/Fintech-IPO-Availability-Timestamping-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Filing-Revision-Versioning-Corporate-Actions-algorithm",
        "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": "verified",
        "via": "D"
      },
      "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": "https://github.com/IslamBaraka90/Fintech-Corporate-Action-Status-Effective-Date-Reconciliation-Corporate-Actions-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Base-Date-Base-Value-Initialization-Index-Engineering-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Index-Divisor-Initialization-Index-Engineering-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Divisor-Continuity-Adjustment-Index-Engineering-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Corporate-Action-Divisor-Bridge-Index-Engineering-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Intraday-Index-Level-Calculation-Index-Engineering-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Price-Weighted-Index-Engineering-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Total-Market-Cap-Index-Engineering-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Free-Float-Market-Cap-Index-Engineering-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Capped-Free-Float-Market-Cap-Index-Engineering-algorithm",
        "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": "https://github.com/IslamBaraka90/Fintech-Modified-Market-Cap-Index-Engineering-algorithm",
        "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: each eligible name receives the target weight 1/N at the rebalance date. Realised weights then drift with relative prices until the next scheduled rebalance, and restoring the equal target is what creates turnover. The construction does not imply continuous rebalancing; the rebalance calendar is a separate methodology choice that this function does not model.",
        "params": [
          {
            "name": "data",
            "type": "{ ids: string[]; returns: number[] }",
            "required": true,
            "description": "Constituent ids and their period returns. The returns are applied to the 1/N target weights of a single period; no rebalance calendar, drifted weight, or trade is taken as input.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ids, weights, portfolioReturn }",
          "description": "The 1/N target weights and the resulting single-period portfolio return. No turnover or trade list is produced."
        },
        "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, measured over the returns strictly before the current one, as a sample standard deviation with an n-1 denominator. `annualization` is the periods-per-year count (252 for daily data) that multiplies the sample variance before the square root. `maxExposure` caps exposure when volatility is low and is also the exposure used when a window's realised volatility is exactly zero. `baseLevel` is the index value at the start of the series; it scales the level but never the returns. There is no exposure floor, no rebalance band or trigger, and no separate warm-up parameter: the first `lookback` observations are given exposure 1 by convention.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ exposures, strategyReturns, levels, endingLevel }",
          "description": "The exposure actually taken each period alongside the returns — the exposure path is what explains the strategy's behaviour. No turnover, trade, or cost figure is produced."
        },
        "warmup": null,
        "errors": [
          {
            "when": "lookback < 2, or returns has no more than lookback observations",
            "behaviour": "throws"
          },
          {
            "when": "targetVolatility, maxExposure, or annualization is not positive",
            "behaviour": "throws"
          },
          {
            "when": "a strategy return drives the index level to zero or below",
            "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. This package's convention is the median of the supplied monthly turnover ratios against a monthly threshold; the median is deliberate, because a mean is dominated by one spike of activity. The statistic is a median monthly ratio, not an annualized traded value ratio, and providers differ in window length, statistic, and whether they annualize.",
        "params": [
          {
            "name": "data",
            "type": "{ records: Record[]; minimumMedianTurnover: number; minimumMonths: number }",
            "required": true,
            "description": "Each record supplies `monthlyTurnover`, the already-computed monthly ratios of traded value to free-float market capitalisation. The raw traded value and capitalisation are never seen, so suspended and part-traded months cannot be recognised here and must be resolved upstream. `minimumMonths` is the sustained-history requirement, which is what stops a newly listed name qualifying on a burst of IPO volume; it is a minimum length, not a window, and every month supplied is included in the median.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ results, passingIds, threshold }",
          "description": "Per-candidate results with the realised median monthly ratio and the monthly threshold applied."
        },
        "warmup": null,
        "errors": [
          {
            "when": "minimumMedianTurnover is negative, or minimumMonths is less than 1",
            "behaviour": "throws"
          },
          {
            "when": "any record supplies fewer months than minimumMonths, or a negative monthly ratio",
            "behaviour": "throws for the whole call, not only that record"
          }
        ],
        "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 from one aggregate restricted-share count, then rounds it up to a band. Classifying holdings as strategic, government, insider or cross-held is upstream work: this function receives only the single total those decisions produce, and neither checks nor reports the classes separately. 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": "Each record supplies `issuedShares` and `strategicShares`, the single aggregate of all restricted holdings; the raw factor is (issuedShares - strategicShares) / issuedShares. `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. The rounded factor is the raw factor taken up to the next multiple of `roundingStep` and capped at 1, with a factor already on a band boundary left where it is. No per-class breakdown of excluded holdings is returned, because none is supplied."
        },
        "warmup": null,
        "errors": [
          {
            "when": "roundingStep is not in (0, 1]",
            "behaviour": "throws"
          },
          {
            "when": "issuedShares is not positive, strategicShares is negative, or strategicShares exceeds issuedShares",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "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, in issues — direction discarded on purpose. It reports how far apart the two counts were, so an up session and a down session of the same size share a value. Nothing here reads it as conviction, activity, volatility, or a signal: the package returns the signed spread and the original counts alongside it, and interpretation is left to separate research.",
        "params": [
          {
            "name": "request",
            "type": "{ decision_time: string; metric_variant: string; records: Record[] }",
            "required": true,
            "description": "`metric_variant` must be the string `raw_issue_count`; it is the only supported form. A normalized, smoothed, or cumulative variant is not calculated — the request comes back with evaluation state `unsupported`. `decision_time` bounds which revisions are usable: a record counts only when both its `effective_at` and its `available_at` are at or before it.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ metric, evaluation_state, publishable, reason_codes, decision_time, records_causally_available, future_records_ignored, record_id, revision, is_provisional, net_advances, absolute_breadth_index, mover_count, classified_count, coverage_ratio, breadth_state, plus the snapshot identity and count fields when resolved }",
          "description": "`evaluation_state` is `resolved`, `incomplete`, `ambiguous`, or `unsupported`; every derived number is null unless it is `resolved`. A resolved result adds the snapshot identity — session, venue, universe id and revision, session and calendar ids, comparison basis, corporate-action policy, listing-identifier scheme — and the full count partition, so the index always travels with the universe it was computed over. `breadth_state` separates the three distinct ways a zero can arise: `active_balance`, `no_movers`, and `empty_universe`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "metric_variant is anything other than `raw_issue_count`",
            "behaviour": "reported as evaluation state `unsupported` rather than thrown"
          },
          {
            "when": "an input cannot be interpreted safely: a timestamp that is missing, malformed or without a UTC offset, a non-string identity field, a negative or unsafe count, a non-boolean `is_final`, or a `kind` other than observation or cancellation",
            "behaviour": "throws ABIValidationError"
          }
        ],
        "complexity": {
          "time": "O(r log r) for r revision records: validation and causal filtering are linear, and the visible revisions are sorted before the lineage head is taken",
          "space": "O(r)"
        }
      },
      "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. Scaling A−D by 1000/(A+D) makes each input invariant when advances and declines grow together, so issue-count growth does not dominate the scale. Threshold levels remain historical practice, not universal rules.",
        "params": [
          {
            "name": "records",
            "type": "BreadthRecord[]",
            "required": true,
            "description": "Session records carrying `session_sequence`, `revision`, `available_at`, `event_type`, `source_evidence_state`, the six series identity fields (`venue_id`, `universe_id`, `methodology_id`, `calendar_id`, `volume_unit`, `volume_adjustment_basis`), and the `advances` and `declines` counts the ratio adjustment consumes.",
            "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_policy, initial_index }",
          "description": "`status` is `resolved`, `incomplete`, `ambiguous`, or `unsupported`; only a resolved result carries `points`. Each point holds its session date, the transformed input, both EMA states, the oscillator, the cumulative index value, and a warm-up status of `warming_fast`, `warming_slow` or `ready` — the first oscillator appears at observation 39. `seed_policy` is `sma_19_39` and `initial_index` is the accumulator's declared starting constant, 0.0."
        },
        "warmup": {
          "count": "39 observations",
          "value": "warm-up status: warming_fast, then warming_slow",
          "note": "Every point carries a warm-up status. Under the sma_19_39 seed policy the 19-period EMA resolves first and the 39-period EMA second, so the first oscillator and the first summation-index step both appear at observation 39."
        },
        "errors": [
          {
            "when": "evidence is missing or inconsistent: no record at the cutoff, a gap in the session sequence, a duplicate or non-contiguous revision, a cancelled session, a source not yet ready, or a break in series identity",
            "behaviour": "returned as a non-resolved status with reason_codes; not thrown"
          },
          {
            "when": "a record is malformed: a timestamp not ending in Z, a non-positive session_sequence, a negative revision, an empty identity field, a non-finite or negative count, or advances + declines equal to zero, which leaves the ratio undefined",
            "behaviour": "throws ValueError"
          }
        ],
        "complexity": {
          "time": "O(n log n) for n records: sessions and per-session revisions are sorted before the head revision is taken, then the EMA recursion is a single linear pass",
          "space": "O(n)"
        }
      },
      "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. Weighting participation by share volume gives a series that can move differently from the issue-count oscillator, but this package neither measures nor interprets that difference: divergence signals are excluded. Magnitude is only comparable within one declared volume unit and adjustment basis, because doubling every allocated volume doubles the input, both EMA states, and the oscillator.",
        "params": [
          {
            "name": "records",
            "type": "BreadthRecord[]",
            "required": true,
            "description": "Session records carrying `session_sequence`, `revision`, `available_at`, `event_type`, `source_evidence_state`, the six series identity fields (`venue_id`, `universe_id`, `methodology_id`, `calendar_id`, `volume_unit`, `volume_adjustment_basis`), and an exactly reconciling volume partition: `up_volume`, `down_volume`, `unchanged_volume` and a positive `total_volume` equal to their sum.",
            "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_policy, initial_index }",
          "description": "`status` is `resolved`, `incomplete`, `ambiguous`, or `unsupported`; only a resolved result carries `points`. Each point holds its session date, the up-minus-down volume input, both EMA states, the oscillator, and a warm-up status of `warming_fast`, `warming_slow` or `ready` — the first oscillator appears at observation 39. This topic is the oscillator only: it declares no cumulative seed, so `index_value`, `latest_index_value` and `initial_index` are always null. The Volume Summation Index is a separate construction."
        },
        "warmup": {
          "count": "39 observations",
          "value": "warm-up status: warming_fast, then warming_slow",
          "note": "Every point carries a warm-up status. The 19-period EMA resolves first and the 39-period EMA second, so the first oscillator value appears at observation 39. This topic declares no cumulative seed, so the index fields stay null throughout."
        },
        "errors": [
          {
            "when": "a volume field is absent, non-finite or negative, `total_volume` is not positive, or the up/down/unchanged partition does not sum exactly to it",
            "behaviour": "throws ValueError"
          },
          {
            "when": "a record is otherwise malformed: a timestamp not ending in Z, a non-positive session_sequence, a negative revision, or an empty series-identity field",
            "behaviour": "throws ValueError"
          },
          {
            "when": "evidence is missing or inconsistent: no record at the cutoff, a gap in the session sequence, a duplicate or non-contiguous revision, a cancelled session, a source not yet ready, or a break in series identity",
            "behaviour": "returned as a non-resolved status with reason_codes; not thrown"
          }
        ],
        "complexity": {
          "time": "O(n log n) for n records: sessions and per-session revisions are sorted before the head revision is taken, then the EMA recursion is a single linear pass",
          "space": "O(n)"
        }
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Topic decision flow — New Highs–New Lows",
            "source": "flowchart LR\n    A[\"Ready NH and NL counts\"] --> B[\"Subtract NL from NH\"]\n    B --> C{\"Sign\"}\n    C -->|\"positive\"| D[\"More new highs\"]\n    C -->|\"zero\"| E[\"Balanced or genuine no-extremes\"]\n    C -->|\"negative\"| F[\"More new lows\"]\n    D --> G[\"Publish issues + universe size\"]\n    E --> G\n    F --> G"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Topic decision flow — High-Low Ratio",
            "source": "flowchart LR\n    A[\"Ready NH and NL counts\"] --> B{\"NL = 0?\"}\n    B -->|\"No\"| C[\"Publish NH / NL\"]\n    B -->|\"Yes\"| D{\"NH > 0?\"}\n    D -->|\"Yes\"| E[\"Unbounded: no infinity token\"]\n    D -->|\"No\"| F[\"Incomplete: no new extremes\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Topic decision flow — High-Low Index",
            "source": "flowchart LR\n    A[\"Daily NH and NL\"] --> B{\"NH + NL > 0?\"}\n    B -->|\"No\"| I[\"Undefined RHP; contaminate active window\"]\n    B -->|\"Yes\"| C[\"RHP = 100 × NH / (NH + NL)\"]\n    C --> D[\"Append to rolling tray\"]\n    D --> E{\"Ten defined values?\"}\n    E -->|\"No\"| W[\"Warming\"]\n    E -->|\"Yes\"| F[\"Mean of ten RHP values\"]\n    F --> G[\"Publish percentage points\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Topic decision flow — Percent Above 20-Day MA",
            "source": "flowchart LR\n    A[\"Point-in-time members\"] --> B[\"Require 20 comparable adjusted closes\"]\n    B --> C{\"Every member ready?\"}\n    C -->|\"No\"| I[\"Incomplete: keep denominator atomic\"]\n    C -->|\"Yes\"| D[\"Compute each SMA20\"]\n    D --> E{\"Current price > SMA20?\"}\n    E -->|\"Yes\"| F[\"Add one to numerator\"]\n    E -->|\"No or equal\"| G[\"Keep only in denominator\"]\n    F --> H[\"100 × above / eligible\"]\n    G --> H"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Topic decision flow — Percent Above 50-Day MA",
            "source": "flowchart LR\n    A[\"Point-in-time members\"] --> B[\"Require 50 comparable adjusted closes\"]\n    B --> C{\"Every member ready?\"}\n    C -->|\"No\"| I[\"Incomplete: keep denominator atomic\"]\n    C -->|\"Yes\"| D[\"Compute each SMA50\"]\n    D --> E{\"Current price > SMA50?\"}\n    E -->|\"Yes\"| F[\"Add one to numerator\"]\n    E -->|\"No or equal\"| G[\"Keep only in denominator\"]\n    F --> H[\"100 × above / eligible\"]\n    G --> H"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Topic decision flow — Percent Above 200-Day MA",
            "source": "flowchart LR\n    A[\"Point-in-time members\"] --> B[\"Require 200 comparable adjusted closes\"]\n    B --> C{\"Every member ready?\"}\n    C -->|\"No\"| I[\"Incomplete: keep denominator atomic\"]\n    C -->|\"Yes\"| D[\"Compute each SMA200\"]\n    D --> E{\"Current price > SMA200?\"}\n    E -->|\"Yes\"| F[\"Add one to numerator\"]\n    E -->|\"No or equal\"| G[\"Keep only in denominator\"]\n    F --> H[\"100 × above / eligible\"]\n    G --> H"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation Flow — Zweig Breadth Thrust",
            "source": "flowchart LR\n    A[\"Ordered A and D counts\"] --> B[\"Breadth ratio A/(A+D)\"]\n    B --> C[\"Update EMA10\"]\n    C --> D{\"EMA < 0.400?\"}\n    D -->|\"Yes\"| E[\"Arm or refresh clock\"]\n    D -->|\"No\"| F{\"Armed and EMA > 0.615?\"}\n    E --> G[\"Advance session age\"]\n    G --> F\n    F -->|\"Yes, age ≤ 10\"| H[\"Publish thrust now\"]\n    F -->|\"No, age > 10\"| I[\"Expire\"]\n    F -->|\"No, age ≤ 10\"| G"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation Flow — Arms Index (TRIN)",
            "source": "flowchart LR\n    A[\"Four positive synchronized legs\"] --> B[\"Issue ratio A/D\"]\n    A --> C[\"Volume ratio V+/V−\"]\n    B --> D[\"TRIN = issue ratio / volume ratio\"]\n    C --> D\n    A -->|\"Any leg ≤ 0\"| X[\"Incomplete topology\"]\n    D --> E[\"Publish TRIN plus both ratios\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation Flow — Advance/Decline Volume Line",
            "source": "flowchart LR\n    A[\"Declared seed\"] --> B[\"Ordered session\"]\n    B --> C[\"Net volume = V+ − V−\"]\n    C --> D[\"Level = prior level + net volume\"]\n    D --> E[\"Append increment and level\"]\n    E --> B\n    B -->|\"Missing or unordered\"| X[\"Stop recursive tail\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation Flow — Upside/Downside Volume Ratio",
            "source": "flowchart LR\n    A[\"Nonnegative V+ and V−\"] --> B{\"V− > 0?\"}\n    B -->|\"Yes\"| C[\"Publish V+/V−\"]\n    B -->|\"No\"| D{\"V+ > 0?\"}\n    D -->|\"Yes\"| E[\"Unbounded; withhold value\"]\n    D -->|\"No\"| F[\"Incomplete 0/0\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation Flow — Cumulative TICK",
            "source": "flowchart LR\n    A[\"One session and exact grid\"] --> B{\"Next timestamp gap = interval?\"}\n    B -->|\"No\"| X[\"Incomplete sampling_gap\"]\n    B -->|\"Yes\"| C[\"TICK = uptick − downtick issues\"]\n    C --> D[\"Cumulative = prior + TICK\"]\n    D --> E[\"Retain timestamp and trace\"]\n    E --> B"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation Flow — Breadth-Divergence Detector",
            "source": "flowchart LR\n    A[\"Ordered price and breadth\"] --> B[\"Confirm price pivot after right bars\"]\n    B --> C[\"Sample breadth on pivot date\"]\n    C --> D[\"Compare adjacent same-kind pivots\"]\n    D --> E[\"ΔP = (P2−P1)/P1\"]\n    D --> F[\"ΔB = (B2−B1)/breadth_scale\"]\n    E --> G{\"Directional minimums pass?\"}\n    F --> G\n    G -->|\"Yes\"| H[\"Publish on second pivot confirmation date\"]\n    G -->|\"No\"| I[\"No event\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation Flow — Top-N Index Contribution",
            "source": "flowchart LR\n    A[\"Point-in-time component snapshot\"] --> B{\"Complete, unique, finite?\"}\n    B -->|\"No\"| X[\"Incomplete — withhold value\"]\n    B -->|\"Yes\"| C[\"Apply Top-N Index Contribution contract\"]\n    C --> D[\"Retain component audit trace\"]\n    D --> E[\"Publish value, unit, parameter, and as-of\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation Flow — Herfindahl Constituent Concentration",
            "source": "flowchart LR\n    A[\"Point-in-time component snapshot\"] --> B{\"Complete, unique, finite?\"}\n    B -->|\"No\"| X[\"Incomplete — withhold value\"]\n    B -->|\"Yes\"| C[\"Apply Herfindahl Constituent Concentration contract\"]\n    C --> D[\"Retain component audit trace\"]\n    D --> E[\"Publish value, unit, parameter, and as-of\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation Flow — Effective Number of Constituents",
            "source": "flowchart LR\n    A[\"Point-in-time component snapshot\"] --> B{\"Complete, unique, finite?\"}\n    B -->|\"No\"| X[\"Incomplete — withhold value\"]\n    B -->|\"Yes\"| C[\"Apply Effective Number of Constituents contract\"]\n    C --> D[\"Retain component audit trace\"]\n    D --> E[\"Publish value, unit, parameter, and as-of\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation Flow — Sector Diffusion Index",
            "source": "flowchart LR\n    A[\"Point-in-time component snapshot\"] --> B{\"Complete, unique, finite?\"}\n    B -->|\"No\"| X[\"Incomplete — withhold value\"]\n    B -->|\"Yes\"| C[\"Apply Sector Diffusion Index contract\"]\n    C --> D[\"Retain component audit trace\"]\n    D --> E[\"Publish value, unit, parameter, and as-of\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation Flow — Factor Diffusion Index",
            "source": "flowchart LR\n    A[\"Point-in-time component snapshot\"] --> B{\"Complete, unique, finite?\"}\n    B -->|\"No\"| X[\"Incomplete — withhold value\"]\n    B -->|\"Yes\"| C[\"Apply Factor Diffusion Index contract\"]\n    C --> D[\"Retain component audit trace\"]\n    D --> E[\"Publish value, unit, parameter, and as-of\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f01-a03/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Shadow-to-Body Ratio calculation flow",
            "source": "flowchart LR\n    S1[\"Validate OHLC and positive tick size\"]\n    S2[\"Calculate body shadows and range\"]\n    S3[\"Return literal ratios only when body is positive\"]\n    S4[\"Calculate tickfloored diagnostics and dominant shadow\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"body exactly zero\"}\n    D --> O[\"dominant_shadow_ratio + diagnostics\"]\n    O --> A[\"Audit: Upper shadow  body  lower shadow equals the full candle ra\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f01-a04/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Gap Classification calculation flow",
            "source": "flowchart LR\n    S1[\"Validate both candles and tick configuration\"]\n    S2[\"Calculate six directional gap distances\"]\n    S3[\"Apply positivedistance and threshold rules\"]\n    S4[\"Select fullrange then body then openonly precedence an\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"positive distance exactly equals tick threshold\"}\n    D --> O[\"gap_distance + diagnostics\"]\n    O --> A[\"Audit: A selected fullrange gap implies the corresponding body an\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f01-a05/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Trend-Context Filter calculation flow",
            "source": "flowchart LR\n    S1[\"Validate aligned prior closerange arrays and configura\"]\n    S2[\"Select the latest lookback observations\"]\n    S3[\"Calculate signed net move total path efficiency and me\"]\n    S4[\"Apply efficiency and normalizedmove gates symmetricall\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"normalized move or efficiency exactly equals its gate\"}\n    D --> O[\"normalized_move + diagnostics\"]\n    O --> A[\"Audit: The candidate candle is absent from every context input\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a01/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Doji calculation flow",
            "source": "flowchart LR\n    S1[\"Validate the candle tick context and aligned prior sca\"]\n    S2[\"Calculate body upper shadow lower shadow and prior med\"]\n    S3[\"Evaluate the Doji Boolean checks in formula order\"]\n    S4[\"Apply required context when applicable and return ever\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material geometry threshold at exact equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched output has no failed Boolean checks\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a02/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Dragonfly Doji calculation flow",
            "source": "flowchart LR\n    S1[\"Validate the candle tick context and aligned prior sca\"]\n    S2[\"Calculate body upper shadow lower shadow and prior med\"]\n    S3[\"Evaluate the Dragonfly Doji Boolean checks in formula \"]\n    S4[\"Apply required context when applicable and return ever\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material geometry threshold at exact equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched output has no failed Boolean checks\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a03/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Gravestone Doji calculation flow",
            "source": "flowchart LR\n    S1[\"Validate the candle tick context and aligned prior sca\"]\n    S2[\"Calculate body upper shadow lower shadow and prior med\"]\n    S3[\"Evaluate the Gravestone Doji Boolean checks in formula\"]\n    S4[\"Apply required context when applicable and return ever\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material geometry threshold at exact equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched output has no failed Boolean checks\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a04/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Marubozu calculation flow",
            "source": "flowchart LR\n    S1[\"Validate the candle tick context and aligned prior sca\"]\n    S2[\"Calculate body upper shadow lower shadow and prior med\"]\n    S3[\"Evaluate the Marubozu Boolean checks in formula order\"]\n    S4[\"Apply required context when applicable and return ever\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material geometry threshold at exact equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched output has no failed Boolean checks\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a05/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Spinning Top calculation flow",
            "source": "flowchart LR\n    S1[\"Validate the candle tick context and aligned prior sca\"]\n    S2[\"Calculate body upper shadow lower shadow and prior med\"]\n    S3[\"Evaluate the Spinning Top Boolean checks in formula or\"]\n    S4[\"Apply required context when applicable and return ever\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material geometry threshold at exact equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched output has no failed Boolean checks\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a06/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Hammer calculation flow",
            "source": "flowchart LR\n    S1[\"Validate the candle tick context and aligned prior sca\"]\n    S2[\"Calculate body upper shadow lower shadow and prior med\"]\n    S3[\"Evaluate the Hammer Boolean checks in formula order\"]\n    S4[\"Apply required context when applicable and return ever\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material geometry threshold at exact equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched output has no failed Boolean checks\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a07/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Hanging Man calculation flow",
            "source": "flowchart LR\n    S1[\"Validate the candle tick context and aligned prior sca\"]\n    S2[\"Calculate body upper shadow lower shadow and prior med\"]\n    S3[\"Evaluate the Hanging Man Boolean checks in formula ord\"]\n    S4[\"Apply required context when applicable and return ever\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material geometry threshold at exact equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched output has no failed Boolean checks\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a08/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Inverted Hammer calculation flow",
            "source": "flowchart LR\n    S1[\"Validate the candle tick context and aligned prior sca\"]\n    S2[\"Calculate body upper shadow lower shadow and prior med\"]\n    S3[\"Evaluate the Inverted Hammer Boolean checks in formula\"]\n    S4[\"Apply required context when applicable and return ever\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material geometry threshold at exact equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched output has no failed Boolean checks\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a09/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Shooting Star calculation flow",
            "source": "flowchart LR\n    S1[\"Validate the candle tick context and aligned prior sca\"]\n    S2[\"Calculate body upper shadow lower shadow and prior med\"]\n    S3[\"Evaluate the Shooting Star Boolean checks in formula o\"]\n    S4[\"Apply required context when applicable and return ever\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material geometry threshold at exact equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched output has no failed Boolean checks\"]"
          }
        ]
      },
      "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-F02-A10",
      "name": "Long-Legged Doji",
      "headline": null,
      "slug": "long-legged-doji",
      "path": "price-action-and-candlesticks/single-candle-patterns/long-legged-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/long-legged-doji",
        "entry": "longLeggedDoji",
        "params": [
          "input"
        ],
        "exports": [
          "longLeggedDoji"
        ],
        "archetype": "record-transform",
        "signature": "longLeggedDoji(input)"
      },
      "api": {
        "summary": "Marks each bar whose body is a small fraction of its high-low span while both shadows are long, and reports how much slack the tightest of those three tests had.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronologically ordered array of OHLCV rows; each needs a non-empty `timestamp` strictly greater than the previous row's and finite `open`, `high`, `low`, `close` and `volume`. The single-candle family validates four `parameters` keys on every call: `body_ratio` (default 0.05, within 0..1), `shadow_ratio` (default 0.35, within 0..1), `shadow_body_multiple` (default 2, at least 0) and `tick_tolerance` (default 0.01, at least 0). This topic reads `body_ratio` as the largest body share of the span it will accept and `shadow_ratio` as the smallest share of the span each shadow must reach.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series.label` is `\"neutral\"` on a matching bar and `\"none\"` otherwise. `series.score` is the minimum of the three margins (`body_ratio` minus body share, upper-shadow share minus `shadow_ratio`, lower-shadow share minus `shadow_ratio`), so it is at or above zero exactly when the bar matches. `latest` carries the last value of each. There is no warm-up: both series are populated from the first bar, so `ready_at` is 0."
        },
        "warmup": {
          "count": "0 bars",
          "value": "null",
          "note": "Every test is per-bar geometry with no smoothing state, so `label` and `score` are emitted for index 0 and `ready_at` is 0. The one gap is a flat bar where `high` equals `low`: `score` is null there and `label` is `\"none\"`, which is a real verdict rather than a warm-up placeholder."
        },
        "errors": [
          {
            "when": "a bar has a non-finite price or volume, a negative volume, a `high` below its own open/low/close, a `low` above them, or a `timestamp` that does not advance",
            "behaviour": "throws Error"
          },
          {
            "when": "`body_ratio` or `shadow_ratio` is not a finite number, or falls outside 0..1",
            "behaviour": "throws Error"
          },
          {
            "when": "`input` is not an object, `input.parameters` is not an object, or `bars` is not an array holding at least one bar",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "longLeggedDoji({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F02-A10",
          "title": "Long-Legged Doji",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "label": [
              "neutral",
              "none",
              "none",
              "none",
              "none",
              "neutral"
            ],
            "score": [
              0.05,
              -0.03915474022958794,
              -0.08295729760191171,
              -0.08829149989844472,
              -0.0589777590581788,
              0.0044297342216514934
            ]
          },
          "latest": {
            "label": "none",
            "score": -0.06921211954649767
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a10/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a10/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a10/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a10/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Long-Legged Doji calculation flow",
            "source": "flowchart LR\n    A[\"one closed OHLC candle, tick size, prior-only reference sc\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Long-Legged Doji convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Long-Legged Doji readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib pattern-recognition catalog",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "CME Group candlestick chart lesson",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques",
          "author": "Steve Nison",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/single-candle-patterns/long-legged-doji/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/single-candle-patterns/long-legged-doji/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F02-A11",
      "name": "Four-Price Doji",
      "headline": null,
      "slug": "four-price-doji",
      "path": "price-action-and-candlesticks/single-candle-patterns/four-price-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/four-price-doji",
        "entry": "fourPriceDoji",
        "params": [
          "input"
        ],
        "exports": [
          "fourPriceDoji"
        ],
        "archetype": "record-transform",
        "signature": "fourPriceDoji(input)"
      },
      "api": {
        "summary": "Marks each bar whose entire range and whose open-to-close distance both sit within a tick tolerance, the degenerate candle where all four prices are effectively the same.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronologically ordered array of OHLCV rows; each needs a non-empty `timestamp` strictly greater than the previous row's and finite `open`, `high`, `low`, `close` and `volume`. The single-candle family validates `body_ratio` (default 0.05), `shadow_ratio` (default 0.35), `shadow_body_multiple` (default 2) and `tick_tolerance` (default 0.01) on every call, but this topic reads only `tick_tolerance`, the price distance at which a range and a body still count as zero.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series.label` is `\"neutral\"` when both `high` minus `low` and the absolute open-to-close distance are within `tick_tolerance`, and `\"none\"` otherwise. `series.score` is `tick_tolerance` minus the larger of those two distances, so it is at or above zero exactly when the bar matches. `latest` carries the last value of each. There is no warm-up: unlike its siblings this topic has no positive-span guard, so both series hold a value for every bar and `ready_at` is 0."
        },
        "warmup": {
          "count": "0 bars",
          "value": "null",
          "note": "Purely per-bar arithmetic with no smoothing state and no span guard, so neither `label` nor `score` is ever null and `ready_at` is 0."
        },
        "errors": [
          {
            "when": "a bar has a non-finite price or volume, a negative volume, a `high` below its own open/low/close, a `low` above them, or a `timestamp` that does not advance",
            "behaviour": "throws Error"
          },
          {
            "when": "`tick_tolerance` is not a finite number or is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "`input` is not an object, `input.parameters` is not an object, or `bars` is not an array holding at least one bar",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "fourPriceDoji({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F02-A11",
          "title": "Four-Price Doji",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "label": [
              "none",
              "none",
              "none",
              "none",
              "none",
              "none"
            ],
            "score": [
              -2.74500000000001,
              -3.3190167099999908,
              -3.748713730000011,
              -3.928635059999996,
              -3.819996080000001,
              -3.4596505999999945
            ]
          },
          "latest": {
            "label": "none",
            "score": -3.1108633100000045
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a11/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a11/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a11/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a11/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Four-Price Doji calculation flow",
            "source": "flowchart LR\n    A[\"one closed OHLC candle, tick size, prior-only reference sc\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Four-Price Doji convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Four-Price Doji readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib pattern-recognition catalog",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "CME Group candlestick chart lesson",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques",
          "author": "Steve Nison",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/single-candle-patterns/four-price-doji/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/single-candle-patterns/four-price-doji/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F02-A12",
      "name": "High-Wave Candle",
      "headline": null,
      "slug": "high-wave-candle",
      "path": "price-action-and-candlesticks/single-candle-patterns/high-wave-candle",
      "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/high-wave-candle",
        "entry": "highWaveCandle",
        "params": [
          "input"
        ],
        "exports": [
          "highWaveCandle"
        ],
        "archetype": "record-transform",
        "signature": "highWaveCandle(input)"
      },
      "api": {
        "summary": "Marks each bar with a small body relative to its high-low span whose two shadows are both a multiple of that body, the long-tailed indecision candle.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronologically ordered array of OHLCV rows; each needs a non-empty `timestamp` strictly greater than the previous row's and finite `open`, `high`, `low`, `close` and `volume`. The single-candle family validates `body_ratio` (default 0.05, within 0..1), `shadow_ratio` (default 0.35), `shadow_body_multiple` (default 2, at least 0) and `tick_tolerance` (default 0.01) on every call. This topic reads `body_ratio` as the largest body share of the span it will accept and `shadow_body_multiple` as how many bodies long each shadow must be; a zero body satisfies the shadow test outright.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series.label` is `\"neutral\"` on a matching bar and `\"none\"` otherwise. `series.score` is `body_ratio` minus the body share of the span, so it reports headroom on the body test alone and can be at or above zero on a bar the shadow test rejected. `latest` carries the last value of each. There is no warm-up: both series are populated from the first bar, so `ready_at` is 0."
        },
        "warmup": {
          "count": "0 bars",
          "value": "null",
          "note": "Per-bar geometry with no smoothing state, so `ready_at` is 0. On a flat bar where `high` equals `low` the positive-span guard leaves `score` null and `label` at `\"none\"`, which is a real verdict rather than a warm-up placeholder."
        },
        "errors": [
          {
            "when": "a bar has a non-finite price or volume, a negative volume, a `high` below its own open/low/close, a `low` above them, or a `timestamp` that does not advance",
            "behaviour": "throws Error"
          },
          {
            "when": "`body_ratio` is not a finite number or falls outside 0..1, or `shadow_body_multiple` is not a finite number or is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "`input` is not an object, `input.parameters` is not an object, or `bars` is not an array holding at least one bar",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "highWaveCandle({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F02-A12",
          "title": "High-Wave Candle",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "label": [
              "neutral",
              "none",
              "none",
              "none",
              "none",
              "neutral"
            ],
            "score": [
              0.05,
              -0.03915474022958794,
              -0.08295729760191171,
              -0.08829149989844472,
              -0.0589777590581788,
              0.0044297342216514934
            ]
          },
          "latest": {
            "label": "none",
            "score": -0.06921211954649767
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a12/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a12/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a12/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a12/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "High-Wave Candle calculation flow",
            "source": "flowchart LR\n    A[\"one closed OHLC candle, tick size, prior-only reference sc\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected High-Wave Candle convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "High-Wave Candle readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib pattern-recognition catalog",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "CME Group candlestick chart lesson",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques",
          "author": "Steve Nison",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/single-candle-patterns/high-wave-candle/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/single-candle-patterns/high-wave-candle/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F02-A13",
      "name": "Belt Hold",
      "headline": null,
      "slug": "belt-hold",
      "path": "price-action-and-candlesticks/single-candle-patterns/belt-hold",
      "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/belt-hold",
        "entry": "beltHold",
        "params": [
          "input"
        ],
        "exports": [
          "beltHold"
        ],
        "archetype": "record-transform",
        "signature": "beltHold(input)"
      },
      "api": {
        "summary": "Marks each bar that opens at one extreme of its own range within a tick and closes at least 60 percent of the span away, and reports that body share and which side it favoured.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronologically ordered array of OHLCV rows; each needs a non-empty `timestamp` strictly greater than the previous row's and finite `open`, `high`, `low`, `close` and `volume`. The single-candle family validates `body_ratio` (default 0.05), `shadow_ratio` (default 0.35), `shadow_body_multiple` (default 2) and `tick_tolerance` (default 0.01, at least 0) on every call, but this topic reads only `tick_tolerance`, how far the open may sit from the low (bullish) or the high (bearish). The 60 percent body share is fixed in the branch and is not configurable.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series.label` is `\"bullish\"` when the bar closes up and opens within `tick_tolerance` of its low, `\"bearish\"` when it closes down and opens within `tick_tolerance` of its high, and `\"none\"` otherwise. `series.score` is the body as a share of the high-low span, between 0 and 1, reported on every bar with a positive range whether or not it matched. `latest` carries the last value of each. There is no warm-up: both series are populated from the first bar, so `ready_at` is 0."
        },
        "warmup": {
          "count": "0 bars",
          "value": "null",
          "note": "Per-bar geometry with no smoothing state, so `ready_at` is 0. On a flat bar where `high` equals `low` the positive-span guard leaves `score` null and `label` at `\"none\"`, which is a real verdict rather than a warm-up placeholder."
        },
        "errors": [
          {
            "when": "a bar has a non-finite price or volume, a negative volume, a `high` below its own open/low/close, a `low` above them, or a `timestamp` that does not advance",
            "behaviour": "throws Error"
          },
          {
            "when": "`tick_tolerance` is not a finite number or is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "`input` is not an object, `input.parameters` is not an object, or `bars` is not an array holding at least one bar",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "beltHold({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F02-A13",
          "title": "Belt Hold",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "label": [
              "none",
              "none",
              "none",
              "none",
              "none",
              "none"
            ],
            "score": [
              0,
              0.08915474022958794,
              0.13295729760191172,
              0.13829149989844472,
              0.1089777590581788,
              0.04557026577834851
            ]
          },
          "latest": {
            "label": "none",
            "score": 0.11921211954649767
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a13/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a13/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a13/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a13/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Belt Hold calculation flow",
            "source": "flowchart LR\n    A[\"one closed OHLC candle, tick size, prior-only reference sc\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Belt Hold convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Belt Hold readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib pattern-recognition catalog",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "CME Group candlestick chart lesson",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques",
          "author": "Steve Nison",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/single-candle-patterns/belt-hold/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/single-candle-patterns/belt-hold/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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a01/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Bullish Engulfing calculation flow",
            "source": "flowchart LR\n    S1[\"Validate consecutive comparable candles tick tolerance\"]\n    S2[\"Calculate both anatomies and the firstbody midpoint\"]\n    S3[\"Evaluate the Bullish Engulfing contract A bearish firs\"]\n    S4[\"Apply prior context and return every check and diagnos\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material endpoint midpoint or tolerance equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched pair has no failed geometry or context checks\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a02/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Bearish Engulfing calculation flow",
            "source": "flowchart LR\n    S1[\"Validate consecutive comparable candles tick tolerance\"]\n    S2[\"Calculate both anatomies and the firstbody midpoint\"]\n    S3[\"Evaluate the Bearish Engulfing contract A bullish firs\"]\n    S4[\"Apply prior context and return every check and diagnos\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material endpoint midpoint or tolerance equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched pair has no failed geometry or context checks\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a03/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Bullish Harami calculation flow",
            "source": "flowchart LR\n    S1[\"Validate consecutive comparable candles tick tolerance\"]\n    S2[\"Calculate both anatomies and the firstbody midpoint\"]\n    S3[\"Evaluate the Bullish Harami contract A short bullish s\"]\n    S4[\"Apply prior context and return every check and diagnos\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material endpoint midpoint or tolerance equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched pair has no failed geometry or context checks\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a04/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Bearish Harami calculation flow",
            "source": "flowchart LR\n    S1[\"Validate consecutive comparable candles tick tolerance\"]\n    S2[\"Calculate both anatomies and the firstbody midpoint\"]\n    S3[\"Evaluate the Bearish Harami contract A short bearish s\"]\n    S4[\"Apply prior context and return every check and diagnos\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material endpoint midpoint or tolerance equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched pair has no failed geometry or context checks\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a05/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Piercing Line calculation flow",
            "source": "flowchart LR\n    S1[\"Validate consecutive comparable candles tick tolerance\"]\n    S2[\"Calculate both anatomies and the firstbody midpoint\"]\n    S3[\"Evaluate the Piercing Line contract After a long beari\"]\n    S4[\"Apply prior context and return every check and diagnos\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material endpoint midpoint or tolerance equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched pair has no failed geometry or context checks\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a06/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Dark Cloud Cover calculation flow",
            "source": "flowchart LR\n    S1[\"Validate consecutive comparable candles tick tolerance\"]\n    S2[\"Calculate both anatomies and the firstbody midpoint\"]\n    S3[\"Evaluate the Dark Cloud Cover contract After a long bu\"]\n    S4[\"Apply prior context and return every check and diagnos\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material endpoint midpoint or tolerance equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched pair has no failed geometry or context checks\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a07/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Tweezer Top calculation flow",
            "source": "flowchart LR\n    S1[\"Validate consecutive comparable candles tick tolerance\"]\n    S2[\"Calculate both anatomies and the firstbody midpoint\"]\n    S3[\"Evaluate the Tweezer Top contract A bullish then beari\"]\n    S4[\"Apply prior context and return every check and diagnos\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material endpoint midpoint or tolerance equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched pair has no failed geometry or context checks\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a08/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Tweezer Bottom calculation flow",
            "source": "flowchart LR\n    S1[\"Validate consecutive comparable candles tick tolerance\"]\n    S2[\"Calculate both anatomies and the firstbody midpoint\"]\n    S3[\"Evaluate the Tweezer Bottom contract A bearish then bu\"]\n    S4[\"Apply prior context and return every check and diagnos\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"the material endpoint midpoint or tolerance equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: A matched pair has no failed geometry or context checks\"]"
          }
        ]
      },
      "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-F03-A09",
      "name": "Harami Cross",
      "headline": null,
      "slug": "harami-cross",
      "path": "price-action-and-candlesticks/two-candle-patterns/harami-cross",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F03",
        "family": "Two-Candle Patterns",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/two-candle-patterns/harami-cross",
        "entry": "haramiCross",
        "params": [
          "input"
        ],
        "exports": [
          "haramiCross"
        ],
        "archetype": "record-transform",
        "signature": "haramiCross(input)"
      },
      "api": {
        "summary": "Scans consecutive pairs of bars for a doji whose body sits inside the previous bar's body, and reports the pattern's direction from the colour of that earlier bar.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronologically ordered array of OHLCV rows; each needs a non-empty `timestamp` strictly greater than the previous row's and finite `open`, `high`, `low`, `close` and `volume`. The pattern family validates two `parameters` keys on every call: `tick_tolerance` (default 0.01, at least 0) and `doji_body_ratio` (default 0.05, within 0..1). This topic uses both, `doji_body_ratio` as the largest body share of the second bar's span that still counts as a doji and `tick_tolerance` as the slack allowed at each end of the containment test.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series.matched` is the boolean verdict for the pair ending at that index, and `series.label` is `\"bullish\"` when the first bar closed down, `\"bearish\"` when it closed up, and `\"none\"` when the pattern failed or the first bar closed exactly at its open. `latest` carries the last value of each. The warm-up is the one leading bar that has no predecessor."
        },
        "warmup": {
          "count": "1 bar",
          "value": "null",
          "note": "The pattern needs a two-bar window, so both series hold null at index 0 and `ready_at` is 1. From index 1 onward `matched` is false or true, and false is a real verdict rather than a warm-up placeholder, so `ready_at` does not depend on any pattern ever firing. A one-bar input returns null throughout, with `ready_at` null and `state` \"waiting\"."
        },
        "errors": [
          {
            "when": "a bar has a non-finite price or volume, a negative volume, a `high` below its own open/low/close, a `low` above them, or a `timestamp` that does not advance",
            "behaviour": "throws Error"
          },
          {
            "when": "`doji_body_ratio` is not a finite number or falls outside 0..1, or `tick_tolerance` is not a finite number or is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "`input` is not an object, `input.parameters` is not an object, or `bars` is not an array holding at least one bar",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "haramiCross({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F03-A09",
          "title": "Harami Cross",
          "state": "calculated",
          "ready": true,
          "ready_at": 1,
          "series": {
            "label": [
              null,
              "none",
              "none",
              "none",
              "none",
              "none"
            ],
            "matched": [
              null,
              false,
              false,
              false,
              false,
              false
            ]
          },
          "latest": {
            "label": "none",
            "matched": false
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a09/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a09/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a09/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a09/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Harami Cross calculation flow",
            "source": "flowchart LR\n    A[\"two consecutive closed OHLC candles, tick size, declared g\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Harami Cross convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Harami Cross readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib pattern-recognition catalog",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "CME Group candlestick chart lesson",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques",
          "author": "Steve Nison",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/two-candle-patterns/harami-cross/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/two-candle-patterns/harami-cross/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F03-A10",
      "name": "Kicking Pattern",
      "headline": null,
      "slug": "kicking-pattern",
      "path": "price-action-and-candlesticks/two-candle-patterns/kicking-pattern",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F03",
        "family": "Two-Candle Patterns",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/two-candle-patterns/kicking-pattern",
        "entry": "kickingPattern",
        "params": [
          "input"
        ],
        "exports": [
          "kickingPattern"
        ],
        "archetype": "record-transform",
        "signature": "kickingPattern(input)"
      },
      "api": {
        "summary": "Scans consecutive pairs of bars for two near-marubozu candles of opposite colour separated by a clean gap, with no overlap between the two ranges.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronologically ordered array of OHLCV rows; each needs a non-empty `timestamp` strictly greater than the previous row's and finite `open`, `high`, `low`, `close` and `volume`. The pattern family validates `tick_tolerance` (default 0.01, at least 0) and `doji_body_ratio` (default 0.05, within 0..1) on every call, but this topic reads only `tick_tolerance`, the margin by which the second bar's range must clear the first bar's. The 80 percent body share that makes a candle near-marubozu is fixed in the branch and is not configurable.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series.matched` is the boolean verdict for the pair ending at that index, and `series.label` is `\"bullish\"` when the pattern fires and the second bar closed up, `\"bearish\"` when it fired downward, and `\"none\"` when it did not fire. `latest` carries the last value of each. The warm-up is the one leading bar that has no predecessor."
        },
        "warmup": {
          "count": "1 bar",
          "value": "null",
          "note": "The pattern needs a two-bar window, so both series hold null at index 0 and `ready_at` is 1. From index 1 onward `matched` is false or true, and false is a real verdict rather than a warm-up placeholder, so `ready_at` does not depend on any pattern ever firing. A one-bar input returns null throughout, with `ready_at` null and `state` \"waiting\"."
        },
        "errors": [
          {
            "when": "a bar has a non-finite price or volume, a negative volume, a `high` below its own open/low/close, a `low` above them, or a `timestamp` that does not advance",
            "behaviour": "throws Error"
          },
          {
            "when": "`tick_tolerance` is not a finite number or is negative, or `doji_body_ratio` falls outside 0..1",
            "behaviour": "throws Error"
          },
          {
            "when": "`input` is not an object, `input.parameters` is not an object, or `bars` is not an array holding at least one bar",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "kickingPattern({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F03-A10",
          "title": "Kicking Pattern",
          "state": "calculated",
          "ready": true,
          "ready_at": 1,
          "series": {
            "label": [
              null,
              "none",
              "none",
              "none",
              "none",
              "none"
            ],
            "matched": [
              null,
              false,
              false,
              false,
              false,
              false
            ]
          },
          "latest": {
            "label": "none",
            "matched": false
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a10/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a10/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a10/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a10/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Kicking Pattern calculation flow",
            "source": "flowchart LR\n    A[\"two consecutive closed OHLC candles, tick size, declared g\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Kicking Pattern convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Kicking Pattern readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib pattern-recognition catalog",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "CME Group candlestick chart lesson",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques",
          "author": "Steve Nison",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/two-candle-patterns/kicking-pattern/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/two-candle-patterns/kicking-pattern/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F03-A11",
      "name": "Matching Low",
      "headline": null,
      "slug": "matching-low",
      "path": "price-action-and-candlesticks/two-candle-patterns/matching-low",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F03",
        "family": "Two-Candle Patterns",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/two-candle-patterns/matching-low",
        "entry": "matchingLow",
        "params": [
          "input"
        ],
        "exports": [
          "matchingLow"
        ],
        "archetype": "record-transform",
        "signature": "matchingLow(input)"
      },
      "api": {
        "summary": "Scans consecutive pairs of bars for two down candles whose closes land within a tick of each other, marking a repeated closing floor.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronologically ordered array of OHLCV rows; each needs a non-empty `timestamp` strictly greater than the previous row's and finite `open`, `high`, `low`, `close` and `volume`. The pattern family validates `tick_tolerance` (default 0.01, at least 0) and `doji_body_ratio` (default 0.05, within 0..1) on every call, but this topic reads only `tick_tolerance`, the largest gap between the two closes that still counts as a match.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series.matched` is the boolean verdict for the pair ending at that index, and `series.label` is `\"bullish\"` when it fires and `\"none\"` when it does not; this topic emits no bearish label. `latest` carries the last value of each. The warm-up is the one leading bar that has no predecessor."
        },
        "warmup": {
          "count": "1 bar",
          "value": "null",
          "note": "The pattern needs a two-bar window, so both series hold null at index 0 and `ready_at` is 1. From index 1 onward `matched` is false or true, and false is a real verdict rather than a warm-up placeholder, so `ready_at` does not depend on any pattern ever firing. A one-bar input returns null throughout, with `ready_at` null and `state` \"waiting\"."
        },
        "errors": [
          {
            "when": "a bar has a non-finite price or volume, a negative volume, a `high` below its own open/low/close, a `low` above them, or a `timestamp` that does not advance",
            "behaviour": "throws Error"
          },
          {
            "when": "`tick_tolerance` is not a finite number or is negative, or `doji_body_ratio` falls outside 0..1",
            "behaviour": "throws Error"
          },
          {
            "when": "`input` is not an object, `input.parameters` is not an object, or `bars` is not an array holding at least one bar",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "matchingLow({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F03-A11",
          "title": "Matching Low",
          "state": "calculated",
          "ready": true,
          "ready_at": 1,
          "series": {
            "label": [
              null,
              "none",
              "none",
              "none",
              "none",
              "none"
            ],
            "matched": [
              null,
              false,
              false,
              false,
              false,
              false
            ]
          },
          "latest": {
            "label": "none",
            "matched": false
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a11/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a11/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a11/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a11/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Matching Low calculation flow",
            "source": "flowchart LR\n    A[\"two consecutive closed OHLC candles, tick size, declared g\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Matching Low convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Matching Low readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib pattern-recognition catalog",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "CME Group candlestick chart lesson",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques",
          "author": "Steve Nison",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/two-candle-patterns/matching-low/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/two-candle-patterns/matching-low/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F03-A12",
      "name": "Rising/Falling Window",
      "headline": null,
      "slug": "rising-falling-window",
      "path": "price-action-and-candlesticks/two-candle-patterns/rising-falling-window",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F03",
        "family": "Two-Candle Patterns",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/two-candle-patterns/rising-falling-window",
        "entry": "risingFallingWindow",
        "params": [
          "input"
        ],
        "exports": [
          "risingFallingWindow"
        ],
        "archetype": "record-transform",
        "signature": "risingFallingWindow(input)"
      },
      "api": {
        "summary": "Scans consecutive pairs of bars for a price gap, where the second bar's range clears the first bar's entirely in either direction.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronologically ordered array of OHLCV rows; each needs a non-empty `timestamp` strictly greater than the previous row's and finite `open`, `high`, `low`, `close` and `volume`. The pattern family validates `tick_tolerance` (default 0.01, at least 0) and `doji_body_ratio` (default 0.05, within 0..1) on every call, but this topic reads only `tick_tolerance`, the margin by which the second bar's low must clear the first bar's high, or its high fall below the first bar's low, for the gap to count.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series.matched` is the boolean verdict for the pair ending at that index, and `series.label` is `\"rising\"` for an upward gap, `\"falling\"` for a downward one, and `\"none\"` when the ranges overlap. `latest` carries the last value of each. The warm-up is the one leading bar that has no predecessor."
        },
        "warmup": {
          "count": "1 bar",
          "value": "null",
          "note": "The pattern needs a two-bar window, so both series hold null at index 0 and `ready_at` is 1. From index 1 onward `matched` is false or true, and false is a real verdict rather than a warm-up placeholder, so `ready_at` does not depend on any gap ever appearing. A one-bar input returns null throughout, with `ready_at` null and `state` \"waiting\"."
        },
        "errors": [
          {
            "when": "a bar has a non-finite price or volume, a negative volume, a `high` below its own open/low/close, a `low` above them, or a `timestamp` that does not advance",
            "behaviour": "throws Error"
          },
          {
            "when": "`tick_tolerance` is not a finite number or is negative, or `doji_body_ratio` falls outside 0..1",
            "behaviour": "throws Error"
          },
          {
            "when": "`input` is not an object, `input.parameters` is not an object, or `bars` is not an array holding at least one bar",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "risingFallingWindow({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F03-A12",
          "title": "Rising/Falling Window",
          "state": "calculated",
          "ready": true,
          "ready_at": 1,
          "series": {
            "label": [
              null,
              "none",
              "none",
              "none",
              "none",
              "none"
            ],
            "matched": [
              null,
              false,
              false,
              false,
              false,
              false
            ]
          },
          "latest": {
            "label": "none",
            "matched": false
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a12/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a12/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a12/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a12/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Rising/Falling Window calculation flow",
            "source": "flowchart LR\n    A[\"two consecutive closed OHLC candles, tick size, declared g\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Rising/Falling Window convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Rising/Falling Window readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib pattern-recognition catalog",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "CME Group candlestick chart lesson",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques",
          "author": "Steve Nison",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/two-candle-patterns/rising-falling-window/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/two-candle-patterns/rising-falling-window/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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a01/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Morning Star calculation flow",
            "source": "flowchart LR\n    S1[\"Validate OHLC and one consistent price basis\"]\n    S2[\"Build median priorbody and priorrange scales\"]\n    S3[\"Evaluate candle directions and scale thresholds\"]\n    S4[\"Evaluate gaps containment opens shadows or penetration\"]\n    S5[\"Apply required trend context\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"realbody gap and penetration equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: matched implies every named geometry check passes and tren\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a02/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Evening Star calculation flow",
            "source": "flowchart LR\n    S1[\"Validate OHLC and one consistent price basis\"]\n    S2[\"Build median priorbody and priorrange scales\"]\n    S3[\"Evaluate candle directions and scale thresholds\"]\n    S4[\"Evaluate gaps containment opens shadows or penetration\"]\n    S5[\"Apply required trend context\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"realbody gap and penetration equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: matched implies every named geometry check passes and tren\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a03/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Three White Soldiers calculation flow",
            "source": "flowchart LR\n    S1[\"Validate OHLC and one consistent price basis\"]\n    S2[\"Build median priorbody and priorrange scales\"]\n    S3[\"Evaluate candle directions and scale thresholds\"]\n    S4[\"Evaluate gaps containment opens shadows or penetration\"]\n    S5[\"Apply required trend context\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"openinsidebody and shortuppershadow rules\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: matched implies every named geometry check passes and tren\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a04/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Three Black Crows calculation flow",
            "source": "flowchart LR\n    S1[\"Validate OHLC and one consistent price basis\"]\n    S2[\"Build median priorbody and priorrange scales\"]\n    S3[\"Evaluate candle directions and scale thresholds\"]\n    S4[\"Evaluate gaps containment opens shadows or penetration\"]\n    S5[\"Apply required trend context\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"openinsidebody and shortlowershadow rules\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: matched implies every named geometry check passes and tren\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a05/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Three Inside Up/Down calculation flow",
            "source": "flowchart LR\n    S1[\"Validate OHLC and one consistent price basis\"]\n    S2[\"Build median priorbody and priorrange scales\"]\n    S3[\"Evaluate candle directions and scale thresholds\"]\n    S4[\"Evaluate gaps containment opens shadows or penetration\"]\n    S5[\"Apply required trend context\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"strict containment versus endpoint equality\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: matched implies every named geometry check passes and tren\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a06/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Three Outside Up/Down calculation flow",
            "source": "flowchart LR\n    S1[\"Validate OHLC and one consistent price basis\"]\n    S2[\"Build median priorbody and priorrange scales\"]\n    S3[\"Evaluate candle directions and scale thresholds\"]\n    S4[\"Evaluate gaps containment opens shadows or penetration\"]\n    S5[\"Apply required trend context\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"strictly larger engulfing body\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: matched implies every named geometry check passes and tren\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a07/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Abandoned Baby calculation flow",
            "source": "flowchart LR\n    S1[\"Validate OHLC and one consistent price basis\"]\n    S2[\"Build median priorbody and priorrange scales\"]\n    S3[\"Evaluate candle directions and scale thresholds\"]\n    S4[\"Evaluate gaps containment opens shadows or penetration\"]\n    S5[\"Apply required trend context\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"two fullrange gaps rather than bodyonly separation\"}\n    D --> O[\"matched + diagnostics\"]\n    O --> A[\"Audit: matched implies every named geometry check passes and tren\"]"
          }
        ]
      },
      "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-F04-A08",
      "name": "Morning Doji Star",
      "headline": null,
      "slug": "morning-doji-star",
      "path": "price-action-and-candlesticks/multi-candle-patterns/morning-doji-star",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F04",
        "family": "Multi-Candle Patterns",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/multi-candle-patterns/morning-doji-star",
        "entry": "morningDojiStar",
        "params": [
          "input"
        ],
        "exports": [
          "morningDojiStar"
        ],
        "archetype": "record-transform",
        "signature": "morningDojiStar(input)"
      },
      "api": {
        "summary": "Scans three-bar windows for a down candle, then a doji, then an up candle that closes above the midpoint of the first candle's body.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronologically ordered array of OHLCV rows; each needs a non-empty `timestamp` strictly greater than the previous row's and finite `open`, `high`, `low`, `close` and `volume`. The pattern family validates `tick_tolerance` (default 0.01, at least 0) and `doji_body_ratio` (default 0.05, within 0..1) on every call, but this topic reads only `doji_body_ratio`, the largest body share of the middle bar's high-low span that still counts as a doji.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series.matched` is the boolean verdict for the window ending at that index, and `series.label` is `\"bullish\"` when it fires and `\"none\"` when it does not; this pattern has a single direction. `latest` carries the last value of each. The warm-up is the two leading bars that cannot close a three-bar window."
        },
        "warmup": {
          "count": "2 bars",
          "value": "null",
          "note": "The pattern needs a three-bar window, so both series hold null at indexes 0 and 1 and `ready_at` is 2. From index 2 onward `matched` is false or true, and false is a real verdict rather than a warm-up placeholder, so `ready_at` does not depend on any pattern ever firing. An input of one or two bars returns null throughout, with `ready_at` null and `state` \"waiting\"."
        },
        "errors": [
          {
            "when": "a bar has a non-finite price or volume, a negative volume, a `high` below its own open/low/close, a `low` above them, or a `timestamp` that does not advance",
            "behaviour": "throws Error"
          },
          {
            "when": "`doji_body_ratio` is not a finite number or falls outside 0..1, or `tick_tolerance` is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "`input` is not an object, `input.parameters` is not an object, or `bars` is not an array holding at least one bar",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "morningDojiStar({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F04-A08",
          "title": "Morning Doji Star",
          "state": "calculated",
          "ready": true,
          "ready_at": 2,
          "series": {
            "label": [
              null,
              null,
              "none",
              "none",
              "none",
              "none"
            ],
            "matched": [
              null,
              null,
              false,
              false,
              false,
              false
            ]
          },
          "latest": {
            "label": "none",
            "matched": false
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a08/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a08/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a08/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a08/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Morning Doji Star calculation flow",
            "source": "flowchart LR\n    A[\"an ordered OHLC sequence, tick size, gap policy, body scal\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Morning Doji Star convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Morning Doji Star readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib pattern-recognition catalog",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "CME Group candlestick chart lesson",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques",
          "author": "Steve Nison",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/multi-candle-patterns/morning-doji-star/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/multi-candle-patterns/morning-doji-star/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F04-A09",
      "name": "Evening Doji Star",
      "headline": null,
      "slug": "evening-doji-star",
      "path": "price-action-and-candlesticks/multi-candle-patterns/evening-doji-star",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F04",
        "family": "Multi-Candle Patterns",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/multi-candle-patterns/evening-doji-star",
        "entry": "eveningDojiStar",
        "params": [
          "input"
        ],
        "exports": [
          "eveningDojiStar"
        ],
        "archetype": "record-transform",
        "signature": "eveningDojiStar(input)"
      },
      "api": {
        "summary": "Scans three-bar windows for an up candle, then a doji, then a down candle that closes below the midpoint of the first candle's body.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronologically ordered array of OHLCV rows; each needs a non-empty `timestamp` strictly greater than the previous row's and finite `open`, `high`, `low`, `close` and `volume`. The pattern family validates `tick_tolerance` (default 0.01, at least 0) and `doji_body_ratio` (default 0.05, within 0..1) on every call, but this topic reads only `doji_body_ratio`, the largest body share of the middle bar's high-low span that still counts as a doji.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series.matched` is the boolean verdict for the window ending at that index, and `series.label` is `\"bearish\"` when it fires and `\"none\"` when it does not; this pattern has a single direction. `latest` carries the last value of each. The warm-up is the two leading bars that cannot close a three-bar window."
        },
        "warmup": {
          "count": "2 bars",
          "value": "null",
          "note": "The pattern needs a three-bar window, so both series hold null at indexes 0 and 1 and `ready_at` is 2. From index 2 onward `matched` is false or true, and false is a real verdict rather than a warm-up placeholder, so `ready_at` does not depend on any pattern ever firing. An input of one or two bars returns null throughout, with `ready_at` null and `state` \"waiting\"."
        },
        "errors": [
          {
            "when": "a bar has a non-finite price or volume, a negative volume, a `high` below its own open/low/close, a `low` above them, or a `timestamp` that does not advance",
            "behaviour": "throws Error"
          },
          {
            "when": "`doji_body_ratio` is not a finite number or falls outside 0..1, or `tick_tolerance` is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "`input` is not an object, `input.parameters` is not an object, or `bars` is not an array holding at least one bar",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "eveningDojiStar({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F04-A09",
          "title": "Evening Doji Star",
          "state": "calculated",
          "ready": true,
          "ready_at": 2,
          "series": {
            "label": [
              null,
              null,
              "none",
              "none",
              "none",
              "none"
            ],
            "matched": [
              null,
              null,
              false,
              false,
              false,
              false
            ]
          },
          "latest": {
            "label": "bearish",
            "matched": true
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a09/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a09/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a09/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a09/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Evening Doji Star calculation flow",
            "source": "flowchart LR\n    A[\"an ordered OHLC sequence, tick size, gap policy, body scal\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Evening Doji Star convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Evening Doji Star readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib pattern-recognition catalog",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "CME Group candlestick chart lesson",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques",
          "author": "Steve Nison",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/multi-candle-patterns/evening-doji-star/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/multi-candle-patterns/evening-doji-star/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F04-A10",
      "name": "Three-Line Strike",
      "headline": null,
      "slug": "three-line-strike",
      "path": "price-action-and-candlesticks/multi-candle-patterns/three-line-strike",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F04",
        "family": "Multi-Candle Patterns",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/multi-candle-patterns/three-line-strike",
        "entry": "threeLineStrike",
        "params": [
          "input"
        ],
        "exports": [
          "threeLineStrike"
        ],
        "archetype": "record-transform",
        "signature": "threeLineStrike(input)"
      },
      "api": {
        "summary": "Scans four-bar windows for three same-colour candles followed by one opposite candle whose body swallows the run from the first candle's body edge to the third's.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronologically ordered array of OHLCV rows; each needs a non-empty `timestamp` strictly greater than the previous row's and finite `open`, `high`, `low`, `close` and `volume`. The pattern family validates `tick_tolerance` (default 0.01, at least 0) and `doji_body_ratio` (default 0.05, within 0..1) on every call, but this topic's branch reads neither: every comparison is an exact body and colour test with no tolerance.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series.matched` is the boolean verdict for the window ending at that index, and `series.label` is `\"bearish-strike\"` when three up candles are struck by a down candle, `\"bullish-strike\"` for the mirror case, and `\"none\"` otherwise. `latest` carries the last value of each. The warm-up is the three leading bars that cannot close a four-bar window."
        },
        "warmup": {
          "count": "3 bars",
          "value": "null",
          "note": "The pattern needs a four-bar window, so both series hold null at indexes 0 through 2 and `ready_at` is 3. From index 3 onward `matched` is false or true, and false is a real verdict rather than a warm-up placeholder, so `ready_at` does not depend on any pattern ever firing. An input of one to three bars returns null throughout, with `ready_at` null and `state` \"waiting\"."
        },
        "errors": [
          {
            "when": "a bar has a non-finite price or volume, a negative volume, a `high` below its own open/low/close, a `low` above them, or a `timestamp` that does not advance",
            "behaviour": "throws Error"
          },
          {
            "when": "`tick_tolerance` or `doji_body_ratio` is out of range, which the family validates before the branch runs even though this topic does not use either",
            "behaviour": "throws Error"
          },
          {
            "when": "`input` is not an object, `input.parameters` is not an object, or `bars` is not an array holding at least one bar",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "threeLineStrike({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F04-A10",
          "title": "Three-Line Strike",
          "state": "calculated",
          "ready": true,
          "ready_at": 3,
          "series": {
            "label": [
              null,
              null,
              null,
              "none",
              "none",
              "none"
            ],
            "matched": [
              null,
              null,
              null,
              false,
              false,
              false
            ]
          },
          "latest": {
            "label": "none",
            "matched": false
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a10/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a10/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a10/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a10/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Three-Line Strike calculation flow",
            "source": "flowchart LR\n    A[\"an ordered OHLC sequence, tick size, gap policy, body scal\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Three-Line Strike convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Three-Line Strike readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib pattern-recognition catalog",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "CME Group candlestick chart lesson",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques",
          "author": "Steve Nison",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/multi-candle-patterns/three-line-strike/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/multi-candle-patterns/three-line-strike/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F04-A11",
      "name": "Rising/Falling Three Methods",
      "headline": null,
      "slug": "rising-falling-three-methods",
      "path": "price-action-and-candlesticks/multi-candle-patterns/rising-falling-three-methods",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F04",
        "family": "Multi-Candle Patterns",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/multi-candle-patterns/rising-falling-three-methods",
        "entry": "risingFallingThreeMethods",
        "params": [
          "input"
        ],
        "exports": [
          "risingFallingThreeMethods"
        ],
        "archetype": "record-transform",
        "signature": "risingFallingThreeMethods(input)"
      },
      "api": {
        "summary": "Scans five-bar windows for a long candle, three bars whose ranges stay inside it, and a fifth candle of the same colour that closes beyond the first one's close.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronologically ordered array of OHLCV rows; each needs a non-empty `timestamp` strictly greater than the previous row's and finite `open`, `high`, `low`, `close` and `volume`. The pattern family validates `tick_tolerance` (default 0.01, at least 0) and `doji_body_ratio` (default 0.05, within 0..1) on every call, but this topic reads only `tick_tolerance`, the slack allowed at each end of the first bar's range when checking that the three middle bars stay inside it.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series.matched` is the boolean verdict for the window ending at that index, and `series.label` is `\"rising\"` for the bullish continuation, `\"falling\"` for the bearish one, and `\"none\"` otherwise. `latest` carries the last value of each. The warm-up is the four leading bars that cannot close a five-bar window."
        },
        "warmup": {
          "count": "4 bars",
          "value": "null",
          "note": "The pattern needs a five-bar window, so both series hold null at indexes 0 through 3 and `ready_at` is 4. From index 4 onward `matched` is false or true, and false is a real verdict rather than a warm-up placeholder, so `ready_at` does not depend on any pattern ever firing. An input of one to four bars returns null throughout, with `ready_at` null and `state` \"waiting\"."
        },
        "errors": [
          {
            "when": "a bar has a non-finite price or volume, a negative volume, a `high` below its own open/low/close, a `low` above them, or a `timestamp` that does not advance",
            "behaviour": "throws Error"
          },
          {
            "when": "`tick_tolerance` is not a finite number or is negative, or `doji_body_ratio` falls outside 0..1",
            "behaviour": "throws Error"
          },
          {
            "when": "`input` is not an object, `input.parameters` is not an object, or `bars` is not an array holding at least one bar",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "risingFallingThreeMethods({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F04-A11",
          "title": "Rising/Falling Three Methods",
          "state": "calculated",
          "ready": true,
          "ready_at": 4,
          "series": {
            "label": [
              null,
              null,
              null,
              null,
              "none",
              "none"
            ],
            "matched": [
              null,
              null,
              null,
              null,
              false,
              false
            ]
          },
          "latest": {
            "label": "none",
            "matched": false
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a11/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a11/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a11/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a11/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Rising/Falling Three Methods calculation flow",
            "source": "flowchart LR\n    A[\"an ordered OHLC sequence, tick size, gap policy, body scal\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Rising/Falling Three Methods convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Rising/Falling Three Methods readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib pattern-recognition catalog",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "CME Group candlestick chart lesson",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques",
          "author": "Steve Nison",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/multi-candle-patterns/rising-falling-three-methods/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/multi-candle-patterns/rising-falling-three-methods/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F04-A12",
      "name": "Upside Gap Two Crows",
      "headline": null,
      "slug": "upside-gap-two-crows",
      "path": "price-action-and-candlesticks/multi-candle-patterns/upside-gap-two-crows",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F04",
        "family": "Multi-Candle Patterns",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/multi-candle-patterns/upside-gap-two-crows",
        "entry": "upsideGapTwoCrows",
        "params": [
          "input"
        ],
        "exports": [
          "upsideGapTwoCrows"
        ],
        "archetype": "record-transform",
        "signature": "upsideGapTwoCrows(input)"
      },
      "api": {
        "summary": "Scans three-bar windows for an up candle, a gapped-up down candle, and a second down candle that opens higher still yet closes back inside the first candle's body.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronologically ordered array of OHLCV rows; each needs a non-empty `timestamp` strictly greater than the previous row's and finite `open`, `high`, `low`, `close` and `volume`. The pattern family validates `tick_tolerance` (default 0.01, at least 0) and `doji_body_ratio` (default 0.05, within 0..1) on every call, but this topic's branch reads neither: the gap and the containment are strict comparisons with no tolerance applied.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series.matched` is the boolean verdict for the window ending at that index, and `series.label` is `\"bearish\"` when it fires and `\"none\"` when it does not; this pattern has a single direction. `latest` carries the last value of each. The warm-up is the two leading bars that cannot close a three-bar window."
        },
        "warmup": {
          "count": "2 bars",
          "value": "null",
          "note": "The pattern needs a three-bar window, so both series hold null at indexes 0 and 1 and `ready_at` is 2. From index 2 onward `matched` is false or true, and false is a real verdict rather than a warm-up placeholder, so `ready_at` does not depend on any pattern ever firing. An input of one or two bars returns null throughout, with `ready_at` null and `state` \"waiting\"."
        },
        "errors": [
          {
            "when": "a bar has a non-finite price or volume, a negative volume, a `high` below its own open/low/close, a `low` above them, or a `timestamp` that does not advance",
            "behaviour": "throws Error"
          },
          {
            "when": "`tick_tolerance` or `doji_body_ratio` is out of range, which the family validates before the branch runs even though this topic does not use either",
            "behaviour": "throws Error"
          },
          {
            "when": "`input` is not an object, `input.parameters` is not an object, or `bars` is not an array holding at least one bar",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "upsideGapTwoCrows({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F04-A12",
          "title": "Upside Gap Two Crows",
          "state": "calculated",
          "ready": true,
          "ready_at": 2,
          "series": {
            "label": [
              null,
              null,
              "none",
              "none",
              "none",
              "none"
            ],
            "matched": [
              null,
              null,
              false,
              false,
              false,
              false
            ]
          },
          "latest": {
            "label": "none",
            "matched": false
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a12/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a12/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a12/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a12/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Upside Gap Two Crows calculation flow",
            "source": "flowchart LR\n    A[\"an ordered OHLC sequence, tick size, gap policy, body scal\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Upside Gap Two Crows convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Upside Gap Two Crows readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib pattern-recognition catalog",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "CME Group candlestick chart lesson",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques",
          "author": "Steve Nison",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/multi-candle-patterns/upside-gap-two-crows/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/multi-candle-patterns/upside-gap-two-crows/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F04-A13",
      "name": "Mat Hold",
      "headline": null,
      "slug": "mat-hold",
      "path": "price-action-and-candlesticks/multi-candle-patterns/mat-hold",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F04",
        "family": "Multi-Candle Patterns",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/multi-candle-patterns/mat-hold",
        "entry": "matHold",
        "params": [
          "input"
        ],
        "exports": [
          "matHold"
        ],
        "archetype": "record-transform",
        "signature": "matHold(input)"
      },
      "api": {
        "summary": "Scans five-bar windows for an up candle, a gap above its close, three bars that hold above the first candle's body floor, and a fifth up candle closing above every high in the window so far.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronologically ordered array of OHLCV rows; each needs a non-empty `timestamp` strictly greater than the previous row's and finite `open`, `high`, `low`, `close` and `volume`. The pattern family validates `tick_tolerance` (default 0.01, at least 0) and `doji_body_ratio` (default 0.05, within 0..1) on every call, but this topic's branch reads neither: every test is a strict price comparison with no tolerance applied.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series.matched` is the boolean verdict for the window ending at that index, and `series.label` is `\"bullish\"` when it fires and `\"none\"` when it does not; this pattern has a single direction. `latest` carries the last value of each. The warm-up is the four leading bars that cannot close a five-bar window."
        },
        "warmup": {
          "count": "4 bars",
          "value": "null",
          "note": "The pattern needs a five-bar window, so both series hold null at indexes 0 through 3 and `ready_at` is 4. From index 4 onward `matched` is false or true, and false is a real verdict rather than a warm-up placeholder, so `ready_at` does not depend on any pattern ever firing. An input of one to four bars returns null throughout, with `ready_at` null and `state` \"waiting\"."
        },
        "errors": [
          {
            "when": "a bar has a non-finite price or volume, a negative volume, a `high` below its own open/low/close, a `low` above them, or a `timestamp` that does not advance",
            "behaviour": "throws Error"
          },
          {
            "when": "`tick_tolerance` or `doji_body_ratio` is out of range, which the family validates before the branch runs even though this topic does not use either",
            "behaviour": "throws Error"
          },
          {
            "when": "`input` is not an object, `input.parameters` is not an object, or `bars` is not an array holding at least one bar",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "matHold({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F04-A13",
          "title": "Mat Hold",
          "state": "calculated",
          "ready": true,
          "ready_at": 4,
          "series": {
            "label": [
              null,
              null,
              null,
              null,
              "none",
              "none"
            ],
            "matched": [
              null,
              null,
              null,
              null,
              false,
              false
            ]
          },
          "latest": {
            "label": "none",
            "matched": false
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a13/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a13/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a13/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a13/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Mat Hold calculation flow",
            "source": "flowchart LR\n    A[\"an ordered OHLC sequence, tick size, gap policy, body scal\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Mat Hold convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Mat Hold readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib pattern-recognition catalog",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "CME Group candlestick chart lesson",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques",
          "author": "Steve Nison",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/multi-candle-patterns/mat-hold/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/multi-candle-patterns/mat-hold/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-F01-A10",
      "name": "Triangular Moving Average (TRIMA)",
      "headline": null,
      "slug": "triangular-moving-average-trima",
      "path": "technical-indicators/trend-smoothing/triangular-moving-average-trima",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/triangular-moving-average-trima",
        "entry": "triangularMovingAverageTrima",
        "params": [
          "input"
        ],
        "exports": [
          "triangularMovingAverageTrima"
        ],
        "archetype": "series-transform",
        "signature": "triangularMovingAverageTrima(input)"
      },
      "api": {
        "summary": "Smooths close twice with simple moving averages, an inner window of `floor((period + 1) / 2)` followed by an outer window of `floor(period / 2) + 1`, giving the triangular weighting its name.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of OHLCV records with strictly increasing `timestamp`, finite `open`, `high`, `low`, `close` and non-negative `volume`, all sharing one adjustment basis. From `parameters` this topic reads only `period`, an integer of at least 2, default 14.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single key, `value`, the doubly smoothed close. The first `period - 1` entries are null while the two stacked windows fill, so with the default period `ready_at` is 13."
        },
        "warmup": {
          "count": "period - 1 bars (13 at the default period of 14)",
          "value": "null",
          "note": "The inner average first prints at index `floor((period + 1) / 2) - 1` and the outer one needs `floor(period / 2) + 1` of those, which together add up to exactly `period - 1` leading nulls. `ready_at` is the index of the first non-null `value`."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, a high below its open/close/low, or a timestamp that does not increase",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "triangularMovingAverageTrima({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F01-A10",
          "title": "Triangular Moving Average (TRIMA)",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 105.29699925285715
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a10/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a10/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a10/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a10/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Triangular Moving Average (TRIMA) calculation flow",
            "source": "flowchart LR\n    A[\"an oldest-to-newest finite price series, declared price so\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Triangular Moving Average (TRIMA) convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Triangular Moving Average (TRIMA) readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/triangular-moving-average-trima/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/triangular-moving-average-trima/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A11",
      "name": "Tillson T3 Moving Average",
      "headline": null,
      "slug": "tillson-t3-moving-average",
      "path": "technical-indicators/trend-smoothing/tillson-t3-moving-average",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/tillson-t3-moving-average",
        "entry": "tillsonT3MovingAverage",
        "params": [
          "input"
        ],
        "exports": [
          "tillsonT3MovingAverage"
        ],
        "archetype": "series-transform",
        "signature": "tillsonT3MovingAverage(input)"
      },
      "api": {
        "summary": "Chains six exponential moving averages of the same `period` over close and combines the third through sixth with the Tillson volume-factor coefficients, trading warm-up length for a smoother, less laggy curve.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of OHLCV records with strictly increasing `timestamp`, finite `open`, `high`, `low`, `close` and non-negative `volume`, all sharing one adjustment basis. From `parameters` this topic reads `period`, an integer of at least 2, default 14, and `volume_factor`, a finite number between 0 and 1, default 0.7.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single key, `value`, the T3 curve. The warm-up is long because the six EMAs are stacked, so with the default period `ready_at` is 78 rather than 13."
        },
        "warmup": {
          "count": "6 * (period - 1) bars (78 at the default period of 14)",
          "value": "null",
          "note": "Each EMA in the chain seeds from a full `period` of non-null inputs, so every stage pushes the first print `period - 1` bars further out. `value` is null until all four of the third-to-sixth stages are non-null, and `ready_at` is the index where that first happens."
        },
        "errors": [
          {
            "when": "`parameters.volume_factor` is not a finite number between 0 and 1",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty or a bar violates the OHLCV contract",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "tillsonT3MovingAverage({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F01-A11",
          "title": "Tillson T3 Moving Average",
          "state": "calculated",
          "ready": true,
          "ready_at": 78,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 104.92677609155169
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a11/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a11/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a11/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a11/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Tillson T3 Moving Average calculation flow",
            "source": "flowchart LR\n    A[\"an oldest-to-newest finite price series, declared price so\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Tillson T3 Moving Average convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Tillson T3 Moving Average readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/tillson-t3-moving-average/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/tillson-t3-moving-average/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A12",
      "name": "Following Adaptive Moving Average (FAMA)",
      "headline": null,
      "slug": "following-adaptive-moving-average-fama",
      "path": "technical-indicators/trend-smoothing/following-adaptive-moving-average-fama",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/following-adaptive-moving-average-fama",
        "entry": "followingAdaptiveMovingAverageFama",
        "params": [
          "input"
        ],
        "exports": [
          "followingAdaptiveMovingAverageFama"
        ],
        "archetype": "series-transform",
        "signature": "followingAdaptiveMovingAverageFama(input)"
      },
      "api": {
        "summary": "Runs an efficiency-ratio adaptive average over close and its slower follower: net movement across `period` bars divided by the summed absolute bar-to-bar movement sets the smoothing constant, and FAMA tracks MAMA at half that constant.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of OHLCV records with strictly increasing `timestamp`, finite `open`, `high`, `low`, `close` and non-negative `volume`, all sharing one adjustment basis. From `parameters` this topic reads `period`, an integer of at least 2, default 14, plus `fast_alpha`, default 0.5, and `slow_alpha`, default 0.05, both finite numbers between 0 and 1.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry two keys, `mama` and `fama`. Both are null for the first `period` bars, are seeded with the close at index `period`, and thereafter recurse, so with the default period `ready_at` is 14."
        },
        "warmup": {
          "count": "period bars (14 at the default period of 14)",
          "value": "null",
          "note": "The efficiency ratio needs a `period`-bar lookback, so the loop starts at index `period` and both series are seeded there with the close. `ready_at` is that index. A window with zero total movement is treated as an efficiency ratio of 0 rather than dividing by zero."
        },
        "errors": [
          {
            "when": "`parameters.fast_alpha` or `parameters.slow_alpha` is not a finite number between 0 and 1",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty or a bar violates the OHLCV contract",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "followingAdaptiveMovingAverageFama({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F01-A12",
          "title": "Following Adaptive Moving Average (FAMA)",
          "state": "calculated",
          "ready": true,
          "ready_at": 14,
          "series": {
            "mama": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "fama": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "mama": 103.83007356524162,
            "fama": 104.7546779146645
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a12/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a12/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a12/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a12/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Following Adaptive Moving Average (FAMA) calculation flow",
            "source": "flowchart LR\n    A[\"an oldest-to-newest finite price series, declared price so\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Following Adaptive Moving Average (FAMA) convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Following Adaptive Moving Average (FAMA) readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/following-adaptive-moving-average-fama/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/following-adaptive-moving-average-fama/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A13",
      "name": "Arnaud Legoux Moving Average (ALMA)",
      "headline": null,
      "slug": "arnaud-legoux-moving-average-alma",
      "path": "technical-indicators/trend-smoothing/arnaud-legoux-moving-average-alma",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/arnaud-legoux-moving-average-alma",
        "entry": "arnaudLegouxMovingAverageAlma",
        "params": [
          "input"
        ],
        "exports": [
          "arnaudLegouxMovingAverageAlma"
        ],
        "archetype": "series-transform",
        "signature": "arnaudLegouxMovingAverageAlma(input)"
      },
      "api": {
        "summary": "Averages close under a Gaussian weight curve whose peak sits at `offset * (period - 1)` within the window and whose width is `period / sigma`, so pushing the offset toward 1 favours recent bars.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of OHLCV records with strictly increasing `timestamp`, finite `open`, `high`, `low`, `close` and non-negative `volume`, all sharing one adjustment basis. From `parameters` this topic reads `period`, an integer of at least 2, default 14; `offset`, a finite number between 0 and 1, default 0.85; and `sigma`, a finite number of at least 0.000001, default 6.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single key, `value`, the weight-normalised average. The first `period - 1` entries are null while the window fills, so with the default period `ready_at` is 13."
        },
        "warmup": {
          "count": "period - 1 bars (13 at the default period of 14)",
          "value": "null",
          "note": "The weighted average only prints once a full `period`-bar window of close is available, so `ready_at` is `period - 1`. The weights are divided by their own sum, so the offset changes the shape of the curve but not its scale."
        },
        "errors": [
          {
            "when": "`parameters.offset` is not a finite number between 0 and 1",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.sigma` is not a finite number of at least 0.000001",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.period` is not an integer of at least 2",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "arnaudLegouxMovingAverageAlma({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F01-A13",
          "title": "Arnaud Legoux Moving Average (ALMA)",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 102.77111410307967
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a13/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a13/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a13/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a13/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Arnaud Legoux Moving Average (ALMA) calculation flow",
            "source": "flowchart LR\n    A[\"an oldest-to-newest finite price series, declared price so\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Arnaud Legoux Moving Average (ALMA) convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Arnaud Legoux Moving Average (ALMA) readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/arnaud-legoux-moving-average-alma/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/arnaud-legoux-moving-average-alma/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A14",
      "name": "Fractal Adaptive Moving Average (FRAMA)",
      "headline": null,
      "slug": "fractal-adaptive-moving-average-frama",
      "path": "technical-indicators/trend-smoothing/fractal-adaptive-moving-average-frama",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/fractal-adaptive-moving-average-frama",
        "entry": "fractalAdaptiveMovingAverageFrama",
        "params": [
          "input"
        ],
        "exports": [
          "fractalAdaptiveMovingAverageFrama"
        ],
        "archetype": "series-transform",
        "signature": "fractalAdaptiveMovingAverageFrama(input)"
      },
      "api": {
        "summary": "Estimates the fractal dimension of each `period`-bar close window by comparing the ranges of its two halves against the range of the whole, then smooths close with `exp(-4.6 * (dimension - 1))` as the adaptive constant.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of OHLCV records with strictly increasing `timestamp`, finite `open`, `high`, `low`, `close` and non-negative `volume`, all sharing one adjustment basis. From `parameters` this topic reads `period`, an integer of at least 2 that must also be even, default 14, and `minimum_alpha`, a finite number between 0 and 1 that floors the smoothing constant, default 0.01.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single key, `value`. The first `period - 1` entries are null, the bar at that index is seeded with close, and the recursion runs from there, so with the default period `ready_at` is 13."
        },
        "warmup": {
          "count": "period - 1 bars (13 at the default period of 14)",
          "value": "null",
          "note": "The dimension estimate needs a full `period`-bar window split into two halves, so the first output lands at index `period - 1` and is seeded with the close itself. `ready_at` is that index. A degenerate window with no range is treated as dimension 1, which gives the fastest constant."
        },
        "errors": [
          {
            "when": "`parameters.period` is odd — the half-window split requires an even period",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.minimum_alpha` is not a finite number between 0 and 1",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.period` is not an integer of at least 2",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "fractalAdaptiveMovingAverageFrama({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F01-A14",
          "title": "Fractal Adaptive Moving Average (FRAMA)",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 101.14724461464692
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a14/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a14/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a14/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a14/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Fractal Adaptive Moving Average (FRAMA) calculation flow",
            "source": "flowchart LR\n    A[\"an oldest-to-newest finite price series, declared price so\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Fractal Adaptive Moving Average (FRAMA) convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Fractal Adaptive Moving Average (FRAMA) readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/fractal-adaptive-moving-average-frama/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/fractal-adaptive-moving-average-frama/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A15",
      "name": "Zero-Lag Exponential Moving Average (ZLEMA)",
      "headline": null,
      "slug": "zero-lag-exponential-moving-average-zlema",
      "path": "technical-indicators/trend-smoothing/zero-lag-exponential-moving-average-zlema",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/zero-lag-exponential-moving-average-zlema",
        "entry": "zeroLagExponentialMovingAverageZlema",
        "params": [
          "input"
        ],
        "exports": [
          "zeroLagExponentialMovingAverageZlema"
        ],
        "archetype": "series-transform",
        "signature": "zeroLagExponentialMovingAverageZlema(input)"
      },
      "api": {
        "summary": "Removes most of the EMA's lag by first de-lagging close into `2 * close[t] - close[t - lag]`, where `lag` is `floor((period - 1) / 2)`, and then running an ordinary EMA of `period` over that adjusted series.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of OHLCV records with strictly increasing `timestamp`, finite `open`, `high`, `low`, `close` and non-negative `volume`, all sharing one adjustment basis. From `parameters` this topic reads only `period`, an integer of at least 2, default 14, which sets both the de-lag distance and the EMA smoothing constant.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single key, `value`. The warm-up stacks the de-lag offset on top of the EMA seed, so with the default period `ready_at` is 19, not 13."
        },
        "warmup": {
          "count": "floor((period - 1) / 2) + period - 1 bars (19 at the default period of 14)",
          "value": "null",
          "note": "The de-lagged series is null for its first `floor((period - 1) / 2)` bars, and the EMA then needs a further `period` non-null values to seed from their mean. `ready_at` is the index of the first non-null `value`."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, or a timestamp that does not increase",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "zeroLagExponentialMovingAverageZlema({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F01-A15",
          "title": "Zero-Lag Exponential Moving Average (ZLEMA)",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 101.8372551421456
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a15/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a15/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a15/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a15/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Zero-Lag Exponential Moving Average (ZLEMA) calculation flow",
            "source": "flowchart LR\n    A[\"an oldest-to-newest finite price series, declared price so\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Zero-Lag Exponential Moving Average (ZLEMA) convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Zero-Lag Exponential Moving Average (ZLEMA) readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/zero-lag-exponential-moving-average-zlema/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/zero-lag-exponential-moving-average-zlema/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A16",
      "name": "Least-Squares Moving Average (LSMA)",
      "headline": null,
      "slug": "least-squares-moving-average-lsma",
      "path": "technical-indicators/trend-smoothing/least-squares-moving-average-lsma",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/least-squares-moving-average-lsma",
        "entry": "leastSquaresMovingAverageLsma",
        "params": [
          "input"
        ],
        "exports": [
          "leastSquaresMovingAverageLsma"
        ],
        "archetype": "series-transform",
        "signature": "leastSquaresMovingAverageLsma(input)"
      },
      "api": {
        "summary": "Fits an ordinary least-squares line to each `period`-bar window of close and reports the value of that line at the window's last bar, so the curve follows the local trend rather than its average.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of OHLCV records with strictly increasing `timestamp`, finite `open`, `high`, `low`, `close` and non-negative `volume`, all sharing one adjustment basis. From `parameters` this topic reads only `period`, an integer of at least 2, default 14, which is the regression window length.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single key, `value`, the fitted endpoint `intercept + slope * (period - 1)`. The first `period - 1` entries are null while the window fills, so with the default period `ready_at` is 13."
        },
        "warmup": {
          "count": "period - 1 bars (13 at the default period of 14)",
          "value": "null",
          "note": "A regression needs a full `period`-bar window, so the first fit lands at index `period - 1` and `ready_at` is that index. A window with zero variance in its bar index is given a slope of 0 rather than dividing by zero."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty or a bar violates the OHLCV contract",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "leastSquaresMovingAverageLsma({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F01-A16",
          "title": "Least-Squares Moving Average (LSMA)",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 101.85696110114286
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a16/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a16/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a16/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a16/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Least-Squares Moving Average (LSMA) calculation flow",
            "source": "flowchart LR\n    A[\"an oldest-to-newest finite price series, declared price so\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Least-Squares Moving Average (LSMA) convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Least-Squares Moving Average (LSMA) readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/least-squares-moving-average-lsma/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/least-squares-moving-average-lsma/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A17",
      "name": "Variable Index Dynamic Average (VIDYA)",
      "headline": null,
      "slug": "variable-index-dynamic-average-vidya",
      "path": "technical-indicators/trend-smoothing/variable-index-dynamic-average-vidya",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/variable-index-dynamic-average-vidya",
        "entry": "variableIndexDynamicAverageVidya",
        "params": [
          "input"
        ],
        "exports": [
          "variableIndexDynamicAverageVidya"
        ],
        "archetype": "series-transform",
        "signature": "variableIndexDynamicAverageVidya(input)"
      },
      "api": {
        "summary": "Scales the EMA constant `2 / (period + 1)` by the absolute Chande momentum oscillator of the last `period` one-bar changes, so the average speeds up in one-sided moves and nearly freezes when gains and losses balance.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of OHLCV records with strictly increasing `timestamp`, finite `open`, `high`, `low`, `close` and non-negative `volume`, all sharing one adjustment basis. From `parameters` this topic reads only `period`, an integer of at least 2, default 14, which sets both the base smoothing constant and the momentum lookback.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single key, `value`. It is null for the first `period` bars, is seeded with the close at index `period`, and recurses from there, so with the default period `ready_at` is 14."
        },
        "warmup": {
          "count": "period bars (14 at the default period of 14)",
          "value": "null",
          "note": "The momentum window is taken over one-bar changes, whose own first entry is undefined, so the loop starts at index `period` and seeds `value` with the close there. `ready_at` is that index. A window with no gains and no losses scores 0, which holds the average flat."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty or a bar violates the OHLCV contract",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "variableIndexDynamicAverageVidya({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F01-A17",
          "title": "Variable Index Dynamic Average (VIDYA)",
          "state": "calculated",
          "ready": true,
          "ready_at": 14,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 104.2557087704378
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a17/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a17/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a17/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a17/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Variable Index Dynamic Average (VIDYA) calculation flow",
            "source": "flowchart LR\n    A[\"an oldest-to-newest finite price series, declared price so\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Variable Index Dynamic Average (VIDYA) convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Variable Index Dynamic Average (VIDYA) readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/variable-index-dynamic-average-vidya/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/variable-index-dynamic-average-vidya/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A18",
      "name": "McGinley Dynamic",
      "headline": null,
      "slug": "mcginley-dynamic",
      "path": "technical-indicators/trend-smoothing/mcginley-dynamic",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/mcginley-dynamic",
        "entry": "mcginleyDynamic",
        "params": [
          "input"
        ],
        "exports": [
          "mcginleyDynamic"
        ],
        "archetype": "series-transform",
        "signature": "mcginleyDynamic(input)"
      },
      "api": {
        "summary": "Tracks close with McGinley's self-adjusting recursion, dividing the step toward the new close by `k * period * (close / previous) ** 4` so the line accelerates when price runs away from it and coasts when price is near.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of OHLCV records with strictly increasing `timestamp`, finite `open`, `high`, `low`, `close` and non-negative `volume`, all sharing one adjustment basis. From `parameters` this topic reads `period`, an integer of at least 2, default 14, and `k`, a finite number of at least 0.000001 that damps the step size, default 0.6.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single key, `value`. There is no warm-up: the first bar is seeded with its own close, so `ready_at` is 0 and no entry is ever null."
        },
        "warmup": {
          "count": "0 bars",
          "value": "not applicable",
          "note": "Unlike the windowed smoothers in this family, the recursion is seeded directly from the first close, so `value` is populated from index 0 and `ready_at` is 0. `period` still controls how fast the line converges, it just does not delay the first print."
        },
        "errors": [
          {
            "when": "`parameters.k` is not a finite number of at least 0.000001",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty or a bar violates the OHLCV contract",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "mcginleyDynamic({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F01-A18",
          "title": "McGinley Dynamic",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "value": [
              100,
              100.19828143903013,
              100.49269368385441,
              100.78556845098775,
              101.010298670479,
              101.15287258809037
            ]
          },
          "latest": {
            "value": 103.52627869720108
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a18/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a18/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a18/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a18/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "McGinley Dynamic calculation flow",
            "source": "flowchart LR\n    A[\"an oldest-to-newest finite price series, declared price so\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected McGinley Dynamic convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "McGinley Dynamic readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/mcginley-dynamic/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/mcginley-dynamic/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A19",
      "name": "Jurik-Style Moving Average Design",
      "headline": null,
      "slug": "jurik-style-moving-average-design",
      "path": "technical-indicators/trend-smoothing/jurik-style-moving-average-design",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/jurik-style-moving-average-design",
        "entry": "jurikStyleMovingAverageDesign",
        "params": [
          "input"
        ],
        "exports": [
          "jurikStyleMovingAverageDesign"
        ],
        "archetype": "series-transform",
        "signature": "jurikStyleMovingAverageDesign(input)"
      },
      "api": {
        "summary": "Demonstrates the Jurik design idea without the proprietary internals: the current absolute bar-to-bar change is scored against its own `period`-bar average, and that score stretches a base smoothing constant between a floor and a ceiling before the average is applied to close.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of OHLCV records with strictly increasing `timestamp`, finite `open`, `high`, `low`, `close` and non-negative `volume`, all sharing one adjustment basis. From `parameters` this topic reads `period`, an integer of at least 2, default 14; `base_alpha`, default `2 / (period + 1)`; `volatility_sensitivity`, a finite number of at least 0, default 0.5; `minimum_alpha`, default 0.01; and `maximum_alpha`, default 0.8. The three alpha parameters must each be finite and between 0 and 1.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry two keys, `value` and `alpha`, the smoothed close and the clamped constant actually used at that bar. Both are null for the first `period - 1` bars while the change baseline fills, so with the default period `ready_at` is 13."
        },
        "warmup": {
          "count": "period - 1 bars (13 at the default period of 14)",
          "value": "null",
          "note": "The baseline is a simple average of `period` absolute changes, so nothing prints until index `period - 1`, where `value` is seeded with the close. `ready_at` is that index. A baseline of zero scores 0, which leaves `base_alpha` unmodified before clamping."
        },
        "errors": [
          {
            "when": "`parameters.base_alpha`, `minimum_alpha`, or `maximum_alpha` is not a finite number between 0 and 1",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.volatility_sensitivity` is negative or not finite",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.period` is not an integer of at least 2",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "jurikStyleMovingAverageDesign({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F01-A19",
          "title": "Jurik-Style Moving Average Design",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "alpha": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 103.48082066608806,
            "alpha": 0.17224435187656212
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a19/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a19/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a19/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a19/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Jurik-Style Moving Average Design calculation flow",
            "source": "flowchart LR\n    A[\"an oldest-to-newest finite price series, declared price so\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Jurik-Style Moving Average Design convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Jurik-Style Moving Average Design readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/jurik-style-moving-average-design/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/jurik-style-moving-average-design/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A20",
      "name": "Volume-Weighted Moving Average (VWMA)",
      "headline": null,
      "slug": "volume-weighted-moving-average-vwma",
      "path": "technical-indicators/trend-smoothing/volume-weighted-moving-average-vwma",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/volume-weighted-moving-average-vwma",
        "entry": "volumeWeightedMovingAverageVwma",
        "params": [
          "input"
        ],
        "exports": [
          "volumeWeightedMovingAverageVwma"
        ],
        "archetype": "series-transform",
        "signature": "volumeWeightedMovingAverageVwma(input)"
      },
      "api": {
        "summary": "Averages close over a rolling `period`-bar window using each bar's `volume` as its weight, so heavily traded bars pull the line further than quiet ones.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of OHLCV records with strictly increasing `timestamp`, finite `open`, `high`, `low`, `close` and non-negative `volume`, all sharing one adjustment basis. The `volume` field is load-bearing here rather than merely validated. From `parameters` this topic reads only `period`, an integer of at least 2, default 14.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single key, `value`. The first `period - 1` entries are null while the window fills, so with the default period `ready_at` is 13, and any later window whose volumes sum to zero is also null rather than a division by zero."
        },
        "warmup": {
          "count": "period - 1 bars (13 at the default period of 14)",
          "value": "null",
          "note": "The first weighted average lands at index `period - 1`, which is `ready_at`. Nulls can also reappear after the warm-up on any window of entirely zero-volume bars, so callers should not assume the series is dense once it starts."
        },
        "errors": [
          {
            "when": "a bar carries a negative `volume`",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty or a bar violates the OHLCV contract",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "volumeWeightedMovingAverageVwma({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F01-A20",
          "title": "Volume-Weighted Moving Average (VWMA)",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 104.80335290167793
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a20/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a20/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a20/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a20/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Volume-Weighted Moving Average (VWMA) calculation flow",
            "source": "flowchart LR\n    A[\"an oldest-to-newest finite price series, declared price so\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Volume-Weighted Moving Average (VWMA) convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Volume-Weighted Moving Average (VWMA) readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/volume-weighted-moving-average-vwma/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/volume-weighted-moving-average-vwma/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A21",
      "name": "Quadratic-Weighted Moving Average",
      "headline": null,
      "slug": "quadratic-weighted-moving-average",
      "path": "technical-indicators/trend-smoothing/quadratic-weighted-moving-average",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/quadratic-weighted-moving-average",
        "entry": "quadraticWeightedMovingAverage",
        "params": [
          "input"
        ],
        "exports": [
          "quadraticWeightedMovingAverage"
        ],
        "archetype": "series-transform",
        "signature": "quadraticWeightedMovingAverage(input)"
      },
      "api": {
        "summary": "Averages close over a rolling `period`-bar window with weights that grow as the square of a bar's position, 1, 4, 9 and so on, front-loading recency harder than the linear weights of a WMA.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of OHLCV records with strictly increasing `timestamp`, finite `open`, `high`, `low`, `close` and non-negative `volume`, all sharing one adjustment basis. From `parameters` this topic reads only `period`, an integer of at least 2, default 14, which sets both the window length and the number of squared weights.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single key, `value`, the weight-normalised average. The first `period - 1` entries are null while the window fills, so with the default period `ready_at` is 13."
        },
        "warmup": {
          "count": "period - 1 bars (13 at the default period of 14)",
          "value": "null",
          "note": "The average prints only from a complete `period`-bar window, so `ready_at` is `period - 1`. Weights are divided by their own sum, so the output stays in price units."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty or a bar violates the OHLCV contract",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "quadraticWeightedMovingAverage({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F01-A21",
          "title": "Quadratic-Weighted Moving Average",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 103.03978017722167
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a21/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a21/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a21/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a21/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Quadratic-Weighted Moving Average calculation flow",
            "source": "flowchart LR\n    A[\"an oldest-to-newest finite price series, declared price so\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Quadratic-Weighted Moving Average convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Quadratic-Weighted Moving Average readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/quadratic-weighted-moving-average/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/quadratic-weighted-moving-average/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A22",
      "name": "Gaussian Moving Average",
      "headline": null,
      "slug": "gaussian-moving-average",
      "path": "technical-indicators/trend-smoothing/gaussian-moving-average",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/gaussian-moving-average",
        "entry": "gaussianMovingAverage",
        "params": [
          "input"
        ],
        "exports": [
          "gaussianMovingAverage"
        ],
        "archetype": "series-transform",
        "signature": "gaussianMovingAverage(input)"
      },
      "api": {
        "summary": "Averages close under a Gaussian weight curve centred at `offset * (period - 1)` with width `period / sigma`. The default offset of 0.5 puts the peak in the middle of the window, which is what separates this from ALMA's recency-shifted variant of the same kernel.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of OHLCV records with strictly increasing `timestamp`, finite `open`, `high`, `low`, `close` and non-negative `volume`, all sharing one adjustment basis. From `parameters` this topic reads `period`, an integer of at least 2, default 14; `offset`, a finite number between 0 and 1, default 0.5; and `sigma`, a finite number of at least 0.000001, default 6.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single key, `value`, the weight-normalised average. The first `period - 1` entries are null while the window fills, so with the default period `ready_at` is 13."
        },
        "warmup": {
          "count": "period - 1 bars (13 at the default period of 14)",
          "value": "null",
          "note": "The kernel is applied only to complete `period`-bar windows, so `ready_at` is `period - 1`. Centring the peak makes the filter symmetric in weighting but the output is still computed only from bars up to and including the current one."
        },
        "errors": [
          {
            "when": "`parameters.offset` is not a finite number between 0 and 1",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.sigma` is not a finite number of at least 0.000001",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.period` is not an integer of at least 2",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "gaussianMovingAverage({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F01-A22",
          "title": "Gaussian Moving Average",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 105.48707931937686
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a22/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a22/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a22/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a22/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Gaussian Moving Average calculation flow",
            "source": "flowchart LR\n    A[\"an oldest-to-newest finite price series, declared price so\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Gaussian Moving Average convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Gaussian Moving Average readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/gaussian-moving-average/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/gaussian-moving-average/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A23",
      "name": "Ehlers Super Smoother Filter",
      "headline": null,
      "slug": "ehlers-super-smoother-filter",
      "path": "technical-indicators/trend-smoothing/ehlers-super-smoother-filter",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/ehlers-super-smoother-filter",
        "entry": "ehlersSuperSmootherFilter",
        "params": [
          "input"
        ],
        "exports": [
          "ehlersSuperSmootherFilter"
        ],
        "archetype": "series-transform",
        "signature": "ehlersSuperSmootherFilter(input)"
      },
      "api": {
        "summary": "Applies Ehlers' two-pole Butterworth recursion to the two-bar mean of close, with feedback coefficients derived from `period` via `exp(-sqrt(2) * pi / period)`, suppressing high-frequency noise with far less lag than a moving average of the same length.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of OHLCV records with strictly increasing `timestamp`, finite `open`, `high`, `low`, `close` and non-negative `volume`, all sharing one adjustment basis. From `parameters` this topic reads only `period`, an integer of at least 2, default 14, which sets the filter's cutoff.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single key, `value`. There is no warm-up: the first two bars pass their close through unchanged before the recursion takes over, so `ready_at` is 0 and no entry is ever null."
        },
        "warmup": {
          "count": "0 bars",
          "value": "not applicable",
          "note": "The recursion needs two prior outputs, and the implementation supplies them by seeding indices 0 and 1 with the raw close rather than emitting nulls. `ready_at` is therefore 0, but the first few values are effectively unfiltered and should be treated as transient."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty or a bar violates the OHLCV contract",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "ehlersSuperSmootherFilter({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F01-A23",
          "title": "Ehlers Super Smoother Filter",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "value": [
              100,
              101.78791214,
              102.82125123553132,
              103.40896247631203,
              103.66519218875615,
              103.63747331288454
            ]
          },
          "latest": {
            "value": 103.12560464143179
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a23/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a23/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a23/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a23/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Ehlers Super Smoother Filter calculation flow",
            "source": "flowchart LR\n    A[\"an oldest-to-newest finite price series, declared price so\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Ehlers Super Smoother Filter convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Ehlers Super Smoother Filter readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/ehlers-super-smoother-filter/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/ehlers-super-smoother-filter/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A24",
      "name": "Ehlers Instantaneous Trendline",
      "headline": null,
      "slug": "ehlers-instantaneous-trendline",
      "path": "technical-indicators/trend-smoothing/ehlers-instantaneous-trendline",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/ehlers-instantaneous-trendline",
        "entry": "ehlersInstantaneousTrendline",
        "params": [
          "input"
        ],
        "exports": [
          "ehlersInstantaneousTrendline"
        ],
        "archetype": "series-transform",
        "signature": "ehlersInstantaneousTrendline(input)"
      },
      "api": {
        "summary": "Splits close into a smoothed centre line and what is left over: the trendline is an EMA of `max(4, period)` and the detrended series is the bar's close minus that trendline.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of OHLCV records with strictly increasing `timestamp`, finite `open`, `high`, `low`, `close` and non-negative `volume`, all sharing one adjustment basis. From `parameters` this topic reads only `period`, an integer of at least 2, default 14. The EMA length is `max(4, period)`, so periods of 2 and 3 are both treated as 4.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry two keys, `trendline` and `detrended`. Both are null for the first `max(4, period) - 1` bars while the EMA seeds, so with the default period `ready_at` is 13."
        },
        "warmup": {
          "count": "max(4, period) - 1 bars (13 at the default period of 14)",
          "value": "null",
          "note": "The EMA seeds from the mean of its first `max(4, period)` closes, so the trendline first prints at index `max(4, period) - 1`, and `detrended` is null wherever the trendline is. `ready_at` is that index."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, or a timestamp that does not increase",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "ehlersInstantaneousTrendline({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F01-A24",
          "title": "Ehlers Instantaneous Trendline",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "trendline": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "detrended": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "trendline": 103.6493158929627,
            "detrended": -3.6585014229627006
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a24/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a24/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a24/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a24/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Ehlers Instantaneous Trendline calculation flow",
            "source": "flowchart LR\n    A[\"an oldest-to-newest finite price series, declared price so\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Ehlers Instantaneous Trendline convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Ehlers Instantaneous Trendline readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/ehlers-instantaneous-trendline/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/ehlers-instantaneous-trendline/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-F02-A09",
      "name": "Average Directional Index Rating (ADXR)",
      "headline": null,
      "slug": "average-directional-index-rating-adxr",
      "path": "technical-indicators/trend-systems/average-directional-index-rating-adxr",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/average-directional-index-rating-adxr",
        "entry": "averageDirectionalIndexRatingAdxr",
        "params": [
          "input"
        ],
        "exports": [
          "averageDirectionalIndexRatingAdxr"
        ],
        "archetype": "series-transform",
        "signature": "averageDirectionalIndexRatingAdxr(input)"
      },
      "api": {
        "summary": "Runs the Wilder directional-movement system over the bars and returns the smoothed `plus_di`, `minus_di` and `adx` lines together with `adxr`, the average of the current `adx` and the `adx` from `period` bars earlier.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the OHLCV series, validated for finite prices, strictly increasing `timestamp`, a single adjustment `basis`, non-negative `volume`, and a high and low that bracket the other prices. From `parameters` this topic reads only `period` (integer, minimum 2, default 14), which drives the Wilder smoothing of true range and directional movement and also sets the ADXR lookback.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `plus_di`, `minus_di`, `adx` and `adxr`. Each line has its own warm-up, so the four do not start on the same bar."
        },
        "warmup": {
          "count": "period bars (14 by default)",
          "value": "null",
          "note": "With the default period every series is null through index 13. `plus_di` and `minus_di` first resolve at index 14, so `ready_at` is 14; `adx` starts at index 27 and `adxr` at index 41, and both stay null until then."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, a timestamp not greater than the previous one, or a high below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "averageDirectionalIndexRatingAdxr({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F02-A09",
          "title": "Average Directional Index Rating (ADXR)",
          "state": "calculated",
          "ready": true,
          "ready_at": 14,
          "series": {
            "plus_di": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "minus_di": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "adx": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "adxr": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "plus_di": 7.883000058107942,
            "minus_di": 17.582637107405173,
            "adx": 21.37786648985954,
            "adxr": 21.42643518653003
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a09/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a09/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a09/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a09/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Average Directional Index Rating (ADXR) calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations with explicit window, s\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Average Directional Index Rating (ADXR) convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Average Directional Index Rating (ADXR) readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/average-directional-index-rating-adxr/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/average-directional-index-rating-adxr/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A10",
      "name": "Vortex Indicator (+VI/−VI)",
      "headline": null,
      "slug": "vortex-indicator-vi-vi",
      "path": "technical-indicators/trend-systems/vortex-indicator-vi-vi",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/vortex-indicator-vi-vi",
        "entry": "vortexIndicatorViVi",
        "params": [
          "input"
        ],
        "exports": [
          "vortexIndicatorViVi"
        ],
        "archetype": "series-transform",
        "signature": "vortexIndicatorViVi(input)"
      },
      "api": {
        "summary": "Sums the upward and downward vortex movements over a rolling window and divides each by the summed true range, giving the paired `plus_vi` and `minus_vi` lines.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the OHLCV series, validated for finite prices, strictly increasing `timestamp`, a single adjustment `basis`, non-negative `volume`, and a high and low that bracket the other prices. From `parameters` this topic reads only `period` (integer, minimum 2, default 14), the length of both the movement sums and the true-range sum.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `plus_vi` and `minus_vi`, and nothing else. Both share one warm-up, and either is null on any bar whose true-range sum is zero."
        },
        "warmup": {
          "count": "period bars (14 by default)",
          "value": "null",
          "note": "The vortex movements are undefined on the first bar, so the first complete window ends one bar later than a plain rolling sum would: with the default period, indices 0 to 13 are null and `ready_at` is 14."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, a timestamp not greater than the previous one, or a high below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "vortexIndicatorViVi({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F02-A10",
          "title": "Vortex Indicator (+VI/−VI)",
          "state": "calculated",
          "ready": true,
          "ready_at": 14,
          "series": {
            "plus_vi": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "minus_vi": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "plus_vi": 0.91078566552092,
            "minus_vi": 1.0406526774370142
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a10/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a10/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a10/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a10/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Vortex Indicator (+VI/−VI) calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations with explicit window, s\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Vortex Indicator (+VI/−VI) convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Vortex Indicator (+VI/−VI) readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/vortex-indicator-vi-vi/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/vortex-indicator-vi-vi/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A11",
      "name": "Choppiness Index",
      "headline": null,
      "slug": "choppiness-index",
      "path": "technical-indicators/trend-systems/choppiness-index",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/choppiness-index",
        "entry": "choppinessIndex",
        "params": [
          "input"
        ],
        "exports": [
          "choppinessIndex"
        ],
        "archetype": "series-transform",
        "signature": "choppinessIndex(input)"
      },
      "api": {
        "summary": "Compares the summed true range over a window against the window's own high-to-low span, on a base-10 log scale normalised by the window length, so a trending stretch scores low and a choppy one scores high.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the OHLCV series, validated for finite prices, strictly increasing `timestamp`, a single adjustment `basis`, non-negative `volume`, and a high and low that bracket the other prices. From `parameters` this topic reads only `period` (integer, minimum 2, default 14), the length of the true-range sum and of the highest-high and lowest-low window.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key. After the warm-up a bar is still null when the window's highest high equals its lowest low, or when the summed true range is not positive."
        },
        "warmup": {
          "count": "period - 1 bars (13 by default)",
          "value": "null",
          "note": "`value` is null until the first full window closes, so with the default period indices 0 to 12 are null and `ready_at` is 13."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, a timestamp not greater than the previous one, or a high below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "choppinessIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F02-A11",
          "title": "Choppiness Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 52.26756132464782
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a11/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a11/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a11/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a11/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Choppiness Index calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations with explicit window, s\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Choppiness Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Choppiness Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/choppiness-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/choppiness-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A12",
      "name": "Trend Intensity Index",
      "headline": null,
      "slug": "trend-intensity-index",
      "path": "technical-indicators/trend-systems/trend-intensity-index",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/trend-intensity-index",
        "entry": "trendIntensityIndex",
        "params": [
          "input"
        ],
        "exports": [
          "trendIntensityIndex"
        ],
        "archetype": "series-transform",
        "signature": "trendIntensityIndex(input)"
      },
      "api": {
        "summary": "Splits each close into the part above and the part below a simple moving average, sums each part over a second window, and reports the upside sum as a percentage of the two sums combined.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the OHLCV series, validated for finite prices, strictly increasing `timestamp`, a single adjustment `basis`, non-negative `volume`, and a high and low that bracket the other prices. From `parameters` this topic reads `period` (integer, minimum 2, default 14), the moving-average length, and `intensity_period` (integer, minimum 2, defaulting to whatever `period` resolved to), the length of the deviation sums.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key, a percentage between 0 and 100. A bar is null when both deviation sums are zero, which happens only when every close in the window sits exactly on its moving average. The two windows stack, which is what makes the warm-up longer than callers expect."
        },
        "warmup": {
          "count": "period + intensity_period - 2 bars (26 by default)",
          "value": "null",
          "note": "The moving average needs `period` bars, and the deviation sum then needs `intensity_period` non-null deviations on top of it. With both at the default 14 the first value lands at index 26, so `ready_at` is 26."
        },
        "errors": [
          {
            "when": "`parameters.period` or `parameters.intensity_period` is present but is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, a timestamp not greater than the previous one, or a high below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "trendIntensityIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F02-A12",
          "title": "Trend Intensity Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 26,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 57.21213322600646
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a12/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a12/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a12/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a12/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Trend Intensity Index calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations with explicit window, s\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Trend Intensity Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Trend Intensity Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/trend-intensity-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/trend-intensity-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A13",
      "name": "QStick",
      "headline": null,
      "slug": "qstick",
      "path": "technical-indicators/trend-systems/qstick",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/qstick",
        "entry": "qstick",
        "params": [
          "input"
        ],
        "exports": [
          "qstick"
        ],
        "archetype": "series-transform",
        "signature": "qstick(input)"
      },
      "api": {
        "summary": "Averages the candle body, close minus open, over a rolling window, so a positive reading means the window closed above its opens more often than not.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the OHLCV series, validated for finite prices, strictly increasing `timestamp`, a single adjustment `basis`, non-negative `volume`, and a high and low that bracket the other prices. From `parameters` this topic reads only `period` (integer, minimum 2, default 14), the length of the simple moving average taken over the bodies.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key, in price units rather than a normalised scale. Once the warm-up is past, every bar has a value."
        },
        "warmup": {
          "count": "period - 1 bars (13 by default)",
          "value": "null",
          "note": "The moving average emits nothing until `period` bodies exist, so with the default period indices 0 to 12 are null and `ready_at` is 13."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, a timestamp not greater than the previous one, or a high below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "qstick({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F02-A13",
          "title": "QStick",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -0.018717604285716862
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a13/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a13/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a13/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a13/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "QStick calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations with explicit window, s\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected QStick convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "QStick readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/qstick/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/qstick/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A14",
      "name": "Mass Index",
      "headline": null,
      "slug": "mass-index",
      "path": "technical-indicators/trend-systems/mass-index",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/mass-index",
        "entry": "massIndex",
        "params": [
          "input"
        ],
        "exports": [
          "massIndex"
        ],
        "archetype": "series-transform",
        "signature": "massIndex(input)"
      },
      "api": {
        "summary": "Takes the ratio of a 9-period EMA of the high-low range to the 9-period EMA of that EMA, then sums the ratio over a longer window, so range expansion after a contraction pushes the total up.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the OHLCV series, validated for finite prices, strictly increasing `timestamp`, a single adjustment `basis`, non-negative `volume`, and a high and low that bracket the other prices. From `parameters` this topic reads `sum_period` (integer, minimum 2, default 25), the length of the final sum; the two EMA lengths are fixed at 9 and are not configurable. `period` is still validated by the family, with the same integer-minimum-2 rule, but no branch of this calculation uses it.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key. The chained EMAs make the warm-up much longer than `sum_period` alone suggests."
        },
        "warmup": {
          "count": "sum_period + 15 bars (40 by default)",
          "value": "null",
          "note": "The first EMA resolves at index 8, the EMA of that EMA at index 16, and the sum then needs `sum_period` consecutive ratios. With the default `sum_period` of 25 the first value lands at index 40, so `ready_at` is 40."
        },
        "errors": [
          {
            "when": "`parameters.sum_period` or `parameters.period` is present but is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, a timestamp not greater than the previous one, or a high below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * sum_period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "massIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F02-A14",
          "title": "Mass Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 40,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 25.15692329607823
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a14/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a14/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a14/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a14/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Mass Index calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations with explicit window, s\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Mass Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Mass Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/mass-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/mass-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A15",
      "name": "Vertical Horizontal Filter",
      "headline": null,
      "slug": "vertical-horizontal-filter",
      "path": "technical-indicators/trend-systems/vertical-horizontal-filter",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/vertical-horizontal-filter",
        "entry": "verticalHorizontalFilter",
        "params": [
          "input"
        ],
        "exports": [
          "verticalHorizontalFilter"
        ],
        "archetype": "series-transform",
        "signature": "verticalHorizontalFilter(input)"
      },
      "api": {
        "summary": "Divides the highest-to-lowest close span over a window by the sum of the absolute bar-to-bar close changes in that same window, separating directed movement from back-and-forth movement.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the OHLCV series, validated for finite prices, strictly increasing `timestamp`, a single adjustment `basis`, non-negative `volume`, and a high and low that bracket the other prices. From `parameters` this topic reads only `period` (integer, minimum 2, default 14), the length of both the close extremes and the absolute change sum.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key. A bar is null when the summed absolute change is zero, that is when every close in the window is identical, since that would divide by zero. The warm-up is one window."
        },
        "warmup": {
          "count": "period - 1 bars (13 by default)",
          "value": "null",
          "note": "Both the extremes and the change sum need a full window, so with the default period indices 0 to 12 are null and `ready_at` is 13."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, a timestamp not greater than the previous one, or a high below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "verticalHorizontalFilter({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F02-A15",
          "title": "Vertical Horizontal Filter",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 0.6258523821746035
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a15/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a15/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a15/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a15/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Vertical Horizontal Filter calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations with explicit window, s\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Vertical Horizontal Filter convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Vertical Horizontal Filter readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/vertical-horizontal-filter/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/vertical-horizontal-filter/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A16",
      "name": "Random Walk Index (High/Low)",
      "headline": null,
      "slug": "random-walk-index-high-low",
      "path": "technical-indicators/trend-systems/random-walk-index-high-low",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/random-walk-index-high-low",
        "entry": "randomWalkIndexHighLow",
        "params": [
          "input"
        ],
        "exports": [
          "randomWalkIndexHighLow"
        ],
        "archetype": "series-transform",
        "signature": "randomWalkIndexHighLow(input)"
      },
      "api": {
        "summary": "Scores how far price has travelled against what a random walk would explain, by taking the largest displacement-over-expected-range ratio across every lookback length from 2 up to `period`, once upward and once downward.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the OHLCV series, validated for finite prices, strictly increasing `timestamp`, a single adjustment `basis`, non-negative `volume`, and a high and low that bracket the other prices. From `parameters` this topic reads only `period` (integer, minimum 2, default 14), the longest lookback the maximum is taken over.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `high` and `low`, the upward and downward random-walk scores, and no combined line. Both share one warm-up."
        },
        "warmup": {
          "count": "period bars (14 by default)",
          "value": "null",
          "note": "The scan starts at index `period` because the longest lookback reaches that far back, so with the default period indices 0 to 13 are null and `ready_at` is 14."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, a timestamp not greater than the previous one, or a high below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period^2)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "randomWalkIndexHighLow({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F02-A16",
          "title": "Random Walk Index (High/Low)",
          "state": "calculated",
          "ready": true,
          "ready_at": 14,
          "series": {
            "high": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "low": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "high": 0.16740171878302448,
            "low": 1.3252890024447201
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a16/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a16/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a16/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a16/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Random Walk Index (High/Low) calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations with explicit window, s\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Random Walk Index (High/Low) convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Random Walk Index (High/Low) readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/random-walk-index-high-low/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/random-walk-index-high-low/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A17",
      "name": "Trend Trigger Factor",
      "headline": null,
      "slug": "trend-trigger-factor",
      "path": "technical-indicators/trend-systems/trend-trigger-factor",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/trend-trigger-factor",
        "entry": "trendTriggerFactor",
        "params": [
          "input"
        ],
        "exports": [
          "trendTriggerFactor"
        ],
        "archetype": "series-transform",
        "signature": "trendTriggerFactor(input)"
      },
      "api": {
        "summary": "Compares the current window's high and low against the immediately prior window's, and reports the buy-minus-sell power as a percentage of their average.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the OHLCV series, validated for finite prices, strictly increasing `timestamp`, a single adjustment `basis`, non-negative `volume`, and a high and low that bracket the other prices. From `parameters` this topic reads only `period` (integer, minimum 2, default 14), the length of each of the two adjacent windows.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key. A bar is null when the buy and sell powers average to zero. Because two windows are compared, the warm-up is twice the period."
        },
        "warmup": {
          "count": "2 * period - 1 bars (27 by default)",
          "value": "null",
          "note": "The first bar with both a current and a prior window is at index `2 * period - 1`, so with the default period indices 0 to 26 are null and `ready_at` is 27."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, a timestamp not greater than the previous one, or a high below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "trendTriggerFactor({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F02-A17",
          "title": "Trend Trigger Factor",
          "state": "calculated",
          "ready": true,
          "ready_at": 27,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -1.7406369378325768
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a17/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a17/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a17/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a17/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Trend Trigger Factor calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations with explicit window, s\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Trend Trigger Factor convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Trend Trigger Factor readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/trend-trigger-factor/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/trend-trigger-factor/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A18",
      "name": "Directional Trend Index",
      "headline": null,
      "slug": "directional-trend-index",
      "path": "technical-indicators/trend-systems/directional-trend-index",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/directional-trend-index",
        "entry": "directionalTrendIndex",
        "params": [
          "input"
        ],
        "exports": [
          "directionalTrendIndex"
        ],
        "archetype": "series-transform",
        "signature": "directionalTrendIndex(input)"
      },
      "api": {
        "summary": "Wilder-smooths the net of the upward high moves against the downward low moves, and divides it by the smoothed total of both, giving a signed percentage that runs from -100 to 100.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the OHLCV series, validated for finite prices, strictly increasing `timestamp`, a single adjustment `basis`, non-negative `volume`, and a high and low that bracket the other prices. From `parameters` this topic reads only `period` (integer, minimum 2, default 14), the Wilder smoothing length applied to both the difference and the total.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key. A bar is null when the smoothed total of the moves is zero. The warm-up runs one bar past the period because the first bar has no prior high or low to move from."
        },
        "warmup": {
          "count": "period bars (14 by default)",
          "value": "null",
          "note": "The move series is undefined on the first bar, so the Wilder seed closes at index `period`: with the default period indices 0 to 13 are null and `ready_at` is 14."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, a timestamp not greater than the previous one, or a high below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "directionalTrendIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F02-A18",
          "title": "Directional Trend Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 14,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -37.841395713258386
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a18/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a18/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a18/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a18/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Directional Trend Index calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations with explicit window, s\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Directional Trend Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Directional Trend Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/directional-trend-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/directional-trend-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A19",
      "name": "Trend Strength Index",
      "headline": null,
      "slug": "trend-strength-index",
      "path": "technical-indicators/trend-systems/trend-strength-index",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/trend-strength-index",
        "entry": "trendStrengthIndex",
        "params": [
          "input"
        ],
        "exports": [
          "trendStrengthIndex"
        ],
        "archetype": "series-transform",
        "signature": "trendStrengthIndex(input)"
      },
      "api": {
        "summary": "Measures the absolute gap between a fast and a slow EMA of the close in units of average true range, so the spread is comparable across volatility regimes.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the OHLCV series, validated for finite prices, strictly increasing `timestamp`, a single adjustment `basis`, non-negative `volume`, and a high and low that bracket the other prices. From `parameters` this topic reads `fast_period` (integer, minimum 2, default 7), `slow_period` (integer, default 21, and required to be at least `fast_period` plus 1), and `period` (integer, minimum 2, default 14) for the average true range in the denominator.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key, a non-negative ratio. A bar is null when the average true range is zero. The slow EMA dominates the warm-up."
        },
        "warmup": {
          "count": "slow_period - 1 bars (20 by default)",
          "value": "null",
          "note": "The slow EMA resolves at index `slow_period - 1`, later than both the fast EMA and the average true range at the defaults, so with 21 and 14 indices 0 to 19 are null and `ready_at` is 20."
        },
        "errors": [
          {
            "when": "`parameters.slow_period` is not an integer of at least `fast_period` plus 1",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.fast_period` or `parameters.period` is present but is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, a timestamp not greater than the previous one, or a high below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "trendStrengthIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F02-A19",
          "title": "Trend Strength Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 20,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 0.4082377773242465
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a19/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a19/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a19/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a19/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Trend Strength Index calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations with explicit window, s\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Trend Strength Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Trend Strength Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/trend-strength-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/trend-strength-index/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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation flow",
            "source": "flowchart LR\n  A[\"Finalized finalized close\"] --> B[\"Validate order, alignment, and finite values\"]\n  B --> C[\"Close change\"]\n  C --> D[\"Gain / loss split\"]\n  D --> E[\"Wilder smoothing\"]\n  E --> F{\"History and denominator valid?\"}\n  F -- \"No · short history\" --> G[\"warming-up + reason\"]\n  F -- \"No · no finite scale\" --> H[\"undefined + reason\"]\n  F -- \"Yes\" --> I[\"RSI ratio\"]\n  I --> J[\"ready + aligned component trace\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation flow",
            "source": "flowchart LR\n  A[\"Finalized finalized high, low, close\"] --> B[\"Validate order, alignment, and finite values\"]\n  B --> C[\"Trailing range\"]\n  C --> D[\"Fast %K\"]\n  D --> E[\"Slow %K SMA\"]\n  E --> F{\"History and denominator valid?\"}\n  F -- \"No · short history\" --> G[\"warming-up + reason\"]\n  F -- \"No · no finite scale\" --> H[\"undefined + reason\"]\n  F -- \"Yes\" --> I[\"Slow %D SMA\"]\n  I --> J[\"ready + aligned component trace\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation flow",
            "source": "flowchart LR\n  A[\"Finalized finalized close\"] --> B[\"Validate order, alignment, and finite values\"]\n  B --> C[\"Wilder RSI\"]\n  C --> D[\"RSI range\"]\n  D --> E[\"Raw StochRSI\"]\n  E --> F{\"History and denominator valid?\"}\n  F -- \"No · short history\" --> G[\"warming-up + reason\"]\n  F -- \"No · no finite scale\" --> H[\"undefined + reason\"]\n  F -- \"Yes\" --> I[\"Smoothed %K / %D\"]\n  I --> J[\"ready + aligned component trace\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation flow",
            "source": "flowchart LR\n  A[\"Finalized finalized high, low, close\"] --> B[\"Validate order, alignment, and finite values\"]\n  B --> C[\"Trailing range\"]\n  C --> D[\"Distance from high\"]\n  D --> E[\"Normalize by range\"]\n  E --> F{\"History and denominator valid?\"}\n  F -- \"No · short history\" --> G[\"warming-up + reason\"]\n  F -- \"No · no finite scale\" --> H[\"undefined + reason\"]\n  F -- \"Yes\" --> I[\"Williams %R\"]\n  I --> J[\"ready + aligned component trace\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation flow",
            "source": "flowchart LR\n  A[\"Finalized finalized high, low, close\"] --> B[\"Validate order, alignment, and finite values\"]\n  B --> C[\"Typical price\"]\n  C --> D[\"Window mean\"]\n  D --> E[\"Mean deviation\"]\n  E --> F{\"History and denominator valid?\"}\n  F -- \"No · short history\" --> G[\"warming-up + reason\"]\n  F -- \"No · no finite scale\" --> H[\"undefined + reason\"]\n  F -- \"Yes\" --> I[\"Scaled displacement\"]\n  I --> J[\"ready + aligned component trace\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation flow",
            "source": "flowchart LR\n  A[\"Finalized finalized high, low, close plus previous close\"] --> B[\"Validate order, alignment, and finite values\"]\n  B --> C[\"BP and true range\"]\n  C --> D[\"Three ratio-of-sums windows\"]\n  D --> E[\"4/2/1 weighting\"]\n  E --> F{\"History and denominator valid?\"}\n  F -- \"No · short history\" --> G[\"warming-up + reason\"]\n  F -- \"No · no finite scale\" --> H[\"undefined + reason\"]\n  F -- \"Yes\" --> I[\"Ultimate oscillator\"]\n  I --> J[\"ready + aligned component trace\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation flow",
            "source": "flowchart LR\n  A[\"Finalized finalized close\"] --> B[\"Validate order, alignment, and finite values\"]\n  B --> C[\"Signed / absolute change\"]\n  C --> D[\"Long EMA\"]\n  D --> E[\"Short EMA\"]\n  E --> F{\"History and denominator valid?\"}\n  F -- \"No · short history\" --> G[\"warming-up + reason\"]\n  F -- \"No · no finite scale\" --> H[\"undefined + reason\"]\n  F -- \"Yes\" --> I[\"Signed-to-magnitude ratio\"]\n  I --> J[\"ready + aligned component trace\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation flow",
            "source": "flowchart LR\n  A[\"Finalized strictly positive finalized close\"] --> B[\"Validate order, alignment, and finite values\"]\n  B --> C[\"Price RSI\"]\n  C --> D[\"Streak and streak RSI\"]\n  D --> E[\"Prior-only return rank\"]\n  E --> F{\"History and denominator valid?\"}\n  F -- \"No · short history\" --> G[\"warming-up + reason\"]\n  F -- \"No · no finite scale\" --> H[\"undefined + reason\"]\n  F -- \"Yes\" --> I[\"Three-way mean\"]\n  I --> J[\"ready + aligned component trace\"]"
          }
        ]
      },
      "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-F03-A09",
      "name": "Absolute Price Oscillator",
      "headline": null,
      "slug": "absolute-price-oscillator",
      "path": "technical-indicators/momentum/absolute-price-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/absolute-price-oscillator",
        "entry": "absolutePriceOscillator",
        "params": [
          "input"
        ],
        "exports": [
          "absolutePriceOscillator"
        ],
        "archetype": "series-transform",
        "signature": "absolutePriceOscillator(input)"
      },
      "api": {
        "summary": "Subtracts a slow EMA of `close` from a fast EMA of `close`, leaving the momentum spread in price units rather than as a percentage.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `fast_period` (integer >= 2, default 5) and `slow_period` (integer >= `fast_period` + 1, default 34). `period` (default 14) is validated by the shared momentum preamble but is not used here.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, holding the fast EMA minus the slow EMA at each bar. Both EMAs seed from the simple average of their first full window, so the series opens with a null warm-up prefix."
        },
        "warmup": {
          "count": "slow_period - 1 bars (33 with the default 34)",
          "value": "null",
          "note": "`value` stays null until the slow EMA is seeded, which happens at index `slow_period - 1`; `ready_at` is 33 on the canonical fixture."
        },
        "errors": [
          {
            "when": "`slow_period` is not an integer greater than `fast_period`",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `high` is below its `open`, `close`, or `low`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "absolutePriceOscillator({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A09",
          "title": "Absolute Price Oscillator",
          "state": "calculated",
          "ready": true,
          "ready_at": 33,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -2.0125312416213603
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a09/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a09/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a09/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a09/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Absolute Price Oscillator calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Absolute Price Oscillator convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Absolute Price Oscillator readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/absolute-price-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/absolute-price-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A10",
      "name": "Rate-of-Change Variants (ROC, ROCP, and ROCR)",
      "headline": null,
      "slug": "rate-of-change-variants-roc-rocp-and-rocr",
      "path": "technical-indicators/momentum/rate-of-change-variants-roc-rocp-and-rocr",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/rate-of-change-variants-roc-rocp-and-rocr",
        "entry": "rateOfChangeVariantsRocRocpAndRocr",
        "params": [
          "input"
        ],
        "exports": [
          "rateOfChangeVariantsRocRocpAndRocr"
        ],
        "archetype": "series-transform",
        "signature": "rateOfChangeVariantsRocRocpAndRocr(input)"
      },
      "api": {
        "summary": "Expresses the same `period`-bar price ratio three ways: as a percentage, as a proportion, and as the raw ratio.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `period` (integer >= 2, default 14), the lookback in bars. The preamble also validates `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for either throws even though this topic does not use them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry three keys. `rocp` is `close / close[-period] - 1`, `roc` is 100 times `rocp`, and `rocr` is `1 + rocp`. All three share the same null warm-up prefix."
        },
        "warmup": {
          "count": "period bars (14 by default)",
          "value": "null",
          "note": "The first `period` bars have no reference close, so all three keys are null and `ready_at` is `period`, 14 on the canonical fixture. A close of exactly 0 `period` bars back also produces a null later in the series."
        },
        "errors": [
          {
            "when": "`period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` are not strictly increasing by `timestamp`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "rateOfChangeVariantsRocRocpAndRocr({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A10",
          "title": "Rate-of-Change Variants (ROC, ROCP, and ROCR)",
          "state": "calculated",
          "ready": true,
          "ready_at": 14,
          "series": {
            "roc": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "rocp": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "rocr": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "roc": -3.185757936162148,
            "rocp": -0.03185757936162148,
            "rocr": 0.9681424206383785
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a10/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a10/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a10/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a10/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Rate-of-Change Variants (ROC, ROCP, and ROCR) calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Rate-of-Change Variants (ROC, ROCP, and ROCR) convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Rate-of-Change Variants (ROC, ROCP, and ROCR) readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/rate-of-change-variants-roc-rocp-and-rocr/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/rate-of-change-variants-roc-rocp-and-rocr/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A11",
      "name": "Price Momentum (MOM)",
      "headline": null,
      "slug": "price-momentum-mom",
      "path": "technical-indicators/momentum/price-momentum-mom",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/price-momentum-mom",
        "entry": "priceMomentumMom",
        "params": [
          "input"
        ],
        "exports": [
          "priceMomentumMom"
        ],
        "archetype": "series-transform",
        "signature": "priceMomentumMom(input)"
      },
      "api": {
        "summary": "The plain price difference between the current close and the close `period` bars earlier.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `period` (integer >= 2, default 14), the lookback in bars. The preamble also validates `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for either throws even though this topic does not use them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, equal to `close - close[-period]` in price units. The opening bars are null for the length of the warm-up."
        },
        "warmup": {
          "count": "period bars (14 by default)",
          "value": "null",
          "note": "No reference close exists for the first `period` bars, so `ready_at` is `period`, 14 on the canonical fixture. Unlike the rate-of-change form there is no division, so no later nulls appear."
        },
        "errors": [
          {
            "when": "`period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `close` is missing or not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "priceMomentumMom({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A11",
          "title": "Price Momentum (MOM)",
          "state": "calculated",
          "ready": true,
          "ready_at": 14,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -3.2902858499999894
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a11/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a11/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a11/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a11/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Price Momentum (MOM) calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Price Momentum (MOM) convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Price Momentum (MOM) readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/price-momentum-mom/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/price-momentum-mom/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A12",
      "name": "Chande Momentum Oscillator",
      "headline": null,
      "slug": "chande-momentum-oscillator",
      "path": "technical-indicators/momentum/chande-momentum-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/chande-momentum-oscillator",
        "entry": "chandeMomentumOscillator",
        "params": [
          "input"
        ],
        "exports": [
          "chandeMomentumOscillator"
        ],
        "archetype": "series-transform",
        "signature": "chandeMomentumOscillator(input)"
      },
      "api": {
        "summary": "Compares summed up-closes against summed down-closes over a `period` window and scales the imbalance to a -100..100 range.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `period` (integer >= 2, default 14), the window over which gains and losses are summed. The preamble also validates `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for either throws even though this topic does not use them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, equal to 100 times (gain sum - loss sum) divided by (gain sum + loss sum) over the trailing window. The series opens with a null warm-up prefix."
        },
        "warmup": {
          "count": "period bars (14 by default)",
          "value": "null",
          "note": "The one-bar change is null at index 0, so the first complete window of changes ends at index `period`; `ready_at` is 14 on the canonical fixture. A window in which every close is unchanged makes gains plus losses zero and yields a null there too."
        },
        "errors": [
          {
            "when": "`period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is not an array, or is empty",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "chandeMomentumOscillator({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A12",
          "title": "Chande Momentum Oscillator",
          "state": "calculated",
          "ready": true,
          "ready_at": 14,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -25.17047643492069
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a12/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a12/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a12/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a12/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Chande Momentum Oscillator calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Chande Momentum Oscillator convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Chande Momentum Oscillator readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/chande-momentum-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/chande-momentum-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A13",
      "name": "Awesome Oscillator",
      "headline": null,
      "slug": "awesome-oscillator",
      "path": "technical-indicators/momentum/awesome-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/awesome-oscillator",
        "entry": "awesomeOscillator",
        "params": [
          "input"
        ],
        "exports": [
          "awesomeOscillator"
        ],
        "archetype": "series-transform",
        "signature": "awesomeOscillator(input)"
      },
      "api": {
        "summary": "Subtracts a 34-period simple average of the median price from a 5-period one, measuring the gap between short and long swing momentum.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. This topic reads no keys from `parameters`: the median price is `(high + low) / 2` and the 5 and 34 window lengths are fixed in the implementation. The shared momentum preamble still validates `period` (default 14), `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for any of them throws even though this topic reads none of them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, the 5-period simple average of the median price minus its 34-period simple average. The series opens with a null warm-up prefix set by the longer window."
        },
        "warmup": {
          "count": "33 bars",
          "value": "null",
          "note": "The 34-period average is the binding constraint, so the first non-null lands at index 33 and `ready_at` is 33 on the canonical fixture. The lengths are hard-coded, so this warm-up does not move with `parameters`."
        },
        "errors": [
          {
            "when": "`period` is supplied but is not an integer >= 2, even though this topic ignores it",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `low` is above its `open`, `high`, or `close`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "awesomeOscillator({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A13",
          "title": "Awesome Oscillator",
          "state": "calculated",
          "ready": true,
          "ready_at": 33,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -2.700632041029408
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a13/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a13/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a13/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a13/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Awesome Oscillator calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Awesome Oscillator convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Awesome Oscillator readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/awesome-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/awesome-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A14",
      "name": "Accelerator Oscillator",
      "headline": null,
      "slug": "accelerator-oscillator",
      "path": "technical-indicators/momentum/accelerator-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/accelerator-oscillator",
        "entry": "acceleratorOscillator",
        "params": [
          "input"
        ],
        "exports": [
          "acceleratorOscillator"
        ],
        "archetype": "series-transform",
        "signature": "acceleratorOscillator(input)"
      },
      "api": {
        "summary": "Subtracts a 5-period simple average of the Awesome Oscillator from the oscillator itself, isolating the change in momentum rather than its level.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. This topic reads no keys from `parameters`: the underlying 5/34 median-price averages and the 5-period signal are all fixed lengths. The shared momentum preamble still validates `period` (default 14), `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for any of them throws even though this topic reads none of them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, the Awesome Oscillator minus its own 5-period simple average. Its warm-up is longer than the Awesome Oscillator's because the signal average must itself fill."
        },
        "warmup": {
          "count": "37 bars",
          "value": "null",
          "note": "The Awesome Oscillator first resolves at index 33, and its 5-period average needs four more bars, so the first non-null lands at index 37 and `ready_at` is 37 on the canonical fixture."
        },
        "errors": [
          {
            "when": "`period` is supplied but is not an integer >= 2, even though this topic ignores it",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `volume` is negative",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "acceleratorOscillator({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A14",
          "title": "Accelerator Oscillator",
          "state": "calculated",
          "ready": true,
          "ready_at": 37,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -1.2120760466823697
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a14/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a14/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a14/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a14/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Accelerator Oscillator calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Accelerator Oscillator convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Accelerator Oscillator readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/accelerator-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/accelerator-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A15",
      "name": "TRIX",
      "headline": null,
      "slug": "trix",
      "path": "technical-indicators/momentum/trix",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/trix",
        "entry": "trix",
        "params": [
          "input"
        ],
        "exports": [
          "trix"
        ],
        "archetype": "series-transform",
        "signature": "trix(input)"
      },
      "api": {
        "summary": "The one-bar percentage rate of change of a triple-smoothed EMA of `close`, which strips most short-cycle noise before measuring momentum.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `period` (integer >= 2, default 14), used for all three EMA passes. The preamble also validates `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for either throws even though this topic does not use them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, equal to 100 times the one-bar ratio change of the triple EMA. Three stacked EMA seeds plus the one-bar difference make the warm-up prefix the longest of the simple momentum topics."
        },
        "warmup": {
          "count": "3 * (period - 1) + 1 bars (40 with the default 14)",
          "value": "null",
          "note": "Each EMA pass costs `period - 1` bars to seed and the closing rate-of-change costs one more, so `ready_at` is 40 on the canonical fixture. A previous triple-EMA value of exactly 0 also yields a null."
        },
        "errors": [
          {
            "when": "`period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` do not all share one adjustment `basis`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "trix({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A15",
          "title": "TRIX",
          "state": "calculated",
          "ready": true,
          "ready_at": 40,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -0.006461491886777804
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a15/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a15/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a15/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a15/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "TRIX calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected TRIX convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "TRIX readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/trix/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/trix/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A16",
      "name": "Stochastic Momentum Index",
      "headline": null,
      "slug": "stochastic-momentum-index",
      "path": "technical-indicators/momentum/stochastic-momentum-index",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/stochastic-momentum-index",
        "entry": "stochasticMomentumIndex",
        "params": [
          "input"
        ],
        "exports": [
          "stochasticMomentumIndex"
        ],
        "archetype": "series-transform",
        "signature": "stochasticMomentumIndex(input)"
      },
      "api": {
        "summary": "Measures where `close` sits relative to the midpoint of the `period` high-low range, then double-smooths both the distance and the range before scaling to -100..100.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `period` (integer >= 2, default 14), the lookback for the highest high and lowest low. The two 3-period EMA smoothing passes are fixed. The preamble also validates `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for either throws even though this topic does not use them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, equal to 200 times the double-smoothed distance from the range midpoint divided by the double-smoothed range. The series opens with a null warm-up prefix covering the range lookback and both smoothing passes."
        },
        "warmup": {
          "count": "period - 1 + 4 bars (17 with the default 14)",
          "value": "null",
          "note": "The range resolves at index `period - 1` and each 3-period EMA costs two more bars, so `ready_at` is 17 on the canonical fixture. A double-smoothed range of exactly 0 also yields a null."
        },
        "errors": [
          {
            "when": "`period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `high` is below its `low`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "stochasticMomentumIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A16",
          "title": "Stochastic Momentum Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 17,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -57.30649740900241
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a16/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a16/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a16/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a16/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Stochastic Momentum Index calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Stochastic Momentum Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Stochastic Momentum Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/stochastic-momentum-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/stochastic-momentum-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A17",
      "name": "Relative Vigor Index",
      "headline": null,
      "slug": "relative-vigor-index",
      "path": "technical-indicators/momentum/relative-vigor-index",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/relative-vigor-index",
        "entry": "relativeVigorIndex",
        "params": [
          "input"
        ],
        "exports": [
          "relativeVigorIndex"
        ],
        "archetype": "series-transform",
        "signature": "relativeVigorIndex(input)"
      },
      "api": {
        "summary": "Divides the `period` average of the candle body by the `period` average of the candle range, reading closing vigour relative to the day's travel.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `period` (integer >= 2, default 14), the window for both simple averages. The preamble also validates `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for either throws even though this topic does not use them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, the `period` simple average of `close - open` divided by the `period` simple average of `high - low`. This is the ratio form only; no signal line is emitted. A null warm-up prefix precedes the first reading."
        },
        "warmup": {
          "count": "period - 1 bars (13 with the default 14)",
          "value": "null",
          "note": "Both simple averages complete at index `period - 1`, so `ready_at` is 13 on the canonical fixture. A window whose average range is exactly 0 also yields a null."
        },
        "errors": [
          {
            "when": "`period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `open` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "relativeVigorIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A17",
          "title": "Relative Vigor Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -0.006058146501095789
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a17/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a17/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a17/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a17/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Relative Vigor Index calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Relative Vigor Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Relative Vigor Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/relative-vigor-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/relative-vigor-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A18",
      "name": "Relative Momentum Index",
      "headline": null,
      "slug": "relative-momentum-index",
      "path": "technical-indicators/momentum/relative-momentum-index",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/relative-momentum-index",
        "entry": "relativeMomentumIndex",
        "params": [
          "input"
        ],
        "exports": [
          "relativeMomentumIndex"
        ],
        "archetype": "series-transform",
        "signature": "relativeMomentumIndex(input)"
      },
      "api": {
        "summary": "An RSI-shaped 0..100 reading built on the change over `momentum_lag` bars instead of the one-bar change, Wilder-smoothed over `period`.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `period` (integer >= 2, default 14) for the Wilder smoothing and `momentum_lag` (integer >= 1, default 5) for the change interval. The preamble also validates `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for either throws even though this topic does not use them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, equal to 100 times the smoothed up-move divided by the sum of the smoothed up- and down-moves. The warm-up prefix stacks the momentum lag on top of the Wilder seed."
        },
        "warmup": {
          "count": "momentum_lag + period - 1 bars (18 with the defaults 5 and 14)",
          "value": "null",
          "note": "The lagged change is null for the first `momentum_lag` bars and the Wilder average then needs `period` consecutive values to seed, so `ready_at` is 18 on the canonical fixture. Smoothed up- and down-moves that sum to exactly 0 also yield a null."
        },
        "errors": [
          {
            "when": "`momentum_lag` is not an integer >= 1",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` are not strictly increasing by `timestamp`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "relativeMomentumIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A18",
          "title": "Relative Momentum Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 18,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 36.68238933579245
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a18/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a18/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a18/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a18/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Relative Momentum Index calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Relative Momentum Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Relative Momentum Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/relative-momentum-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/relative-momentum-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A19",
      "name": "Fisher Transform",
      "headline": null,
      "slug": "fisher-transform",
      "path": "technical-indicators/momentum/fisher-transform",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/fisher-transform",
        "entry": "fisherTransform",
        "params": [
          "input"
        ],
        "exports": [
          "fisherTransform"
        ],
        "archetype": "series-transform",
        "signature": "fisherTransform(input)"
      },
      "api": {
        "summary": "Rescales `close` to its position within the `period` high-low range of closes, clamps it just inside -1..1, and applies the Fisher transform to give the result near-Gaussian tails.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `period` (integer >= 2, default 14), the lookback for the highest and lowest close. The preamble also validates `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for either throws even though this topic does not use them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, equal to `0.5 * ln((1 + x) / (1 - x))` where `x` is the range position clamped to +/-0.999. This is the unsmoothed form; no EMA is applied to the normalised input and no trigger line is emitted. A null warm-up prefix precedes the first reading."
        },
        "warmup": {
          "count": "period - 1 bars (13 with the default 14)",
          "value": "null",
          "note": "The rolling highest and lowest close both complete at index `period - 1`, so `ready_at` is 13 on the canonical fixture. A window whose highest and lowest close are equal also yields a null."
        },
        "errors": [
          {
            "when": "`period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `timestamp` is missing or not a non-empty string",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "fisherTransform({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A19",
          "title": "Fisher Transform",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -3.8002011672502
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a19/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a19/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a19/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a19/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Fisher Transform calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Fisher Transform convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Fisher Transform readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/fisher-transform/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/fisher-transform/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A20",
      "name": "Inverse Fisher Transform",
      "headline": null,
      "slug": "inverse-fisher-transform",
      "path": "technical-indicators/momentum/inverse-fisher-transform",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/inverse-fisher-transform",
        "entry": "inverseFisherTransform",
        "params": [
          "input"
        ],
        "exports": [
          "inverseFisherTransform"
        ],
        "archetype": "series-transform",
        "signature": "inverseFisherTransform(input)"
      },
      "api": {
        "summary": "Squashes a scaled one-bar close change into -1..1 with the inverse Fisher transform, which is the hyperbolic tangent of the scaled input.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `source_scale` (finite number >= 0, default 0.1), the multiplier applied to the one-bar close change before the transform. The shared momentum preamble still validates `period` (default 14), `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for any of them throws even though this topic reads none of them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, equal to `(exp(2y) - 1) / (exp(2y) + 1)` where `y` is `source_scale` times the one-bar close change. Unlike the other momentum topics there is no null warm-up prefix."
        },
        "warmup": {
          "count": "none",
          "value": "0 at the first bar",
          "note": "The first bar has no prior close, and the missing change is treated as 0 rather than propagated, so `value` is 0 at index 0 and `ready_at` is 0 on the canonical fixture."
        },
        "errors": [
          {
            "when": "`source_scale` is negative or not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters` is supplied but is not an object",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "inverseFisherTransform({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A20",
          "title": "Inverse Fisher Transform",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "value": [
              0,
              0.17691016466328705,
              0.11617573521901128,
              0.027727270131488183,
              -0.04007677888344102,
              -0.05619814139841276
            ]
          },
          "latest": {
            "value": -0.1468007517369847
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a20/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a20/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a20/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a20/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Inverse Fisher Transform calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Inverse Fisher Transform convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Inverse Fisher Transform readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/inverse-fisher-transform/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/inverse-fisher-transform/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A21",
      "name": "Schaff Trend Cycle",
      "headline": null,
      "slug": "schaff-trend-cycle",
      "path": "technical-indicators/momentum/schaff-trend-cycle",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/schaff-trend-cycle",
        "entry": "schaffTrendCycle",
        "params": [
          "input"
        ],
        "exports": [
          "schaffTrendCycle"
        ],
        "archetype": "series-transform",
        "signature": "schaffTrendCycle(input)"
      },
      "api": {
        "summary": "Runs the MACD line through two stochastic passes, each followed by a 3-period EMA, turning a trend measure into a 0..100 cycle oscillator.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `cycle_period` (integer >= 2, default 10), the window for both stochastic passes. The 12/26 MACD lengths and the two 3-period EMA passes are fixed. The shared momentum preamble still validates `period` (default 14), `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for any of them throws even though this topic reads none of them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, the twice-stochastic, twice-EMA-smoothed MACD line. Four stacked stages make this the longest warm-up prefix in the family."
        },
        "warmup": {
          "count": "25 + 2 * (cycle_period + 1) bars (47 with the default cycle_period of 10)",
          "value": "null",
          "note": "The MACD line resolves at index 25 once the 26-period EMA seeds; each stochastic pass then costs `cycle_period - 1` bars and each 3-period EMA two more, so `ready_at` is 47 on the canonical fixture."
        },
        "errors": [
          {
            "when": "`cycle_period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * cycle_period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "schaffTrendCycle({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A21",
          "title": "Schaff Trend Cycle",
          "state": "calculated",
          "ready": true,
          "ready_at": 47,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 6.810924814132896
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a21/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a21/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a21/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a21/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Schaff Trend Cycle calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Schaff Trend Cycle convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Schaff Trend Cycle readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/schaff-trend-cycle/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/schaff-trend-cycle/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A22",
      "name": "Quantitative Qualitative Estimation (QQE)",
      "headline": null,
      "slug": "quantitative-qualitative-estimation-qqe",
      "path": "technical-indicators/momentum/quantitative-qualitative-estimation-qqe",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/quantitative-qualitative-estimation-qqe",
        "entry": "quantitativeQualitativeEstimationQqe",
        "params": [
          "input"
        ],
        "exports": [
          "quantitativeQualitativeEstimationQqe"
        ],
        "archetype": "series-transform",
        "signature": "quantitativeQualitativeEstimationQqe(input)"
      },
      "api": {
        "summary": "Smooths a Wilder RSI with a 5-period EMA and wraps it in a volatility band derived from a double Wilder-smoothed average of the smoothed RSI's own absolute change.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `period` (integer >= 2, default 14) for the RSI and both band smoothing passes, and `factor` (finite number >= 0, default 4.236), the band multiplier. The 5-period EMA on the RSI is fixed. The preamble also validates `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for either throws even though this topic does not use them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry three keys: `rsi` (the smoothed RSI), and `upper` and `lower` (the smoothed RSI plus and minus `factor` times the smoothed band width). The three keys do not share one warm-up: `rsi` resolves well before the bands."
        },
        "warmup": {
          "count": "18 bars for `rsi`, 45 bars for `upper` and `lower` (with the default period of 14)",
          "value": "null",
          "note": "`ready_at` reports the first bar at which any series is non-null, so it is 18 on the canonical fixture, driven by `rsi` alone. `upper` and `lower` stay null until index 45, because the band adds a one-bar difference and two more Wilder passes on top; callers that read the bands must wait past `ready_at`."
        },
        "errors": [
          {
            "when": "`factor` is negative or not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "`period` is not an integer >= 2",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "quantitativeQualitativeEstimationQqe({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A22",
          "title": "Quantitative Qualitative Estimation (QQE)",
          "state": "calculated",
          "ready": true,
          "ready_at": 18,
          "series": {
            "rsi": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "upper": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "rsi": 38.502818289066866,
            "upper": 48.90739630995648,
            "lower": 28.098240268177246
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a22/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a22/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a22/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a22/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Quantitative Qualitative Estimation (QQE) calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Quantitative Qualitative Estimation (QQE) convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Quantitative Qualitative Estimation (QQE) readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/quantitative-qualitative-estimation-qqe/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/quantitative-qualitative-estimation-qqe/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A23",
      "name": "WaveTrend Oscillator",
      "headline": null,
      "slug": "wavetrend-oscillator",
      "path": "technical-indicators/momentum/wavetrend-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/wavetrend-oscillator",
        "entry": "wavetrendOscillator",
        "params": [
          "input"
        ],
        "exports": [
          "wavetrendOscillator"
        ],
        "archetype": "series-transform",
        "signature": "wavetrendOscillator(input)"
      },
      "api": {
        "summary": "Builds a CCI-style channel index from the typical price against its own 10-period EMA and mean deviation, then smooths it into a fast line and a slower trigger.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. This topic reads no keys from `parameters`: the typical price is `(high + low + close) / 3` and the 10, 10, 21 and 4 lengths are fixed in the implementation. The shared momentum preamble still validates `period` (default 14), `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for any of them throws even though this topic reads none of them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry two keys: `wt1`, the 21-period EMA of the channel index, and `wt2`, the 4-period simple average of `wt1`. The two keys have different warm-ups, `wt2` trailing `wt1` by three bars."
        },
        "warmup": {
          "count": "38 bars for `wt1`, 41 bars for `wt2`",
          "value": "null",
          "note": "The 10-period EMA of typical price seeds at index 9, its mean-deviation EMA at 18, and the 21-period EMA at 38, so `ready_at` is 38 on the canonical fixture; `wt2` remains null until index 41. A mean deviation of exactly 0 also yields a null."
        },
        "errors": [
          {
            "when": "`period` is supplied but is not an integer >= 2, even though this topic ignores it",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `high` is below its `open`, `close`, or `low`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "wavetrendOscillator({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A23",
          "title": "WaveTrend Oscillator",
          "state": "calculated",
          "ready": true,
          "ready_at": 38,
          "series": {
            "wt1": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "wt2": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "wt1": -25.94276818159519,
            "wt2": -13.858032304032271
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a23/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a23/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a23/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a23/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "WaveTrend Oscillator calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected WaveTrend Oscillator convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "WaveTrend Oscillator readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/wavetrend-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/wavetrend-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A24",
      "name": "Know Sure Thing (KST)",
      "headline": null,
      "slug": "know-sure-thing-kst",
      "path": "technical-indicators/momentum/know-sure-thing-kst",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/know-sure-thing-kst",
        "entry": "knowSureThingKst",
        "params": [
          "input"
        ],
        "exports": [
          "knowSureThingKst"
        ],
        "archetype": "series-transform",
        "signature": "knowSureThingKst(input)"
      },
      "api": {
        "summary": "Weights four smoothed rate-of-change readings taken over different lookbacks into a single momentum line, with a simple-average signal.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. This topic reads no keys from `parameters`: the four components are fixed at lookback/smoothing/weight of 10/10/1, 15/10/2, 20/10/3 and 30/15/4, and the signal is a fixed 9-period average. The shared momentum preamble still validates `period` (default 14), `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for any of them throws even though this topic reads none of them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry two keys: `kst`, the weighted sum of the four smoothed percentage rate-of-change components, and `signal`, its 9-period simple average. The slowest component sets the `kst` warm-up and `signal` trails it."
        },
        "warmup": {
          "count": "44 bars for `kst`, 52 bars for `signal`",
          "value": "null",
          "note": "`kst` requires every component, and the slowest (30-bar lookback smoothed over 15) does not resolve until index 44, so `ready_at` is 44 on the canonical fixture; `signal` remains null until index 52."
        },
        "errors": [
          {
            "when": "`period` is supplied but is not an integer >= 2, even though this topic ignores it",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` are not strictly increasing by `timestamp`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "knowSureThingKst({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A24",
          "title": "Know Sure Thing (KST)",
          "state": "calculated",
          "ready": true,
          "ready_at": 44,
          "series": {
            "kst": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "signal": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "kst": 2.8616450824068522,
            "signal": 4.992752189344036
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a24/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a24/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a24/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a24/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Know Sure Thing (KST) calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Know Sure Thing (KST) convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Know Sure Thing (KST) readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/know-sure-thing-kst/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/know-sure-thing-kst/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A25",
      "name": "Chande Forecast Oscillator",
      "headline": null,
      "slug": "chande-forecast-oscillator",
      "path": "technical-indicators/momentum/chande-forecast-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/chande-forecast-oscillator",
        "entry": "chandeForecastOscillator",
        "params": [
          "input"
        ],
        "exports": [
          "chandeForecastOscillator"
        ],
        "archetype": "series-transform",
        "signature": "chandeForecastOscillator(input)"
      },
      "api": {
        "summary": "Fits a least-squares line to the last `period` closes and reports how far the actual close sits from that line's endpoint, as a percentage of price.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `period` (integer >= 2, default 14), the window for the regression fit. The preamble also validates `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for either throws even though this topic does not use them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, equal to 100 times (close - regression endpoint) divided by close. A null warm-up prefix covers the bars before a full regression window exists."
        },
        "warmup": {
          "count": "period - 1 bars (13 with the default 14)",
          "value": "null",
          "note": "The first complete regression window ends at index `period - 1`, so `ready_at` is 13 on the canonical fixture. A close of exactly 0 also yields a null because it is the divisor."
        },
        "errors": [
          {
            "when": "`period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `close` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "chandeForecastOscillator({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A25",
          "title": "Chande Forecast Oscillator",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -1.8663180623483664
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a25/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a25/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a25/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a25/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Chande Forecast Oscillator calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Chande Forecast Oscillator convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Chande Forecast Oscillator readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/chande-forecast-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/chande-forecast-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A26",
      "name": "Detrended Price Oscillator",
      "headline": null,
      "slug": "detrended-price-oscillator",
      "path": "technical-indicators/momentum/detrended-price-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/detrended-price-oscillator",
        "entry": "detrendedPriceOscillator",
        "params": [
          "input"
        ],
        "exports": [
          "detrendedPriceOscillator"
        ],
        "archetype": "series-transform",
        "signature": "detrendedPriceOscillator(input)"
      },
      "api": {
        "summary": "Removes the trend by subtracting the current `period` simple average from a close shifted back half that window, leaving the short cycle around the average.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `period` (integer >= 2, default 14), which sets both the average length and the backward shift of `floor(period / 2) + 1` bars. The preamble also validates `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for either throws even though this topic does not use them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, equal to the close from `floor(period / 2) + 1` bars ago minus the current `period` simple average. Note the average is not itself displaced; the shift is applied to the price. A null warm-up prefix precedes the first reading."
        },
        "warmup": {
          "count": "period - 1 bars (13 with the default 14)",
          "value": "null",
          "note": "The shift is 8 bars with the default `period` of 14, so the simple average, not the shift, is the binding constraint and `ready_at` is 13 on the canonical fixture."
        },
        "errors": [
          {
            "when": "`period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` do not all share one adjustment `basis`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "detrendedPriceOscillator({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A26",
          "title": "Detrended Price Oscillator",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 2.2657371385714242
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a26/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a26/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a26/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a26/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Detrended Price Oscillator calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Detrended Price Oscillator convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Detrended Price Oscillator readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/detrended-price-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/detrended-price-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A27",
      "name": "Balance of Power",
      "headline": null,
      "slug": "balance-of-power",
      "path": "technical-indicators/momentum/balance-of-power",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/balance-of-power",
        "entry": "balanceOfPower",
        "params": [
          "input"
        ],
        "exports": [
          "balanceOfPower"
        ],
        "archetype": "series-transform",
        "signature": "balanceOfPower(input)"
      },
      "api": {
        "summary": "Divides each candle's body by its full range, giving a per-bar -1..1 reading of how much of the session's travel the close managed to keep.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. This topic reads no keys from `parameters`: the calculation is a single-bar ratio with no lookback. The shared momentum preamble still validates `period` (default 14), `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for any of them throws even though this topic reads none of them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, equal to `(close - open) / (high - low)` for each bar. There is no warm-up prefix, so the first bar already carries a reading."
        },
        "warmup": {
          "count": "none",
          "value": "a value at the first bar",
          "note": "Every bar is self-contained, so `ready_at` is 0 on the canonical fixture. The one exception is a bar whose `high` equals its `low`, which has no range to divide by and yields a null at that index only."
        },
        "errors": [
          {
            "when": "`period` is supplied but is not an integer >= 2, even though this topic ignores it",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `open`, `high`, `low`, or `close` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "balanceOfPower({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A27",
          "title": "Balance of Power",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "value": [
              0,
              0.08915474022958794,
              0.13295729760191172,
              0.13829149989844472,
              0.1089777590581788,
              0.04557026577834851
            ]
          },
          "latest": {
            "value": -0.11921211954649767
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a27/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a27/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a27/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a27/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Balance of Power calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Balance of Power convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Balance of Power readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/balance-of-power/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/balance-of-power/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A28",
      "name": "Psychological Line",
      "headline": null,
      "slug": "psychological-line",
      "path": "technical-indicators/momentum/psychological-line",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/psychological-line",
        "entry": "psychologicalLine",
        "params": [
          "input"
        ],
        "exports": [
          "psychologicalLine"
        ],
        "archetype": "series-transform",
        "signature": "psychologicalLine(input)"
      },
      "api": {
        "summary": "The percentage of the last `period` bars that closed above the previous close, a plain count of how one-sided recent sentiment has been.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `period` (integer >= 2, default 14), the count window. The preamble also validates `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for either throws even though this topic does not use them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, equal to 100 times the number of up-closes in the trailing window divided by `period`. A null warm-up prefix precedes the first reading."
        },
        "warmup": {
          "count": "period bars (14 by default)",
          "value": "null",
          "note": "The first bar has no prior close to compare against, so the first complete window ends at index `period` rather than `period - 1`; `ready_at` is 14 on the canonical fixture."
        },
        "errors": [
          {
            "when": "`period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `timestamp` is missing or not a non-empty string",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "psychologicalLine({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A28",
          "title": "Psychological Line",
          "state": "calculated",
          "ready": true,
          "ready_at": 14,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 28.571428571428573
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a28/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a28/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a28/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a28/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Psychological Line calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Psychological Line convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Psychological Line readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/psychological-line/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/psychological-line/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A29",
      "name": "Pretty Good Oscillator",
      "headline": null,
      "slug": "pretty-good-oscillator",
      "path": "technical-indicators/momentum/pretty-good-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/pretty-good-oscillator",
        "entry": "prettyGoodOscillator",
        "params": [
          "input"
        ],
        "exports": [
          "prettyGoodOscillator"
        ],
        "archetype": "series-transform",
        "signature": "prettyGoodOscillator(input)"
      },
      "api": {
        "summary": "Expresses the gap between `close` and its `period` simple average in units of average true range, so readings stay comparable across volatility regimes.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `period` (integer >= 2, default 14), used for both the simple average and the Wilder-smoothed average true range. The preamble also validates `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for either throws even though this topic does not use them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry one key, `value`, equal to (close - `period` simple average) divided by the `period` ATR. A null warm-up prefix precedes the first reading."
        },
        "warmup": {
          "count": "period - 1 bars (13 with the default 14)",
          "value": "null",
          "note": "True range is defined from the first bar, so the ATR and the simple average both complete at index `period - 1` and `ready_at` is 13 on the canonical fixture. An ATR of exactly 0 also yields a null."
        },
        "errors": [
          {
            "when": "`period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `low` is above its `open`, `high`, or `close`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "prettyGoodOscillator({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A29",
          "title": "Pretty Good Oscillator",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -1.4796507727206563
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a29/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a29/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a29/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a29/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Pretty Good Oscillator calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Pretty Good Oscillator convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Pretty Good Oscillator readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/pretty-good-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/pretty-good-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A30",
      "name": "Price Momentum Oscillator",
      "headline": null,
      "slug": "price-momentum-oscillator",
      "path": "technical-indicators/momentum/price-momentum-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/price-momentum-oscillator",
        "entry": "priceMomentumOscillator",
        "params": [
          "input"
        ],
        "exports": [
          "priceMomentumOscillator"
        ],
        "archetype": "series-transform",
        "signature": "priceMomentumOscillator(input)"
      },
      "api": {
        "summary": "Smooths a heavily scaled one-bar rate of change through two successive EMAs, then adds a third EMA as the signal line.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a chronological array of OHLCV rows, each with a non-empty `timestamp` plus finite `open`, `high`, `low`, `close` and `volume`. This topic reads no keys from `parameters`: the 1000 multiplier and the 10, 14 and 9 EMA lengths are fixed in the implementation. The shared momentum preamble still validates `period` (default 14), `fast_period` (default 5) and `slow_period` (default 34) before branching, so a bad value for any of them throws even though this topic reads none of them.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry two keys: `pmo`, the one-bar rate of change times 1000 smoothed by a 10-period then a 14-period EMA, and `signal`, the 9-period EMA of `pmo`. The two keys have different warm-ups."
        },
        "warmup": {
          "count": "23 bars for `pmo`, 31 bars for `signal`",
          "value": "null",
          "note": "The rate of change is null at index 0, the 10-period EMA seeds at index 10 and the 14-period EMA at index 23, so `ready_at` is 23 on the canonical fixture; `signal` remains null until index 31. A previous close of exactly 0 also yields a null."
        },
        "errors": [
          {
            "when": "`period` is supplied but is not an integer >= 2, even though this topic ignores it",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is not an array, or is empty",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "priceMomentumOscillator({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F03-A30",
          "title": "Price Momentum Oscillator",
          "state": "calculated",
          "ready": true,
          "ready_at": 23,
          "series": {
            "pmo": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "signal": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "pmo": -1.9891476071954817,
            "signal": -0.3983280999092723
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a30/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a30/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a30/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a30/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Price Momentum Oscillator calculation flow",
            "source": "flowchart LR\n    A[\"an ordered price or OHLC series, declared lookbacks, smoot\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Price Momentum Oscillator convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Price Momentum Oscillator readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/price-momentum-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/price-momentum-oscillator/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": [
          {
            "file": "calculation-flow.md",
            "caption": "True Range calculation flow",
            "source": "flowchart LR\n    A[\"Finalized H, L, C\"] --> B{\"First row?\"}\n    B -- \"yes\" --> C[\"TR = H - L\"]\n    B -- \"no\" --> D[\"Compute H-L\"]\n    B -- \"no\" --> E[\"Compute |H-prev C|\"]\n    B -- \"no\" --> F[\"Compute |L-prev C|\"]\n    D --> G[\"Stable maximum and driver\"]\n    E --> G\n    F --> G\n    C --> H[\"Aligned output\"]\n    G --> H"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Average True Range (ATR) calculation flow",
            "source": "flowchart LR\n    A[\"True Range stream\"] --> B{\"n values available?\"}\n    B -- \"no\" --> C[\"ATR = null\"]\n    B -- \"first complete seed\" --> D[\"Arithmetic mean of first n TR\"]\n    B -- \"after seed\" --> E[\"Previous ATR + (TR - previous ATR) / n\"]\n    D --> F[\"Directionless price-unit scale\"]\n    E --> F\n    G[\"Historical revision\"] --> H[\"Recompute every later recursive state\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Bollinger Bands calculation flow",
            "source": "flowchart LR\n    A[\"Trailing n closes\"] --> B[\"SMA middle\"]\n    A --> C[\"Population σ using denominator n\"]\n    B --> D[\"Upper = middle + kσ\"]\n    C --> D\n    B --> E[\"Lower = middle - kσ\"]\n    C --> E\n    D --> F[\"%b location\"]\n    E --> F\n    G[\"σ = 0\"] --> H[\"Bands collapse; %b = null\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Keltner Channels calculation flow",
            "source": "flowchart LR\n    A[\"Close stream\"] --> B[\"SMA-seeded EMA\"]\n    C[\"High, low, previous close\"] --> D[\"True Range\"]\n    D --> E[\"Wilder ATR\"]\n    B --> F{\"Both states ready?\"}\n    E --> F\n    F -- \"no\" --> G[\"Channel = null\"]\n    F -- \"yes\" --> H[\"EMA ± k × ATR\"]\n    I[\"Revision\"] --> J[\"Recompute both recursive paths\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Donchian Channels calculation flow",
            "source": "flowchart LR\n    A[\"Trailing n highs\"] --> B[\"Highest high = upper\"]\n    C[\"Trailing n lows\"] --> D[\"Lowest low = lower\"]\n    B --> E[\"Midrange and width\"]\n    D --> E\n    F[\"New extreme\"] --> G[\"Boundary updates now\"]\n    H[\"Old owner expires\"] --> I{\"Tied owner remains?\"}\n    I -- \"yes\" --> J[\"Boundary unchanged\"]\n    I -- \"no\" --> K[\"Recompute boundary\"]"
          }
        ]
      },
      "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, in percent. Low readings mark contraction and high readings mark expansion; the package makes no claim about what follows either. It is the quantity a 'squeeze' screen ranks on.",
        "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. Must be strictly positive; zero collapses both bands onto the middle and is rejected.",
            "constraints": {
              "exclusive_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 not strictly positive",
            "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Bollinger BandWidth calculation flow",
            "source": "flowchart LR\n    A[\"Trailing closes\"] --> B[\"Bollinger middle, upper, lower\"]\n    B --> C[\"Absolute width = upper - lower\"]\n    C --> D{\"Middle > 0?\"}\n    D -- \"no\" --> E[\"BandWidth = null\"]\n    D -- \"yes\" --> F[\"100 × width / middle\"]\n    F --> G[\"Percent, directionless\"]\n    H[\"Multiply all prices by k>0\"] --> I[\"BandWidth unchanged\"]\n    J[\"Add a constant\"] --> K[\"BandWidth changes\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation flow",
            "source": "flowchart LR\n  A[\"Finalized finalized close and nonnegative volume\"] --> B[\"Validate order, alignment, and finite values\"]\n  B --> C[\"Close comparison\"]\n  C --> D[\"Direction sign\"]\n  D --> E[\"Signed volume\"]\n  E --> F{\"History and denominator valid?\"}\n  F -- \"No · short history\" --> G[\"warming-up + reason\"]\n  F -- \"No · no finite scale\" --> H[\"undefined + reason\"]\n  F -- \"Yes\" --> I[\"Cumulative OBV\"]\n  I --> J[\"ready + aligned component trace\"]"
          },
          {
            "file": "data-basis-reconciliation.md",
            "caption": "Data-basis reconciliation — On-Balance Volume (OBV)",
            "source": "flowchart LR\n    A[\"Same instrument and identifier?\"] -->|Yes| B[\"Same venue or consolidated scope?\"]\n    A -->|No| X[\"Stop: different measurement\"]\n    B -->|Yes| C[\"Same volume unit and bar interval?\"]\n    B -->|No| X\n    C -->|Yes| D[\"Same session and close policy?\"]\n    C -->|No| X\n    D -->|Yes| E[\"Same corrections and price-volume adjustment basis?\"]\n    D -->|No| X\n    E -->|Yes| F[\"Same OBV convention, seed, warm-up, and precision?\"]\n    E -->|No| X\n    F -->|Yes| G[\"Compare intermediate components\"]\n    F -->|No| Y[\"Document convention difference\"]\n    G --> H[\"Compare final output\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation flow",
            "source": "flowchart LR\n  A[\"Finalized finalized high, low, close, and nonnegative volume\"] --> B[\"Validate order, alignment, and finite values\"]\n  B --> C[\"Bar range\"]\n  C --> D[\"Close-location multiplier\"]\n  D --> E[\"Money-flow volume\"]\n  E --> F{\"History and denominator valid?\"}\n  F -- \"No · short history\" --> G[\"warming-up + reason\"]\n  F -- \"No · no finite scale\" --> H[\"undefined + reason\"]\n  F -- \"Yes\" --> I[\"Cumulative A/D Line\"]\n  I --> J[\"ready + aligned component trace\"]"
          },
          {
            "file": "data-basis-reconciliation.md",
            "caption": "Data-basis reconciliation — Accumulation/​Distribution Line",
            "source": "flowchart LR\n    A[\"Same instrument and identifier?\"] -->|Yes| B[\"Same venue or consolidated scope?\"]\n    A -->|No| X[\"Stop: different measurement\"]\n    B -->|Yes| C[\"Same volume unit and bar interval?\"]\n    B -->|No| X\n    C -->|Yes| D[\"Same session and close policy?\"]\n    C -->|No| X\n    D -->|Yes| E[\"Same corrections and price-volume adjustment basis?\"]\n    D -->|No| X\n    E -->|Yes| F[\"Same A/D Line convention, seed, warm-up, and precision?\"]\n    E -->|No| X\n    F -->|Yes| G[\"Compare intermediate components\"]\n    F -->|No| Y[\"Document convention difference\"]\n    G --> H[\"Compare final output\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation flow",
            "source": "flowchart LR\n  A[\"Finalized finalized high, low, close, and nonnegative volume\"] --> B[\"Validate order, alignment, and finite values\"]\n  B --> C[\"Close-location multiplier\"]\n  C --> D[\"Money-flow volume\"]\n  D --> E[\"Rolling numerator / denominator\"]\n  E --> F{\"History and denominator valid?\"}\n  F -- \"No · short history\" --> G[\"warming-up + reason\"]\n  F -- \"No · no finite scale\" --> H[\"undefined + reason\"]\n  F -- \"Yes\" --> I[\"Chaikin Money Flow\"]\n  I --> J[\"ready + aligned component trace\"]"
          },
          {
            "file": "data-basis-reconciliation.md",
            "caption": "Data-basis reconciliation — Chaikin Money Flow",
            "source": "flowchart LR\n    A[\"Same instrument and identifier?\"] -->|Yes| B[\"Same venue or consolidated scope?\"]\n    A -->|No| X[\"Stop: different measurement\"]\n    B -->|Yes| C[\"Same volume unit and bar interval?\"]\n    B -->|No| X\n    C -->|Yes| D[\"Same session and close policy?\"]\n    C -->|No| X\n    D -->|Yes| E[\"Same corrections and price-volume adjustment basis?\"]\n    D -->|No| X\n    E -->|Yes| F[\"Same CMF convention, seed, warm-up, and precision?\"]\n    E -->|No| X\n    F -->|Yes| G[\"Compare intermediate components\"]\n    F -->|No| Y[\"Document convention difference\"]\n    G --> H[\"Compare final output\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation flow",
            "source": "flowchart LR\n  A[\"Finalized finalized high, low, close, and nonnegative volume\"] --> B[\"Validate order, alignment, and finite values\"]\n  B --> C[\"Typical price\"]\n  C --> D[\"Raw and directional flow\"]\n  D --> E[\"Positive / negative sums\"]\n  E --> F{\"History and denominator valid?\"}\n  F -- \"No · short history\" --> G[\"warming-up + reason\"]\n  F -- \"No · no finite scale\" --> H[\"undefined + reason\"]\n  F -- \"Yes\" --> I[\"Money Flow Index\"]\n  I --> J[\"ready + aligned component trace\"]"
          },
          {
            "file": "data-basis-reconciliation.md",
            "caption": "Data-basis reconciliation — Money Flow Index",
            "source": "flowchart LR\n    A[\"Same instrument and identifier?\"] -->|Yes| B[\"Same venue or consolidated scope?\"]\n    A -->|No| X[\"Stop: different measurement\"]\n    B -->|Yes| C[\"Same volume unit and bar interval?\"]\n    B -->|No| X\n    C -->|Yes| D[\"Same session and close policy?\"]\n    C -->|No| X\n    D -->|Yes| E[\"Same corrections and price-volume adjustment basis?\"]\n    D -->|No| X\n    E -->|Yes| F[\"Same MFI convention, seed, warm-up, and precision?\"]\n    E -->|No| X\n    F -->|Yes| G[\"Compare intermediate components\"]\n    F -->|No| Y[\"Document convention difference\"]\n    G --> H[\"Compare final output\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation flow",
            "source": "flowchart LR\n  A[\"Finalized strictly positive finalized close and nonnegative volume\"] --> B[\"Validate order, alignment, and finite values\"]\n  B --> C[\"One-bar return\"]\n  C --> D[\"Current volume\"]\n  D --> E[\"Return-weighted contribution\"]\n  E --> F{\"History and denominator valid?\"}\n  F -- \"No · short history\" --> G[\"warming-up + reason\"]\n  F -- \"No · no finite scale\" --> H[\"undefined + reason\"]\n  F -- \"Yes\" --> I[\"Cumulative VPT\"]\n  I --> J[\"ready + aligned component trace\"]"
          },
          {
            "file": "data-basis-reconciliation.md",
            "caption": "Data-basis reconciliation — Volume Price Trend",
            "source": "flowchart LR\n    A[\"Same instrument and identifier?\"] -->|Yes| B[\"Same venue or consolidated scope?\"]\n    A -->|No| X[\"Stop: different measurement\"]\n    B -->|Yes| C[\"Same volume unit and bar interval?\"]\n    B -->|No| X\n    C -->|Yes| D[\"Same session and close policy?\"]\n    C -->|No| X\n    D -->|Yes| E[\"Same corrections and price-volume adjustment basis?\"]\n    D -->|No| X\n    E -->|Yes| F[\"Same VPT convention, seed, warm-up, and precision?\"]\n    E -->|No| X\n    F -->|Yes| G[\"Compare intermediate components\"]\n    F -->|No| Y[\"Document convention difference\"]\n    G --> H[\"Compare final output\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation flow",
            "source": "flowchart LR\n  A[\"Finalized finalized close and nonnegative volume\"] --> B[\"Validate order, alignment, and finite values\"]\n  B --> C[\"Close change\"]\n  C --> D[\"Raw price-volume force\"]\n  D --> E[\"EMA seed / update\"]\n  E --> F{\"History and denominator valid?\"}\n  F -- \"No · short history\" --> G[\"warming-up + reason\"]\n  F -- \"No · no finite scale\" --> H[\"undefined + reason\"]\n  F -- \"Yes\" --> I[\"Smoothed Force Index\"]\n  I --> J[\"ready + aligned component trace\"]"
          },
          {
            "file": "data-basis-reconciliation.md",
            "caption": "Data-basis reconciliation — Force Index",
            "source": "flowchart LR\n    A[\"Same instrument and identifier?\"] -->|Yes| B[\"Same venue or consolidated scope?\"]\n    A -->|No| X[\"Stop: different measurement\"]\n    B -->|Yes| C[\"Same volume unit and bar interval?\"]\n    B -->|No| X\n    C -->|Yes| D[\"Same session and close policy?\"]\n    C -->|No| X\n    D -->|Yes| E[\"Same corrections and price-volume adjustment basis?\"]\n    D -->|No| X\n    E -->|Yes| F[\"Same Force Index convention, seed, warm-up, and precision?\"]\n    E -->|No| X\n    F -->|Yes| G[\"Compare intermediate components\"]\n    F -->|No| Y[\"Document convention difference\"]\n    G --> H[\"Compare final output\"]"
          }
        ]
      },
      "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": "D07-F05-A07",
      "name": "Chaikin A/D Oscillator",
      "headline": null,
      "slug": "chaikin-a-d-oscillator",
      "path": "technical-indicators/volume-indicators/chaikin-a-d-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/chaikin-a-d-oscillator",
        "entry": "chaikinADOscillator",
        "params": [
          "input"
        ],
        "exports": [
          "chaikinADOscillator"
        ],
        "archetype": "series-transform",
        "signature": "chaikinADOscillator(input)"
      },
      "api": {
        "summary": "Builds the cumulative accumulation/distribution line from the money flow multiplier and volume, then returns the difference between a fast and a slow EMA of that line.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `open`, `high`, `low`, `close` and `volume`. From `parameters` this topic uses `fast_period` (default 3) and `slow_period` (default 10, minimum `fast_period` + 1); `period` (default 14) is validated by the family but unused here.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `ad`, the running cumulative money flow volume, and `value`, the fast EMA of `ad` minus the slow EMA of `ad`. `latest` carries the last element of each. `ad` is populated from the first bar, so `ready_at` is 0 even though `value` has its own warm-up."
        },
        "warmup": {
          "count": "`slow_period` - 1 bars for `value` (9 with the default 10); none for `ad`",
          "value": "null",
          "note": "`ad` is non-null on the first bar, so `ready_at` reports 0 while `value` is still null. Read `value` for readiness, not `ready_at`."
        },
        "errors": [
          {
            "when": "a bar carries a negative `volume`",
            "behaviour": "throws Error"
          },
          {
            "when": "`slow_period` is not an integer greater than `fast_period`",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or its timestamps are not strictly increasing",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "chaikinADOscillator({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F05-A07",
          "title": "Chaikin A/D Oscillator",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "ad": [
              -39473.6842105251,
              -6702.529515955808,
              66669.61995061857,
              148952.74316349486,
              206717.91744960428,
              202168.88289909757
            ],
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "ad": -4337333.133776561,
            "value": -148029.1919731265
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a07/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a07/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a07/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a07/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Chaikin A/D Oscillator calculation flow",
            "source": "flowchart LR\n    A[\"basis-consistent OHLCV observations with venue/session cov\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Chaikin A/D Oscillator convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Chaikin A/D Oscillator readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/chaikin-a-d-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/chaikin-a-d-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A08",
      "name": "Session VWAP Indicator",
      "headline": null,
      "slug": "session-vwap-indicator",
      "path": "technical-indicators/volume-indicators/session-vwap-indicator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/session-vwap-indicator",
        "entry": "sessionVwapIndicator",
        "params": [
          "input"
        ],
        "exports": [
          "sessionVwapIndicator"
        ],
        "archetype": "series-transform",
        "signature": "sessionVwapIndicator(input)"
      },
      "api": {
        "summary": "Accumulates typical price times volume divided by cumulative volume, restarting the accumulation at every new session.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `high`, `low`, `close` and `volume`. This topic reads no parameters of its own; the family reads `period` (default 14), `fast_period` (default 3) and `slow_period` (default 10, minimum `fast_period` + 1) for every volume topic, so a non-integer or out-of-range value throws even when this topic ignores it.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single `value`, and `latest` its last element. The session key is the first ten characters of `timestamp`, and both accumulators reset whenever that key differs from the previous bar's. With daily `YYYY-MM-DD` bars every bar is therefore its own session and `value` equals that bar's typical price, `(high + low + close) / 3`. There is no warm-up."
        },
        "warmup": {
          "count": "none",
          "value": "null only when a session's accumulated volume is 0",
          "note": "`value` is populated on the first bar of every session, so `ready_at` is 0 unless the first bar has zero volume."
        },
        "errors": [
          {
            "when": "a bar carries a negative `volume`",
            "behaviour": "throws Error"
          },
          {
            "when": "a `high` is below the bar's `open`, `low` or `close`",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is not an array, or a `timestamp` is missing or empty",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "sessionVwapIndicator({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F05-A08",
          "title": "Session VWAP Indicator",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "value": [
              100.04833333333333,
              101.74217643000001,
              102.84553092333333,
              103.11026585,
              102.75204238333333,
              102.27411882333332
            ]
          },
          "latest": {
            "value": 100.16305426666668
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a08/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a08/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a08/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a08/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Session VWAP Indicator calculation flow",
            "source": "flowchart LR\n    A[\"basis-consistent OHLCV observations with venue/session cov\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Session VWAP Indicator convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Session VWAP Indicator readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/session-vwap-indicator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/session-vwap-indicator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A09",
      "name": "Anchored VWAP",
      "headline": null,
      "slug": "anchored-vwap",
      "path": "technical-indicators/volume-indicators/anchored-vwap",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/anchored-vwap",
        "entry": "anchoredVwap",
        "params": [
          "input"
        ],
        "exports": [
          "anchoredVwap"
        ],
        "archetype": "series-transform",
        "signature": "anchoredVwap(input)"
      },
      "api": {
        "summary": "Accumulates typical price times volume divided by cumulative volume from a chosen anchor bar onward, with no session reset.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `anchor_index` (default 0, an integer of at least 0).",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single `value`, and `latest` its last element. Bars before `anchor_index` are null; from the anchor onward the running sums never reset, so the value is one continuous VWAP over the tail of the input. The warm-up is the anchor itself."
        },
        "warmup": {
          "count": "`anchor_index` bars (0 by default)",
          "value": "null",
          "note": "`ready_at` equals `anchor_index` unless the anchor bar's volume is 0, in which case the first non-null value comes later."
        },
        "errors": [
          {
            "when": "`anchor_index` is not an integer of at least 0",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar carries a negative `volume`",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `open`, `high`, `low`, `close` or `volume` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "anchoredVwap({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F05-A09",
          "title": "Anchored VWAP",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "value": [
              100.04833333333333,
              100.9199847626376,
              101.59825364331219,
              102.00754238903198,
              102.17243298396093,
              102.19159618167922
            ]
          },
          "latest": {
            "value": 102.78490100053703
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a09/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a09/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a09/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a09/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Anchored VWAP calculation flow",
            "source": "flowchart LR\n    A[\"basis-consistent OHLCV observations with venue/session cov\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Anchored VWAP convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Anchored VWAP readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/anchored-vwap/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/anchored-vwap/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A10",
      "name": "Negative Volume Index",
      "headline": null,
      "slug": "negative-volume-index",
      "path": "technical-indicators/volume-indicators/negative-volume-index",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/negative-volume-index",
        "entry": "negativeVolumeIndex",
        "params": [
          "input"
        ],
        "exports": [
          "negativeVolumeIndex"
        ],
        "archetype": "series-transform",
        "signature": "negativeVolumeIndex(input)"
      },
      "api": {
        "summary": "Tracks a cumulative index seeded at 1000 that compounds the close-to-close return only on bars whose volume fell against the prior bar.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `close` and `volume`. This topic reads no parameters of its own; the family reads `period` (default 14), `fast_period` (default 3) and `slow_period` (default 10, minimum `fast_period` + 1) for every volume topic, so a non-integer or out-of-range value throws even when this topic ignores it.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single `value`, and `latest` its last element. The first bar is 1000; each later bar multiplies the running level by `close / prior close` when volume fell, and otherwise carries the previous level forward unchanged (as it also does when the prior close is 0). No element is ever null, so there is no warm-up."
        },
        "warmup": {
          "count": "none",
          "value": "1000 on the first bar",
          "note": "`ready_at` is 0. The series is a level, not a signal, so the seed is a real value rather than a placeholder."
        },
        "errors": [
          {
            "when": "a bar carries a negative `volume`",
            "behaviour": "throws Error"
          },
          {
            "when": "a `close` is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "two bars share a timestamp, or the bars are out of order",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "negativeVolumeIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F05-A10",
          "title": "Negative Volume Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "value": [
              1000,
              1000,
              1000,
              1000,
              1000,
              1000
            ]
          },
          "latest": {
            "value": 991.0425084378836
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a10/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a10/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a10/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a10/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Negative Volume Index calculation flow",
            "source": "flowchart LR\n    A[\"basis-consistent OHLCV observations with venue/session cov\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Negative Volume Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Negative Volume Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/negative-volume-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/negative-volume-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A11",
      "name": "Positive Volume Index",
      "headline": null,
      "slug": "positive-volume-index",
      "path": "technical-indicators/volume-indicators/positive-volume-index",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/positive-volume-index",
        "entry": "positiveVolumeIndex",
        "params": [
          "input"
        ],
        "exports": [
          "positiveVolumeIndex"
        ],
        "archetype": "series-transform",
        "signature": "positiveVolumeIndex(input)"
      },
      "api": {
        "summary": "Tracks a cumulative index seeded at 1000 that compounds the close-to-close return only on bars whose volume rose against the prior bar.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `close` and `volume`. This topic reads no parameters of its own; the family reads `period` (default 14), `fast_period` (default 3) and `slow_period` (default 10, minimum `fast_period` + 1) for every volume topic, so a non-integer or out-of-range value throws even when this topic ignores it.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single `value`, and `latest` its last element. The first bar is 1000; each later bar multiplies the running level by `close / prior close` when volume rose, and otherwise carries the previous level forward unchanged (as it also does when the prior close is 0). No element is ever null, so there is no warm-up."
        },
        "warmup": {
          "count": "none",
          "value": "1000 on the first bar",
          "note": "`ready_at` is 0. The series is a level, not a signal, so the seed is a real value rather than a placeholder."
        },
        "errors": [
          {
            "when": "a bar carries a negative `volume`",
            "behaviour": "throws Error"
          },
          {
            "when": "a `close` is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "two bars share a timestamp, or the bars are out of order",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "positiveVolumeIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F05-A11",
          "title": "Positive Volume Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "value": [
              1000,
              1017.8791214,
              1029.549389,
              1032.3228269,
              1028.3130013,
              1022.6872597
            ]
          },
          "latest": {
            "value": 1008.9457679026209
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a11/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a11/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a11/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a11/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Positive Volume Index calculation flow",
            "source": "flowchart LR\n    A[\"basis-consistent OHLCV observations with venue/session cov\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Positive Volume Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Positive Volume Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/positive-volume-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/positive-volume-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A12",
      "name": "Ease of Movement",
      "headline": null,
      "slug": "ease-of-movement",
      "path": "technical-indicators/volume-indicators/ease-of-movement",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/ease-of-movement",
        "entry": "easeOfMovement",
        "params": [
          "input"
        ],
        "exports": [
          "easeOfMovement"
        ],
        "archetype": "series-transform",
        "signature": "easeOfMovement(input)"
      },
      "api": {
        "summary": "Divides the typical-price change by a box ratio built from scaled volume over the bar range, then smooths that raw reading with a simple moving average.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `volume_scale` (default 1000000, a finite number of at least 0.000001) and `period` (default 14, an integer of at least 2).",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `raw`, the unsmoothed reading, and `value`, its simple moving average over `period`. `latest` carries the last element of each. `raw` is null on the first bar and on any bar whose `high` equals its `low` or whose volume is 0; `value` needs a full window of non-null `raw`, so it starts later than `raw`. Both warm-ups are described below."
        },
        "warmup": {
          "count": "1 bar for `raw`; `period` bars for `value` (index 14 with the defaults)",
          "value": "null",
          "note": "`ready_at` is 1, driven by `raw`. Because a null inside the window restarts the average, any flat or zero-volume bar pushes `value` out by a further `period` bars."
        },
        "errors": [
          {
            "when": "`volume_scale` is below 0.000001 or not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "`period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar carries a negative `volume`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "easeOfMovement({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F05-A12",
          "title": "Ease of Movement",
          "state": "calculated",
          "ready": true,
          "ready_at": 1,
          "series": {
            "raw": [
              null,
              7.09182670339273,
              4.935760375263474,
              1.1777185136470167,
              -1.4745208573506723,
              -1.699726591438122
            ],
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "raw": -3.4562255141040934,
            "value": -0.7167616272036208
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a12/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a12/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a12/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a12/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Ease of Movement calculation flow",
            "source": "flowchart LR\n    A[\"basis-consistent OHLCV observations with venue/session cov\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Ease of Movement convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Ease of Movement readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/ease-of-movement/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/ease-of-movement/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A13",
      "name": "Klinger Volume Oscillator",
      "headline": null,
      "slug": "klinger-volume-oscillator",
      "path": "technical-indicators/volume-indicators/klinger-volume-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/klinger-volume-oscillator",
        "entry": "klingerVolumeOscillator",
        "params": [
          "input"
        ],
        "exports": [
          "klingerVolumeOscillator"
        ],
        "archetype": "series-transform",
        "signature": "klingerVolumeOscillator(input)"
      },
      "api": {
        "summary": "Signs each bar's volume force by the direction of the high-low-close sum and weights it by where the close sits in the bar range, then returns the fast EMA of that force minus the slow EMA.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `high`, `low`, `close` and `volume`. Inside the branch `fast_period` defaults to 34 and `slow_period` to 55 (minimum `fast_period` + 1). The family validates the same two keys first against defaults of 3 and 10, so supplying `fast_period` of 10 or more without also supplying `slow_period` throws on that earlier check.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single `value`, the fast EMA of the volume force minus the slow EMA, and `latest` its last element. The warm-up is set by the slow EMA seed."
        },
        "warmup": {
          "count": "`slow_period` - 1 bars (54 with the default 55)",
          "value": "null",
          "note": "`ready_at` is 54 on default parameters, so short inputs return `state: waiting` with a null `value`."
        },
        "errors": [
          {
            "when": "`fast_period` is 10 or more and `slow_period` is not supplied",
            "behaviour": "throws Error"
          },
          {
            "when": "`slow_period` is not an integer greater than `fast_period`",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar carries a negative `volume`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "klingerVolumeOscillator({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F05-A13",
          "title": "Klinger Volume Oscillator",
          "state": "calculated",
          "ready": true,
          "ready_at": 54,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -13741.12194581165
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a13/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a13/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a13/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a13/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Klinger Volume Oscillator calculation flow",
            "source": "flowchart LR\n    A[\"basis-consistent OHLCV observations with venue/session cov\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Klinger Volume Oscillator convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Klinger Volume Oscillator readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/klinger-volume-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/klinger-volume-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A14",
      "name": "Volume Oscillator",
      "headline": null,
      "slug": "volume-oscillator",
      "path": "technical-indicators/volume-indicators/volume-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/volume-oscillator",
        "entry": "volumeOscillator",
        "params": [
          "input"
        ],
        "exports": [
          "volumeOscillator"
        ],
        "archetype": "series-transform",
        "signature": "volumeOscillator(input)"
      },
      "api": {
        "summary": "Returns the difference between a fast and a slow simple moving average of raw volume.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp` and `volume`. From `parameters` this topic reads `fast_period` (default 3) and `slow_period` (default 10, minimum `fast_period` + 1); `period` (default 14) is validated by the family but unused here.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single `value`, the fast volume SMA minus the slow one, in raw volume units rather than a percentage. `latest` carries its last element. The warm-up is set by the slow average."
        },
        "warmup": {
          "count": "`slow_period` - 1 bars (9 with the default 10)",
          "value": "null",
          "note": "`ready_at` is 9 on default parameters."
        },
        "errors": [
          {
            "when": "`slow_period` is not an integer greater than `fast_period`",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar carries a negative `volume`",
            "behaviour": "throws Error"
          },
          {
            "when": "fewer than one bar is supplied",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "volumeOscillator({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F05-A14",
          "title": "Volume Oscillator",
          "state": "calculated",
          "ready": true,
          "ready_at": 9,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 6709.5
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a14/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a14/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a14/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a14/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Volume Oscillator calculation flow",
            "source": "flowchart LR\n    A[\"basis-consistent OHLCV observations with venue/session cov\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Volume Oscillator convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Volume Oscillator readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/volume-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/volume-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A15",
      "name": "Percentage Volume Oscillator",
      "headline": null,
      "slug": "percentage-volume-oscillator",
      "path": "technical-indicators/volume-indicators/percentage-volume-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/percentage-volume-oscillator",
        "entry": "percentageVolumeOscillator",
        "params": [
          "input"
        ],
        "exports": [
          "percentageVolumeOscillator"
        ],
        "archetype": "series-transform",
        "signature": "percentageVolumeOscillator(input)"
      },
      "api": {
        "summary": "Expresses the gap between a fast and a slow EMA of volume as a percentage of the slow EMA.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp` and `volume`. From `parameters` this topic reads `fast_period` (default 3) and `slow_period` (default 10, minimum `fast_period` + 1); `period` (default 14) is validated by the family but unused here.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single `value`, 100 times the fast EMA minus the slow EMA divided by the slow EMA, and `latest` its last element. A bar whose slow EMA is 0 yields null rather than a division result. The warm-up is set by the slow EMA seed."
        },
        "warmup": {
          "count": "`slow_period` - 1 bars (9 with the default 10)",
          "value": "null",
          "note": "`ready_at` is 9 on default parameters."
        },
        "errors": [
          {
            "when": "`slow_period` is not an integer greater than `fast_period`",
            "behaviour": "throws Error"
          },
          {
            "when": "`fast_period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar carries a negative `volume`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "percentageVolumeOscillator({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F05-A15",
          "title": "Percentage Volume Oscillator",
          "state": "calculated",
          "ready": true,
          "ready_at": 9,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 2.367053666955535
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a15/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a15/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a15/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a15/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Percentage Volume Oscillator calculation flow",
            "source": "flowchart LR\n    A[\"basis-consistent OHLCV observations with venue/session cov\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Percentage Volume Oscillator convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Percentage Volume Oscillator readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/percentage-volume-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/percentage-volume-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A16",
      "name": "Volume Rate of Change",
      "headline": null,
      "slug": "volume-rate-of-change",
      "path": "technical-indicators/volume-indicators/volume-rate-of-change",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/volume-rate-of-change",
        "entry": "volumeRateOfChange",
        "params": [
          "input"
        ],
        "exports": [
          "volumeRateOfChange"
        ],
        "archetype": "series-transform",
        "signature": "volumeRateOfChange(input)"
      },
      "api": {
        "summary": "Measures the percentage change in volume against the bar `period` positions earlier.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp` and `volume`. From `parameters` this topic reads `period` (default 14, an integer of at least 2).",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single `value`, 100 times `volume / lagged volume - 1`, and `latest` its last element. A bar whose lagged volume is 0 yields null. The warm-up is the lag itself."
        },
        "warmup": {
          "count": "`period` bars (14 with the default)",
          "value": "null",
          "note": "`ready_at` is 14 on default parameters, one more than the moving-average topics in this family because the comparison is a lag rather than a window."
        },
        "errors": [
          {
            "when": "`period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar carries a negative `volume`",
            "behaviour": "throws Error"
          },
          {
            "when": "a `volume` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "volumeRateOfChange({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F05-A16",
          "title": "Volume Rate of Change",
          "state": "calculated",
          "ready": true,
          "ready_at": 14,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 25.301129103211338
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a16/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a16/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a16/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a16/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Volume Rate of Change calculation flow",
            "source": "flowchart LR\n    A[\"basis-consistent OHLCV observations with venue/session cov\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Volume Rate of Change convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Volume Rate of Change readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/volume-rate-of-change/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/volume-rate-of-change/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A17",
      "name": "Relative Volume",
      "headline": null,
      "slug": "relative-volume",
      "path": "technical-indicators/volume-indicators/relative-volume",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/relative-volume",
        "entry": "relativeVolume",
        "params": [
          "input"
        ],
        "exports": [
          "relativeVolume"
        ],
        "archetype": "series-transform",
        "signature": "relativeVolume(input)"
      },
      "api": {
        "summary": "Divides each bar's volume by the simple moving average of volume over the preceding window, giving a multiple of normal activity.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp` and `volume`. From `parameters` this topic reads `period` (default 14, an integer of at least 2).",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single `value`, the ratio of volume to its `period` average, and `latest` its last element. A window whose average volume is 0 yields null. The warm-up is the averaging window."
        },
        "warmup": {
          "count": "`period` - 1 bars (13 with the default 14)",
          "value": "null",
          "note": "`ready_at` is 13 on default parameters. The window includes the current bar, so the reading is not a comparison against history alone."
        },
        "errors": [
          {
            "when": "`period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar carries a negative `volume`",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "relativeVolume({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F05-A17",
          "title": "Relative Volume",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 1.0655386224508623
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a17/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a17/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a17/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a17/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Relative Volume calculation flow",
            "source": "flowchart LR\n    A[\"basis-consistent OHLCV observations with venue/session cov\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Relative Volume convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Relative Volume readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/relative-volume/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/relative-volume/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A18",
      "name": "Money Flow Multiplier and Money Flow Volume",
      "headline": null,
      "slug": "money-flow-multiplier-and-money-flow-volume",
      "path": "technical-indicators/volume-indicators/money-flow-multiplier-and-money-flow-volume",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/money-flow-multiplier-and-money-flow-volume",
        "entry": "moneyFlowMultiplierAndMoneyFlowVolume",
        "params": [
          "input"
        ],
        "exports": [
          "moneyFlowMultiplierAndMoneyFlowVolume"
        ],
        "archetype": "series-transform",
        "signature": "moneyFlowMultiplierAndMoneyFlowVolume(input)"
      },
      "api": {
        "summary": "Returns the per-bar money flow multiplier, the close's position within the bar range mapped to minus one through one, and that multiplier times volume.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `high`, `low`, `close` and `volume`. This topic reads no parameters of its own; the family reads `period` (default 14), `fast_period` (default 3) and `slow_period` (default 10, minimum `fast_period` + 1) for every volume topic, so a non-integer or out-of-range value throws even when this topic ignores it.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `mfm`, the multiplier, and `mfv`, the multiplier times volume; `latest` carries the last element of each. A bar whose `high` equals its `low` gets an `mfm` of 0 rather than null. Both series are populated from the first bar, so there is no warm-up."
        },
        "warmup": {
          "count": "none",
          "value": "0 on a bar whose high equals its low",
          "note": "`ready_at` is 0. These are the per-bar building blocks the rest of the family accumulates, so nothing is smoothed."
        },
        "errors": [
          {
            "when": "a bar carries a negative `volume`",
            "behaviour": "throws Error"
          },
          {
            "when": "a `low` is above the bar's `open`, `high` or `close`",
            "behaviour": "throws Error"
          },
          {
            "when": "a `close` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "moneyFlowMultiplierAndMoneyFlowVolume({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F05-A18",
          "title": "Money Flow Multiplier and Money Flow Volume",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "mfm": [
              -0.052631578947366794,
              0.04121551255295672,
              0.08732347115990827,
              0.09293842014396132,
              0.062081849441474005,
              -0.004662878734817273
            ],
            "mfv": [
              -39473.6842105251,
              32771.15469456929,
              73372.14946657437,
              82283.12321287631,
              57765.17428610943,
              -4549.034550506709
            ]
          },
          "latest": {
            "mfm": -0.16556937573789185,
            "mfv": -207974.176405002
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a18/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a18/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a18/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a18/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Money Flow Multiplier and Money Flow Volume calculation flow",
            "source": "flowchart LR\n    A[\"basis-consistent OHLCV observations with venue/session cov\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Money Flow Multiplier and Money Flow Volume convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Money Flow Multiplier and Money Flow Volume readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/money-flow-multiplier-and-money-flow-volume/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/money-flow-multiplier-and-money-flow-volume/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A19",
      "name": "Volume-Weighted MACD",
      "headline": null,
      "slug": "volume-weighted-macd",
      "path": "technical-indicators/volume-indicators/volume-weighted-macd",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/volume-weighted-macd",
        "entry": "volumeWeightedMacd",
        "params": [
          "input"
        ],
        "exports": [
          "volumeWeightedMacd"
        ],
        "archetype": "series-transform",
        "signature": "volumeWeightedMacd(input)"
      },
      "api": {
        "summary": "Runs the MACD construction on volume-weighted moving averages of close instead of exponential ones, and smooths the resulting line into a signal.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `close` and `volume`. From `parameters` this topic reads `fast_period` (default 3), `slow_period` (default 10, minimum `fast_period` + 1) and `signal_period` (default 9, an integer of at least 2).",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `value`, the fast VWMA of close minus the slow VWMA, and `signal`, the EMA of `value` over `signal_period`. `latest` carries the last element of each. A window whose volume sums to 0 makes that VWMA null, which propagates. The two warm-ups differ and are described below."
        },
        "warmup": {
          "count": "`slow_period` - 1 bars for `value` (9 with the defaults); a further `signal_period` - 1 for `signal` (index 17)",
          "value": "null",
          "note": "`ready_at` is 9, driven by `value`. `signal` is still null there, so a crossover strategy needs the later index."
        },
        "errors": [
          {
            "when": "`slow_period` is not an integer greater than `fast_period`",
            "behaviour": "throws Error"
          },
          {
            "when": "`signal_period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar carries a negative `volume`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "volumeWeightedMacd({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F05-A19",
          "title": "Volume-Weighted MACD",
          "state": "calculated",
          "ready": true,
          "ready_at": 9,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "signal": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -2.799155032079767,
            "signal": -1.3105571933842994
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a19/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a19/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a19/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a19/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Volume-Weighted MACD calculation flow",
            "source": "flowchart LR\n    A[\"basis-consistent OHLCV observations with venue/session cov\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Volume-Weighted MACD convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Volume-Weighted MACD readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/volume-weighted-macd/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/volume-weighted-macd/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A20",
      "name": "Volume Zone Oscillator",
      "headline": null,
      "slug": "volume-zone-oscillator",
      "path": "technical-indicators/volume-indicators/volume-zone-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/volume-zone-oscillator",
        "entry": "volumeZoneOscillator",
        "params": [
          "input"
        ],
        "exports": [
          "volumeZoneOscillator"
        ],
        "archetype": "series-transform",
        "signature": "volumeZoneOscillator(input)"
      },
      "api": {
        "summary": "Signs each bar's volume by the direction of the close change, then expresses the EMA of that signed volume as a percentage of the EMA of total volume.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `close` and `volume`. From `parameters` this topic reads `period` (default 14, an integer of at least 2), used for both EMAs.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single `value`, 100 times the signed-volume EMA over the total-volume EMA, and `latest` its last element. The first bar contributes signed volume of 0 because it has no prior close, and an unchanged close also contributes 0. A bar whose volume EMA is 0 yields null. The warm-up is the EMA seed."
        },
        "warmup": {
          "count": "`period` - 1 bars (13 with the default 14)",
          "value": "null",
          "note": "`ready_at` is 13 on default parameters. Both EMAs seed on the same index, so the ratio becomes available in one step."
        },
        "errors": [
          {
            "when": "`period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar carries a negative `volume`",
            "behaviour": "throws Error"
          },
          {
            "when": "timestamps are not strictly increasing",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "volumeZoneOscillator({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F05-A20",
          "title": "Volume Zone Oscillator",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -65.16002629705007
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a20/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a20/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a20/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a20/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Volume Zone Oscillator calculation flow",
            "source": "flowchart LR\n    A[\"basis-consistent OHLCV observations with venue/session cov\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Volume Zone Oscillator convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Volume Zone Oscillator readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/volume-zone-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/volume-zone-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A21",
      "name": "Twiggs Money Flow",
      "headline": null,
      "slug": "twiggs-money-flow",
      "path": "technical-indicators/volume-indicators/twiggs-money-flow",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/twiggs-money-flow",
        "entry": "twiggsMoneyFlow",
        "params": [
          "input"
        ],
        "exports": [
          "twiggsMoneyFlow"
        ],
        "archetype": "series-transform",
        "signature": "twiggsMoneyFlow(input)"
      },
      "api": {
        "summary": "Accumulates volume weighted by where the close sits inside a range extended to include the prior close, then divides the EMA of that flow by the EMA of volume.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `high`, `low`, `close` and `volume`. From `parameters` this topic reads `period` (default 14, an integer of at least 2), used for both EMAs.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single `value`, the flow EMA divided by the volume EMA, and `latest` its last element. The first bar contributes a flow of 0 because the extended range needs a prior close, and a bar whose extended top equals its extended bottom also contributes 0. A bar whose volume EMA is 0 yields null. The warm-up is the EMA seed."
        },
        "warmup": {
          "count": "`period` - 1 bars (13 with the default 14)",
          "value": "null",
          "note": "`ready_at` is 13 on default parameters. The result is a ratio, not a percentage, so it sits roughly between minus one and one."
        },
        "errors": [
          {
            "when": "`period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar carries a negative `volume`",
            "behaviour": "throws Error"
          },
          {
            "when": "a `high` is below the bar's `open`, `low` or `close`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "twiggsMoneyFlow({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F05-A21",
          "title": "Twiggs Money Flow",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -0.038641839414592004
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a21/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a21/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a21/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a21/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Twiggs Money Flow calculation flow",
            "source": "flowchart LR\n    A[\"basis-consistent OHLCV observations with venue/session cov\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Twiggs Money Flow convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Twiggs Money Flow readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/twiggs-money-flow/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/twiggs-money-flow/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F06-A01",
      "name": "Normalized ATR and ATR Percentage",
      "headline": null,
      "slug": "normalized-atr-and-atr-percentage",
      "path": "technical-indicators/range-and-volatility-indicators/normalized-atr-and-atr-percentage",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F06",
        "family": "Range and Volatility Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/range-and-volatility-indicators/normalized-atr-and-atr-percentage",
        "entry": "normalizedAtrAndAtrPercentage",
        "params": [
          "input"
        ],
        "exports": [
          "normalizedAtrAndAtrPercentage"
        ],
        "archetype": "series-transform",
        "signature": "normalizedAtrAndAtrPercentage(input)"
      },
      "api": {
        "summary": "Wilder's Average True Range over `period` bars, and the same figure restated as a percentage of that bar's close.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads only `period` (default 14, integer >= 2), which is the Wilder RMA length used for the ATR.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `atr`, the Wilder RMA of true range, and `natr`, `100 * atr / close`. `latest` carries the last value of each. Both share the same warm-up: `period - 1` leading nulls, so `ready_at` is 13 at the default period, the index where the RMA seed completes."
        },
        "warmup": {
          "count": "`period - 1` bars (13 at the default period)",
          "value": "null",
          "note": "The ATR is seeded by averaging the first `period` true ranges, so nothing is emitted until that many bars exist. `natr` is derived from `atr` and inherits the same prefix; it is also null on any bar whose close is zero."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "bars are not strictly ordered by timestamp, or a bar's high is below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "normalizedAtrAndAtrPercentage({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F06-A01",
          "title": "Normalized ATR and ATR Percentage",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "atr": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "natr": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "atr": 3.245219101666433,
            "natr": 3.2455172196242965
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a01/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a01/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a01/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Normalized ATR and ATR Percentage calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations with session calendar, previous \"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Normalized ATR and ATR Percentage convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Normalized ATR and ATR Percentage readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/range-and-volatility-indicators/normalized-atr-and-atr-percentage/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/range-and-volatility-indicators/normalized-atr-and-atr-percentage/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F06-A02",
      "name": "Chaikin Volatility",
      "headline": null,
      "slug": "chaikin-volatility",
      "path": "technical-indicators/range-and-volatility-indicators/chaikin-volatility",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F06",
        "family": "Range and Volatility Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/range-and-volatility-indicators/chaikin-volatility",
        "entry": "chaikinVolatility",
        "params": [
          "input"
        ],
        "exports": [
          "chaikinVolatility"
        ],
        "archetype": "series-transform",
        "signature": "chaikinVolatility(input)"
      },
      "api": {
        "summary": "Chaikin Volatility: the percentage change, `roc_period` bars apart, in an exponential moving average of the bar's high-low range.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads `period` (default 14, integer >= 2), the EMA length applied to `high - low`, and `roc_period` (default 10, integer >= 1), the rate-of-change lookback.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single key, `value`, the percentage change in the smoothed range; `latest.value` is its last reading. The warm-up is `period - 1 + roc_period` leading nulls, so `ready_at` is 23 at the defaults."
        },
        "warmup": {
          "count": "`period - 1 + roc_period` bars (23 at the defaults)",
          "value": "null",
          "note": "The EMA of the range seeds at index `period - 1`, and the rate of change needs a smoothed value `roc_period` bars earlier. `value` is additionally null on any bar whose lagged EMA is exactly zero."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.roc_period` is not an integer >= 1",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "chaikinVolatility({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F06-A02",
          "title": "Chaikin Volatility",
          "state": "calculated",
          "ready": true,
          "ready_at": 23,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 11.096464053974685
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a02/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a02/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a02/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Chaikin Volatility calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations with session calendar, previous \"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Chaikin Volatility convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Chaikin Volatility readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/range-and-volatility-indicators/chaikin-volatility/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/range-and-volatility-indicators/chaikin-volatility/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F06-A03",
      "name": "Ulcer Index",
      "headline": null,
      "slug": "ulcer-index",
      "path": "technical-indicators/range-and-volatility-indicators/ulcer-index",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F06",
        "family": "Range and Volatility Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/range-and-volatility-indicators/ulcer-index",
        "entry": "ulcerIndex",
        "params": [
          "input"
        ],
        "exports": [
          "ulcerIndex"
        ],
        "archetype": "series-transform",
        "signature": "ulcerIndex(input)"
      },
      "api": {
        "summary": "Ulcer Index: the root mean square of the percentage drawdown from the running peak close, measured across a window of `period` bars.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads only `period` (default 14, integer >= 2), the width of the root-mean-square window.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single key, `value`, and `latest.value` is its last reading. The warm-up is `period - 1` leading nulls, so `ready_at` is 13 at the default period."
        },
        "warmup": {
          "count": "`period - 1` bars (13 at the default period)",
          "value": "null",
          "note": "The drawdown of each bar against the running peak close is available from the first bar, but the root-mean-square needs a full `period`-bar window before it emits. The peak itself is expanding, not windowed, so it always starts at the first bar supplied."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "bars are not strictly ordered by timestamp, or a bar's high is below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "ulcerIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F06-A03",
          "title": "Ulcer Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 4.221368476494294
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a03/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a03/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a03/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Ulcer Index calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations with session calendar, previous \"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Ulcer Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Ulcer Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/range-and-volatility-indicators/ulcer-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/range-and-volatility-indicators/ulcer-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F06-A04",
      "name": "Relative Volatility Index",
      "headline": null,
      "slug": "relative-volatility-index",
      "path": "technical-indicators/range-and-volatility-indicators/relative-volatility-index",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F06",
        "family": "Range and Volatility Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/range-and-volatility-indicators/relative-volatility-index",
        "entry": "relativeVolatilityIndex",
        "params": [
          "input"
        ],
        "exports": [
          "relativeVolatilityIndex"
        ],
        "archetype": "series-transform",
        "signature": "relativeVolatilityIndex(input)"
      },
      "api": {
        "summary": "Relative Volatility Index: an RSI-shaped 0-100 oscillator that grades the rolling standard deviation of close recorded on up bars against the same measure recorded on down bars.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads only `period` (default 14, integer >= 2). It serves as both the standard-deviation window and the length of the two Wilder RMA smoothings applied to the up and down streams.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single key, `value`, bounded to 0-100; `latest.value` is its last reading. The warm-up is `2 * period - 2` leading nulls, so `ready_at` is 26 at the default period."
        },
        "warmup": {
          "count": "`2 * period - 2` bars (26 at the default period)",
          "value": "null",
          "note": "The standard deviation seeds at index `period - 1`, and each RMA then needs `period` consecutive non-null inputs before it emits, pushing the first reading to `2 * period - 2`. `value` is also null on any bar where the up and down averages sum to zero."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "bars are not strictly ordered by timestamp, or a bar's high is below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "relativeVolatilityIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F06-A04",
          "title": "Relative Volatility Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 26,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 32.31900401565408
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a04/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a04/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a04/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Relative Volatility Index calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations with session calendar, previous \"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Relative Volatility Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Relative Volatility Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/range-and-volatility-indicators/relative-volatility-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/range-and-volatility-indicators/relative-volatility-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F06-A05",
      "name": "Volatility Ratio",
      "headline": null,
      "slug": "volatility-ratio",
      "path": "technical-indicators/range-and-volatility-indicators/volatility-ratio",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F06",
        "family": "Range and Volatility Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/range-and-volatility-indicators/volatility-ratio",
        "entry": "volatilityRatio",
        "params": [
          "input"
        ],
        "exports": [
          "volatilityRatio"
        ],
        "archetype": "series-transform",
        "signature": "volatilityRatio(input)"
      },
      "api": {
        "summary": "Volatility Ratio: the standard deviation of close-to-close simple returns over a short window divided by the same measure over a long window.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads `short_period` (default 5, integer >= 2) and `long_period` (default 20, integer, and strictly greater than `short_period`). The family also validates `period` (default 14, integer >= 2) before this branch runs, even though the ratio does not use it.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single key, `value`, the short-over-long deviation ratio; `latest.value` is its last reading. The warm-up is `long_period` leading nulls, so `ready_at` is 20 at the defaults."
        },
        "warmup": {
          "count": "`long_period` bars (20 at the defaults)",
          "value": "null",
          "note": "Returns are undefined on the first bar, so the long-window deviation only completes at index `long_period` rather than `long_period - 1`. `value` is also null on any bar where the long-window deviation is zero."
        },
        "errors": [
          {
            "when": "`parameters.short_period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.long_period` is not an integer greater than `short_period`",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * long_period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "volatilityRatio({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F06-A05",
          "title": "Volatility Ratio",
          "state": "calculated",
          "ready": true,
          "ready_at": 20,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 0.593478196387429
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a05/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a05/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a05/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Volatility Ratio calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations with session calendar, previous \"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Volatility Ratio convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Volatility Ratio readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/range-and-volatility-indicators/volatility-ratio/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/range-and-volatility-indicators/volatility-ratio/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F06-A06",
      "name": "Volatility Quality Index",
      "headline": null,
      "slug": "volatility-quality-index",
      "path": "technical-indicators/range-and-volatility-indicators/volatility-quality-index",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F06",
        "family": "Range and Volatility Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/range-and-volatility-indicators/volatility-quality-index",
        "entry": "volatilityQualityIndex",
        "params": [
          "input"
        ],
        "exports": [
          "volatilityQualityIndex"
        ],
        "archetype": "series-transform",
        "signature": "volatilityQualityIndex(input)"
      },
      "api": {
        "summary": "Volatility Quality Index: accumulates each bar's true range signed by the direction of its close, then smooths the running total with an exponential moving average.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads only `period` (default 14, integer >= 2), the EMA length applied to the cumulative signed range.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `raw`, the signed true range contributed by each bar, and `value`, the EMA of the running total of `raw`. `latest` carries the last of each. `raw` has no warm-up at all -- it is zero on the first bar and populated from there on -- which is why `ready_at` is 0; `value` carries `period - 1` leading nulls."
        },
        "warmup": {
          "count": "0 bars for `raw`, `period - 1` bars for `value` (13 at the default period)",
          "value": "null",
          "note": "`raw` is defined from the first bar, so the result reports ready at index 0 even though `value` is still null there. Callers reading `latest.value` on a short history must check for null themselves."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "bars are not strictly ordered by timestamp, or a bar's high is below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "volatilityQualityIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F06-A06",
          "title": "Volatility Quality Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "raw": [
              0,
              3.3838169299999947,
              3.758713730000011,
              3.9386350599999957,
              -3.829996080000001,
              -3.4696505999999943
            ],
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "raw": -3.1208633100000043,
            "value": 12.394917882563625
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a06/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a06/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a06/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a06/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Volatility Quality Index calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations with session calendar, previous \"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Volatility Quality Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Volatility Quality Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/range-and-volatility-indicators/volatility-quality-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/range-and-volatility-indicators/volatility-quality-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F06-A07",
      "name": "Average Daily Range",
      "headline": null,
      "slug": "average-daily-range",
      "path": "technical-indicators/range-and-volatility-indicators/average-daily-range",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F06",
        "family": "Range and Volatility Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/range-and-volatility-indicators/average-daily-range",
        "entry": "averageDailyRange",
        "params": [
          "input"
        ],
        "exports": [
          "averageDailyRange"
        ],
        "archetype": "series-transform",
        "signature": "averageDailyRange(input)"
      },
      "api": {
        "summary": "Average Daily Range: the simple moving average of the bar's high-low range over `period` bars.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads only `period` (default 14, integer >= 2), the moving-average window.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single key, `value`, the averaged range in price units; `latest.value` is its last reading. The warm-up is `period - 1` leading nulls, so `ready_at` is 13 at the default period."
        },
        "warmup": {
          "count": "`period - 1` bars (13 at the default period)",
          "value": "null",
          "note": "The simple moving average only emits once a full `period`-bar window of ranges is available; there is no seeding or partial-window behaviour."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "bars are not strictly ordered by timestamp, or a bar's high is below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "averageDailyRange({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F06-A07",
          "title": "Average Daily Range",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 3.0896585750000014
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a07/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a07/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a07/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a07/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Average Daily Range calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations with session calendar, previous \"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Average Daily Range convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Average Daily Range readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/range-and-volatility-indicators/average-daily-range/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/range-and-volatility-indicators/average-daily-range/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F06-A08",
      "name": "Gap Volatility",
      "headline": null,
      "slug": "gap-volatility",
      "path": "technical-indicators/range-and-volatility-indicators/gap-volatility",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F06",
        "family": "Range and Volatility Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/range-and-volatility-indicators/gap-volatility",
        "entry": "gapVolatility",
        "params": [
          "input"
        ],
        "exports": [
          "gapVolatility"
        ],
        "archetype": "series-transform",
        "signature": "gapVolatility(input)"
      },
      "api": {
        "summary": "Gap Volatility: measures each bar's opening gap -- this open less the prior close -- and the rolling standard deviation of those gaps.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads only `period` (default 14, integer >= 2), the standard-deviation window.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `gap`, the raw open-minus-prior-close difference, and `value`, the population standard deviation of `gap` over `period` bars. `latest` carries the last of each. The two warm-ups differ: `gap` is null only on the first bar, which makes `ready_at` 1, while `value` first appears at index `period` (14 at the default)."
        },
        "warmup": {
          "count": "1 bar for `gap`, `period` bars for `value` (14 at the default period)",
          "value": "null",
          "note": "`gap` is undefined on the first bar because there is no prior close, so the deviation window needs one extra bar and lands at index `period` rather than `period - 1`."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "bars are not strictly ordered by timestamp, or a bar's high is below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "gapVolatility({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F06-A08",
          "title": "Gap Volatility",
          "state": "calculated",
          "ready": true,
          "ready_at": 1,
          "series": {
            "gap": [
              null,
              1.4911145199999964,
              0.6672783399999958,
              -0.26733595999999693,
              -0.8183669500000121,
              -0.720687060000003
            ],
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "gap": -1.106646689999991,
            "value": 1.1343149298154644
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a08/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a08/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a08/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a08/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Gap Volatility calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations with session calendar, previous \"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Gap Volatility convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Gap Volatility readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/range-and-volatility-indicators/gap-volatility/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/range-and-volatility-indicators/gap-volatility/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F06-A09",
      "name": "Range Efficiency Ratio",
      "headline": null,
      "slug": "range-efficiency-ratio",
      "path": "technical-indicators/range-and-volatility-indicators/range-efficiency-ratio",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F06",
        "family": "Range and Volatility Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/range-and-volatility-indicators/range-efficiency-ratio",
        "entry": "rangeEfficiencyRatio",
        "params": [
          "input"
        ],
        "exports": [
          "rangeEfficiencyRatio"
        ],
        "archetype": "series-transform",
        "signature": "rangeEfficiencyRatio(input)"
      },
      "api": {
        "summary": "Range Efficiency Ratio: the absolute net close-to-close move across `period` bars divided by the sum of the high-low ranges over the same span.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads only `period` (default 14, integer >= 2), which sets both the close lookback and the range-summing window.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single key, `value`, a 0-1 efficiency reading; `latest.value` is its last value. The warm-up is `period` leading nulls, so `ready_at` is 14 at the default period."
        },
        "warmup": {
          "count": "`period` bars (14 at the default period)",
          "value": "null",
          "note": "The numerator compares the close against the close `period` bars earlier, so it needs one more bar than the range window does. `value` is also null on any bar where the summed range is zero."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "bars are not strictly ordered by timestamp, or a bar's high is below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "rangeEfficiencyRatio({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F06-A09",
          "title": "Range Efficiency Ratio",
          "state": "calculated",
          "ready": true,
          "ready_at": 14,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 0.07606679254426744
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a09/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a09/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a09/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a09/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Range Efficiency Ratio calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations with session calendar, previous \"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Range Efficiency Ratio convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Range Efficiency Ratio readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/range-and-volatility-indicators/range-efficiency-ratio/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/range-and-volatility-indicators/range-efficiency-ratio/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F06-A10",
      "name": "High-Low Range Percentage",
      "headline": null,
      "slug": "high-low-range-percentage",
      "path": "technical-indicators/range-and-volatility-indicators/high-low-range-percentage",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F06",
        "family": "Range and Volatility Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/range-and-volatility-indicators/high-low-range-percentage",
        "entry": "highLowRangePercentage",
        "params": [
          "input"
        ],
        "exports": [
          "highLowRangePercentage"
        ],
        "archetype": "series-transform",
        "signature": "highLowRangePercentage(input)"
      },
      "api": {
        "summary": "Expresses the bar's high-low range as a percentage of its high-low midpoint: `200 * (high - low) / (high + low)`.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. This topic reads no keys of its own from `parameters`, but the family still validates `period` (default 14, integer >= 2) before the branch runs, so an invalid `period` is rejected here too.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single key, `value`, the per-bar range percentage; `latest.value` is the last bar's reading. There is no warm-up -- the calculation is per-bar, so `ready_at` is 0."
        },
        "warmup": {
          "count": "0 bars",
          "value": "not applicable",
          "note": "Every bar is self-contained, so `value` is populated from index 0. The only null case is a bar where `high + low` is exactly zero."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "bars are not strictly ordered by timestamp, or a bar's high is below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "highLowRangePercentage({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F06-A10",
          "title": "High-Low Range Percentage",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "value": [
              2.753004072047775,
              3.272748071764005,
              3.6566626050949482,
              3.82208970566863,
              3.7288541366298587,
              3.392411654116297
            ]
          },
          "latest": {
            "value": 3.1131062534873144
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a10/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a10/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a10/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a10/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "High-Low Range Percentage calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations with session calendar, previous \"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected High-Low Range Percentage convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "High-Low Range Percentage readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/range-and-volatility-indicators/high-low-range-percentage/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/range-and-volatility-indicators/high-low-range-percentage/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F06-A11",
      "name": "Normalized Price Range",
      "headline": null,
      "slug": "normalized-price-range",
      "path": "technical-indicators/range-and-volatility-indicators/normalized-price-range",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F06",
        "family": "Range and Volatility Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/range-and-volatility-indicators/normalized-price-range",
        "entry": "normalizedPriceRange",
        "params": [
          "input"
        ],
        "exports": [
          "normalizedPriceRange"
        ],
        "archetype": "series-transform",
        "signature": "normalizedPriceRange(input)"
      },
      "api": {
        "summary": "Places the close inside the highest high and lowest low of the last `period` bars, scaled to a 0-1 position.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads only `period` (default 14, integer >= 2), the lookback for the rolling extremes.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single key, `value`, a 0-1 position within the recent range; `latest.value` is its last reading. The warm-up is `period - 1` leading nulls, so `ready_at` is 13 at the default period."
        },
        "warmup": {
          "count": "`period - 1` bars (13 at the default period)",
          "value": "null",
          "note": "Both the rolling highest high and the rolling lowest low need a full window before they emit. `value` is also null on any bar where the window high equals the window low, since the range would be zero."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "bars are not strictly ordered by timestamp, or a bar's high is below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "normalizedPriceRange({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F06-A11",
          "title": "Normalized Price Range",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 0.11680400310516117
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a11/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a11/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a11/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a11/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Normalized Price Range calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations with session calendar, previous \"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Normalized Price Range convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Normalized Price Range readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/range-and-volatility-indicators/normalized-price-range/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/range-and-volatility-indicators/normalized-price-range/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F06-A12",
      "name": "Volatility Stop",
      "headline": null,
      "slug": "volatility-stop",
      "path": "technical-indicators/range-and-volatility-indicators/volatility-stop",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F06",
        "family": "Range and Volatility Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/range-and-volatility-indicators/volatility-stop",
        "entry": "volatilityStop",
        "params": [
          "input"
        ],
        "exports": [
          "volatilityStop"
        ],
        "archetype": "series-transform",
        "signature": "volatilityStop(input)"
      },
      "api": {
        "summary": "Volatility Stop: a trailing long stop set `multiplier` ATRs below the highest close of the last `period` bars, and a short stop the same distance above the lowest close.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads `period` (default 14, integer >= 2), used for both the rolling close extremes and the Wilder ATR, and `multiplier` (default 3, a finite number >= 0).",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `long_stop` and `short_stop`, both in price units; `latest` carries the last of each. They share a warm-up of `period - 1` leading nulls, so `ready_at` is 13 at the default period."
        },
        "warmup": {
          "count": "`period - 1` bars (13 at the default period)",
          "value": "null",
          "note": "Both stops need the ATR seed and a full extremes window, and both complete at the same index. The stops do not ratchet or flip; each bar is recomputed from its own window."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.multiplier` is not a finite number, or is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "volatilityStop({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F06-A12",
          "title": "Volatility Stop",
          "state": "calculated",
          "ready": true,
          "ready_at": 13,
          "series": {
            "long_stop": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "short_stop": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "long_stop": 98.43630241500071,
            "short_stop": 109.72647177499931
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a12/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a12/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a12/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f06-a12/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Volatility Stop calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations with session calendar, previous \"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Volatility Stop convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Volatility Stop readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/range-and-volatility-indicators/volatility-stop/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/range-and-volatility-indicators/volatility-stop/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F07-A01",
      "name": "Bollinger %B",
      "headline": null,
      "slug": "bollinger-percent-b",
      "path": "technical-indicators/bands-envelopes-and-squeezes/bollinger-percent-b",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F07",
        "family": "Bands, Envelopes, and Squeezes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/bands-envelopes-and-squeezes/bollinger-percent-b",
        "entry": "bollingerPercentB",
        "params": [
          "input"
        ],
        "exports": [
          "bollingerPercentB"
        ],
        "archetype": "series-transform",
        "signature": "bollingerPercentB(input)"
      },
      "api": {
        "summary": "Bollinger Bands together with %B, the close's position between the lower and upper band. The band arithmetic is delegated to the already-shipped `bollingerBands` implementation.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads `period` (default 20, integer >= 2), the window for the simple moving average and the standard deviation, and `multiplier` (default 2, a finite number >= 0), the band width in deviations. A `multiplier` of 0 collapses both bands onto the centre and bypasses the shared implementation.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `center`, `upper`, `lower` and `percent_b`; `latest` carries the last of each. All four share a warm-up of `period - 1` leading nulls, so `ready_at` is 19 at the default period."
        },
        "warmup": {
          "count": "`period - 1` bars (19 at the default period)",
          "value": "null",
          "note": "The moving average and the standard deviation both complete at index `period - 1`. Past that, `percent_b` is still null wherever the upper and lower bands are equal -- which is every bar when `multiplier` is 0."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.multiplier` is not a finite number, or is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "bollingerPercentB({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F07-A01",
          "title": "Bollinger %B",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "center": [
              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
            ]
          },
          "latest": {
            "center": 104.20055051999998,
            "upper": 108.52982269312228,
            "lower": 99.87127834687767,
            "percent_b": 0.013805568042643967
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a01/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a01/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a01/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Bollinger %B calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations, a declared centerline,\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Bollinger %B convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Bollinger %B readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/bands-envelopes-and-squeezes/bollinger-percent-b/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/bands-envelopes-and-squeezes/bollinger-percent-b/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F07-A02",
      "name": "Moving Average Envelope",
      "headline": null,
      "slug": "moving-average-envelope",
      "path": "technical-indicators/bands-envelopes-and-squeezes/moving-average-envelope",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F07",
        "family": "Bands, Envelopes, and Squeezes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/bands-envelopes-and-squeezes/moving-average-envelope",
        "entry": "movingAverageEnvelope",
        "params": [
          "input"
        ],
        "exports": [
          "movingAverageEnvelope"
        ],
        "archetype": "series-transform",
        "signature": "movingAverageEnvelope(input)"
      },
      "api": {
        "summary": "Moving Average Envelope: a simple moving average of close with bands set a fixed percentage above and below it.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads `period` (default 20, integer >= 2), the moving-average window, and `percentage` (default 0.025, a finite number >= 0), the fractional envelope width. `period` (default 20, integer >= 2) and `multiplier` (default 2, a finite number >= 0) are read and validated by the band family for every topic in it. `multiplier` is not used by this branch.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `center`, `upper` (`center * (1 + percentage)`) and `lower` (`center * (1 - percentage)`); `latest` carries the last of each. All three share a warm-up of `period - 1` leading nulls, so `ready_at` is 19 at the default period."
        },
        "warmup": {
          "count": "`period - 1` bars (19 at the default period)",
          "value": "null",
          "note": "The envelope is a pure scaling of the centre line, so the bands become available on exactly the bar the moving average does."
        },
        "errors": [
          {
            "when": "`parameters.percentage` is not a finite number, or is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "movingAverageEnvelope({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F07-A02",
          "title": "Moving Average Envelope",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "center": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "upper": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "center": 104.20055051999998,
            "upper": 106.80556428299997,
            "lower": 101.59553675699998
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a02/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a02/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a02/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Moving Average Envelope calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations, a declared centerline,\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Moving Average Envelope convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Moving Average Envelope readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/bands-envelopes-and-squeezes/moving-average-envelope/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/bands-envelopes-and-squeezes/moving-average-envelope/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F07-A03",
      "name": "ATR Bands",
      "headline": null,
      "slug": "atr-bands",
      "path": "technical-indicators/bands-envelopes-and-squeezes/atr-bands",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F07",
        "family": "Bands, Envelopes, and Squeezes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/bands-envelopes-and-squeezes/atr-bands",
        "entry": "atrBands",
        "params": [
          "input"
        ],
        "exports": [
          "atrBands"
        ],
        "archetype": "series-transform",
        "signature": "atrBands(input)"
      },
      "api": {
        "summary": "ATR Bands: a simple moving average of close with bands `multiplier` Average True Ranges above and below it.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads `period` (default 20, integer >= 2), which sets both the moving average and the Wilder ATR length, and `multiplier` (default 2, a finite number >= 0), the band width in ATRs.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `center`, `upper` and `lower`; `latest` carries the last of each. All three share a warm-up of `period - 1` leading nulls, so `ready_at` is 19 at the default period. This topic and STARC Bands are deliberately frozen to the same arithmetic."
        },
        "warmup": {
          "count": "`period - 1` bars (19 at the default period)",
          "value": "null",
          "note": "The moving average and the ATR seed complete on the same bar, so the centre and both bands appear together."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.multiplier` is not a finite number, or is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "atrBands({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F07-A03",
          "title": "ATR Bands",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "center": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "upper": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "center": 104.20055051999998,
            "upper": 110.647723370334,
            "lower": 97.75337766966595
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a03/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a03/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a03/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "ATR Bands calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations, a declared centerline,\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected ATR Bands convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "ATR Bands readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/bands-envelopes-and-squeezes/atr-bands/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/bands-envelopes-and-squeezes/atr-bands/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F07-A04",
      "name": "Standard Deviation Channel",
      "headline": null,
      "slug": "standard-deviation-channel",
      "path": "technical-indicators/bands-envelopes-and-squeezes/standard-deviation-channel",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F07",
        "family": "Bands, Envelopes, and Squeezes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/bands-envelopes-and-squeezes/standard-deviation-channel",
        "entry": "standardDeviationChannel",
        "params": [
          "input"
        ],
        "exports": [
          "standardDeviationChannel"
        ],
        "archetype": "series-transform",
        "signature": "standardDeviationChannel(input)"
      },
      "api": {
        "summary": "Standard Deviation Channel: a simple moving average of close with bands `multiplier` population standard deviations above and below it.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads `period` (default 20, integer >= 2), the window for both the moving average and the standard deviation, and `multiplier` (default 2, a finite number >= 0), the band width in deviations.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `center`, `upper` and `lower`; `latest` carries the last of each. All three share a warm-up of `period - 1` leading nulls, so `ready_at` is 19 at the default period."
        },
        "warmup": {
          "count": "`period - 1` bars (19 at the default period)",
          "value": "null",
          "note": "The standard deviation is computed over the population of the window, with no degrees-of-freedom correction, and emits only once the window is full."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.multiplier` is not a finite number, or is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "standardDeviationChannel({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F07-A04",
          "title": "Standard Deviation Channel",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "center": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "upper": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "center": 104.20055051999998,
            "upper": 108.52982269312228,
            "lower": 99.87127834687767
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a04/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a04/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a04/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Standard Deviation Channel calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations, a declared centerline,\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Standard Deviation Channel convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Standard Deviation Channel readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/bands-envelopes-and-squeezes/standard-deviation-channel/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/bands-envelopes-and-squeezes/standard-deviation-channel/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F07-A05",
      "name": "Regression Channel",
      "headline": null,
      "slug": "regression-channel",
      "path": "technical-indicators/bands-envelopes-and-squeezes/regression-channel",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F07",
        "family": "Bands, Envelopes, and Squeezes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/bands-envelopes-and-squeezes/regression-channel",
        "entry": "regressionChannel",
        "params": [
          "input"
        ],
        "exports": [
          "regressionChannel"
        ],
        "archetype": "series-transform",
        "signature": "regressionChannel(input)"
      },
      "api": {
        "summary": "Regression Channel: the end point of a rolling least-squares fit of close over `period` bars, with bands `multiplier` root-mean-square residuals above and below that fitted point.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads `period` (default 20, integer >= 2), the regression window, and `multiplier` (default 2, a finite number >= 0), the channel half-width in residual units.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `center`, the fitted close at the end of each window, plus `upper` and `lower`; `latest` carries the last of each. All three share a warm-up of `period - 1` leading nulls, so `ready_at` is 19 at the default period."
        },
        "warmup": {
          "count": "`period - 1` bars (19 at the default period)",
          "value": "null",
          "note": "The fit is recomputed from scratch on each full window, so nothing is emitted until `period` closes exist. The channel does not extend or anchor across windows."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.multiplier` is not a finite number, or is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "regressionChannel({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F07-A05",
          "title": "Regression Channel",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "center": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "upper": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "center": 103.97453763199998,
            "upper": 108.29510693120406,
            "lower": 99.6539683327959
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a05/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a05/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a05/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Regression Channel calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations, a declared centerline,\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Regression Channel convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Regression Channel readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/bands-envelopes-and-squeezes/regression-channel/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/bands-envelopes-and-squeezes/regression-channel/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F07-A06",
      "name": "Raff Regression Channel",
      "headline": null,
      "slug": "raff-regression-channel",
      "path": "technical-indicators/bands-envelopes-and-squeezes/raff-regression-channel",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F07",
        "family": "Bands, Envelopes, and Squeezes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/bands-envelopes-and-squeezes/raff-regression-channel",
        "entry": "raffRegressionChannel",
        "params": [
          "input"
        ],
        "exports": [
          "raffRegressionChannel"
        ],
        "archetype": "series-transform",
        "signature": "raffRegressionChannel(input)"
      },
      "api": {
        "summary": "Raff Regression Channel: the same rolling least-squares centre line as the regression channel, but the channel half-width is the largest absolute residual in the window rather than its root mean square.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads `period` (default 20, integer >= 2), the regression window, and `multiplier` (default 2, a finite number >= 0) applied to the widest residual.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `center`, `upper` and `lower`; `latest` carries the last of each. All three share a warm-up of `period - 1` leading nulls, so `ready_at` is 19 at the default period. `center` is the fitted value at the end of the window, `upper` is `center + multiplier * width` and `lower` is `center - multiplier * width`, where `width` is the largest absolute residual of that window. At the default `multiplier` of 2 the channel is twice the textbook Raff width; pass `multiplier: 1` for that variant."
        },
        "warmup": {
          "count": "`period - 1` bars (19 at the default period)",
          "value": "null",
          "note": "The centre is the fitted value at the end of the window and appears once `period` closes exist. The band at index t contains that bar's close whenever `multiplier >= 1`, and at `multiplier: 0` both bands collapse onto the centre and generally exclude it. The band is not a claim about the rest of the window: earlier closes are measured against the sloped fit, not against `center`, so they can sit outside the published band."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.multiplier` is not a finite number, or is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "raffRegressionChannel({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F07-A06",
          "title": "Raff Regression Channel",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "center": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "upper": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "center": 103.97453763199998,
            "upper": 111.94198395599993,
            "lower": 96.00709130800003
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a06/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a06/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a06/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a06/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Raff Regression Channel calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations, a declared centerline,\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Raff Regression Channel convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Raff Regression Channel readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/bands-envelopes-and-squeezes/raff-regression-channel/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/bands-envelopes-and-squeezes/raff-regression-channel/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F07-A07",
      "name": "STARC Bands",
      "headline": null,
      "slug": "starc-bands",
      "path": "technical-indicators/bands-envelopes-and-squeezes/starc-bands",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F07",
        "family": "Bands, Envelopes, and Squeezes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/bands-envelopes-and-squeezes/starc-bands",
        "entry": "starcBands",
        "params": [
          "input"
        ],
        "exports": [
          "starcBands"
        ],
        "archetype": "series-transform",
        "signature": "starcBands(input)"
      },
      "api": {
        "summary": "STARC Bands: a simple moving average of close with bands `multiplier` Average True Ranges above and below it.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads `period` (default 20, integer >= 2), which sets both the moving average and the Wilder ATR length, and `multiplier` (default 2, a finite number >= 0), the band width in ATRs.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `center`, `upper` and `lower`; `latest` carries the last of each. All three share a warm-up of `period - 1` leading nulls, so `ready_at` is 19 at the default period. This topic and ATR Bands are deliberately frozen to the same arithmetic."
        },
        "warmup": {
          "count": "`period - 1` bars (19 at the default period)",
          "value": "null",
          "note": "The moving average and the ATR seed complete on the same bar, so the centre and both bands appear together."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.multiplier` is not a finite number, or is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "starcBands({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F07-A07",
          "title": "STARC Bands",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "center": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "upper": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "center": 104.20055051999998,
            "upper": 110.647723370334,
            "lower": 97.75337766966595
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a07/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a07/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a07/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a07/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "STARC Bands calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations, a declared centerline,\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected STARC Bands convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "STARC Bands readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/bands-envelopes-and-squeezes/starc-bands/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/bands-envelopes-and-squeezes/starc-bands/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F07-A08",
      "name": "Fractal Chaos Bands",
      "headline": null,
      "slug": "fractal-chaos-bands",
      "path": "technical-indicators/bands-envelopes-and-squeezes/fractal-chaos-bands",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F07",
        "family": "Bands, Envelopes, and Squeezes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/bands-envelopes-and-squeezes/fractal-chaos-bands",
        "entry": "fractalChaosBands",
        "params": [
          "input"
        ],
        "exports": [
          "fractalChaosBands"
        ],
        "archetype": "series-transform",
        "signature": "fractalChaosBands(input)"
      },
      "api": {
        "summary": "Fractal Chaos Bands: carries forward the most recent confirmed five-bar fractal high and fractal low, each held flat until a new fractal of that side confirms.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. This topic reads no keys of its own from `parameters`; the five-bar fractal window is fixed in code. `period` (default 20, integer >= 2) and `multiplier` (default 2, a finite number >= 0) are read and validated by the band family for every topic in it. Neither is used by this branch, but an invalid value is still rejected.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds only `upper` and `lower` -- there is no `center` for this topic -- and `latest` carries the last of each. The warm-up is data dependent: a fractal is confirmed two bars after its pivot, so nothing can appear before index 4, and each side stays null until its first fractal confirms. In the canonical fixture `upper` first appears at index 5 and `lower` at index 8, making `ready_at` 5."
        },
        "warmup": {
          "count": "at least 4 bars, then data dependent per side",
          "value": "null",
          "note": "Confirmation needs two bars either side of the pivot, so index 4 is the earliest possible reading, and the actual first index depends on when a qualifying high or low occurs. `upper` and `lower` can therefore become available on different bars."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "bars are not strictly ordered by timestamp, or a bar's high is below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "fractalChaosBands({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F07-A08",
          "title": "Fractal Chaos Bands",
          "state": "calculated",
          "ready": true,
          "ready_at": 5,
          "series": {
            "upper": [
              null,
              null,
              null,
              null,
              null,
              105.01857496
            ],
            "lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "upper": 109.83623682,
            "lower": 101.07584902
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a08/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a08/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a08/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a08/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Fractal Chaos Bands calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations, a declared centerline,\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Fractal Chaos Bands convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Fractal Chaos Bands readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/bands-envelopes-and-squeezes/fractal-chaos-bands/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/bands-envelopes-and-squeezes/fractal-chaos-bands/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F07-A09",
      "name": "Projection Bands",
      "headline": null,
      "slug": "projection-bands",
      "path": "technical-indicators/bands-envelopes-and-squeezes/projection-bands",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F07",
        "family": "Bands, Envelopes, and Squeezes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/bands-envelopes-and-squeezes/projection-bands",
        "entry": "projectionBands",
        "params": [
          "input"
        ],
        "exports": [
          "projectionBands"
        ],
        "archetype": "series-transform",
        "signature": "projectionBands(input)"
      },
      "api": {
        "summary": "Projection Bands: fits a least-squares slope to the highs and to the lows of the last `period` bars, projects every bar in the window forward along that slope, and takes the highest projected high and the lowest projected low.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads only `period` (default 20, integer >= 2), the regression and projection window. `period` (default 20, integer >= 2) and `multiplier` (default 2, a finite number >= 0) are read and validated by the band family for every topic in it. `multiplier` is not used by this branch.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds only `upper` and `lower` -- this topic emits no `center` -- and `latest` carries the last of each. Both share a warm-up of `period - 1` leading nulls, so `ready_at` is 19 at the default period."
        },
        "warmup": {
          "count": "`period - 1` bars (19 at the default period)",
          "value": "null",
          "note": "Each band is recomputed from a full window of highs or lows; there is no partial-window output and no carry forward between windows."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "bars are not strictly ordered by timestamp, or a bar's high is below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "projectionBands({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F07-A09",
          "title": "Projection Bands",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "upper": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "upper": 109.63429948293232,
            "lower": 98.68874251
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a09/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a09/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a09/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a09/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Projection Bands calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations, a declared centerline,\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Projection Bands convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Projection Bands readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/bands-envelopes-and-squeezes/projection-bands/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/bands-envelopes-and-squeezes/projection-bands/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F07-A10",
      "name": "Dynamic Zone Bands",
      "headline": null,
      "slug": "dynamic-zone-bands",
      "path": "technical-indicators/bands-envelopes-and-squeezes/dynamic-zone-bands",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F07",
        "family": "Bands, Envelopes, and Squeezes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/bands-envelopes-and-squeezes/dynamic-zone-bands",
        "entry": "dynamicZoneBands",
        "params": [
          "input"
        ],
        "exports": [
          "dynamicZoneBands"
        ],
        "archetype": "series-transform",
        "signature": "dynamicZoneBands(input)"
      },
      "api": {
        "summary": "Dynamic Zone Bands: a quantile envelope of close -- the upper band is the `1 - q` quantile of the last `period` closes and the lower band the `q` quantile -- drawn around a simple moving average.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads `period` (default 20, integer >= 2), the quantile and moving-average window, and `q` (default 0.2, a finite number between 0 and 0.5 inclusive), the tail fraction. `period` (default 20, integer >= 2) and `multiplier` (default 2, a finite number >= 0) are read and validated by the band family for every topic in it. `multiplier` is not used by this branch.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `upper`, `lower` and `center`, in that order; `latest` carries the last of each. All three share a warm-up of `period - 1` leading nulls, so `ready_at` is 19 at the default period."
        },
        "warmup": {
          "count": "`period - 1` bars (19 at the default period)",
          "value": "null",
          "note": "Quantiles are taken over the sorted window with linear interpolation between neighbouring closes, and emit only once the window is full."
        },
        "errors": [
          {
            "when": "`parameters.q` is not a finite number, or falls outside 0 to 0.5",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period * log period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "dynamicZoneBands({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F07-A10",
          "title": "Dynamic Zone Bands",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "upper": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "center": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "upper": 106.046989472,
            "lower": 102.788143482,
            "center": 104.20055051999998
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a10/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a10/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a10/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a10/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Dynamic Zone Bands calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations, a declared centerline,\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Dynamic Zone Bands convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Dynamic Zone Bands readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/bands-envelopes-and-squeezes/dynamic-zone-bands/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/bands-envelopes-and-squeezes/dynamic-zone-bands/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F07-A11",
      "name": "TTM Squeeze",
      "headline": null,
      "slug": "ttm-squeeze",
      "path": "technical-indicators/bands-envelopes-and-squeezes/ttm-squeeze",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F07",
        "family": "Bands, Envelopes, and Squeezes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/bands-envelopes-and-squeezes/ttm-squeeze",
        "entry": "ttmSqueeze",
        "params": [
          "input"
        ],
        "exports": [
          "ttmSqueeze"
        ],
        "archetype": "series-transform",
        "signature": "ttmSqueeze(input)"
      },
      "api": {
        "summary": "TTM Squeeze: flags the bars on which the Bollinger band pair sits entirely inside the Keltner channel pair, the conventional sign of a volatility contraction.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads `period` (default 20, integer >= 2), used for the moving average, the standard deviation, the Keltner EMA and the ATR alike, and `multiplier` (default 2, a finite number >= 0), applied to both band pairs.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `squeeze_on`, `bb_upper`, `bb_lower`, `kc_upper` and `kc_lower`; `latest` carries the last of each. `squeeze_on` is a boolean, not a number, and `false` is a real reading meaning no squeeze -- only null means not yet computed. All five share a warm-up of `period - 1` leading nulls, so `ready_at` is 19 at the default period."
        },
        "warmup": {
          "count": "`period - 1` bars (19 at the default period)",
          "value": "null",
          "note": "The Bollinger pair, the Keltner pair and therefore the flag all become available on the same bar. Do not treat a falsy `squeeze_on` as absence of data: check for null explicitly, since `false` carries meaning."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.multiplier` is not a finite number, or is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "ttmSqueeze({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F07-A11",
          "title": "TTM Squeeze",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "squeeze_on": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "bb_upper": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "bb_lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "kc_upper": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "kc_lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "squeeze_on": true,
            "bb_upper": 108.52982269312228,
            "bb_lower": 99.87127834687767,
            "kc_upper": 110.40185024876313,
            "kc_lower": 97.50750454809507
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a11/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a11/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a11/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a11/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "TTM Squeeze calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations, a declared centerline,\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected TTM Squeeze convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "TTM Squeeze readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/bands-envelopes-and-squeezes/ttm-squeeze/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/bands-envelopes-and-squeezes/ttm-squeeze/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F07-A12",
      "name": "Squeeze Momentum",
      "headline": null,
      "slug": "squeeze-momentum",
      "path": "technical-indicators/bands-envelopes-and-squeezes/squeeze-momentum",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F07",
        "family": "Bands, Envelopes, and Squeezes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/bands-envelopes-and-squeezes/squeeze-momentum",
        "entry": "squeezeMomentum",
        "params": [
          "input"
        ],
        "exports": [
          "squeezeMomentum"
        ],
        "archetype": "series-transform",
        "signature": "squeezeMomentum(input)"
      },
      "api": {
        "summary": "Squeeze Momentum: the TTM squeeze flag and its two band pairs, plus a momentum line -- the regression slope of the close's distance from the midpoint of the `period`-bar high-low range.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads `period` (default 20, integer >= 2), used for the moving average, the standard deviation, the Keltner EMA, the ATR, the range extremes and the momentum regression, and `multiplier` (default 2, a finite number >= 0), applied to both band pairs.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `squeeze_on`, `bb_upper`, `bb_lower`, `kc_upper`, `kc_lower` and `momentum`; `latest` carries the last of each. `squeeze_on` is a boolean and `false` is a real reading meaning no squeeze. The warm-ups differ: the flag and the four bands appear at `period - 1` (19 at the default), which sets `ready_at`, while `momentum` needs a full window of those readings and first appears at `2 * period - 2` (38)."
        },
        "warmup": {
          "count": "`period - 1` bars for the bands and the flag, `2 * period - 2` bars for `momentum` (19 and 38 at the default period)",
          "value": "null",
          "note": "`momentum` regresses the close-minus-midpoint displacement over `period` bars, and that displacement is itself null until the range extremes fill, so it lags the rest of the payload by another `period - 1` bars. The topic reports ready before `momentum` exists."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.multiplier` is not a finite number, or is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "squeezeMomentum({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F07-A12",
          "title": "Squeeze Momentum",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "squeeze_on": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "bb_upper": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "bb_lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "kc_upper": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "kc_lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "momentum": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "squeeze_on": true,
            "bb_upper": 108.52982269312228,
            "bb_lower": 99.87127834687767,
            "kc_upper": 110.40185024876313,
            "kc_lower": 97.50750454809507,
            "momentum": 0.0214809381766915
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a12/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a12/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a12/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a12/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Squeeze Momentum calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations, a declared centerline,\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Squeeze Momentum convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Squeeze Momentum readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/bands-envelopes-and-squeezes/squeeze-momentum/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/bands-envelopes-and-squeezes/squeeze-momentum/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F07-A13",
      "name": "Adaptive Price Zone",
      "headline": null,
      "slug": "adaptive-price-zone",
      "path": "technical-indicators/bands-envelopes-and-squeezes/adaptive-price-zone",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F07",
        "family": "Bands, Envelopes, and Squeezes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/bands-envelopes-and-squeezes/adaptive-price-zone",
        "entry": "adaptivePriceZone",
        "params": [
          "input"
        ],
        "exports": [
          "adaptivePriceZone"
        ],
        "archetype": "series-transform",
        "signature": "adaptivePriceZone(input)"
      },
      "api": {
        "summary": "Adaptive Price Zone: a double-smoothed EMA of close as the centre line, with bands `multiplier` double-smoothed EMAs of the high-low range above and below it.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV array -- each bar carries `timestamp`, `open`, `high`, `low`, `close`, `volume` and an optional `basis`, strictly ordered by timestamp. From `parameters` this topic reads `period` (default 20, integer >= 2), the length of each of the two EMA passes, and `multiplier` (default 2, a finite number >= 0), the band width in smoothed ranges.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `center`, `upper` and `lower`; `latest` carries the last of each. All three share a warm-up of `2 * period - 2` leading nulls, so `ready_at` is 38 at the default period -- noticeably longer than the other band topics."
        },
        "warmup": {
          "count": "`2 * period - 2` bars (38 at the default period)",
          "value": "null",
          "note": "Both the centre and the width are EMAs of EMAs: the inner pass seeds at `period - 1`, and the outer pass then needs `period` consecutive non-null inputs before it emits."
        },
        "errors": [
          {
            "when": "`parameters.period` is not an integer >= 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.multiplier` is not a finite number, or is negative",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar is missing open, high, low, close, or volume, or one of them is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "adaptivePriceZone({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F07-A13",
          "title": "Adaptive Price Zone",
          "state": "calculated",
          "ready": true,
          "ready_at": 38,
          "series": {
            "center": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "upper": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "center": 104.55810128266437,
            "upper": 110.82015139881207,
            "lower": 98.29605116651666
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a13/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a13/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a13/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f07-a13/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Adaptive Price Zone calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC or close observations, a declared centerline,\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Adaptive Price Zone convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Adaptive Price Zone readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/bands-envelopes-and-squeezes/adaptive-price-zone/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/bands-envelopes-and-squeezes/adaptive-price-zone/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F08-A01",
      "name": "Typical Price",
      "headline": null,
      "slug": "typical-price",
      "path": "technical-indicators/price-transforms/typical-price",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F08",
        "family": "Price Transforms",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/price-transforms/typical-price",
        "entry": "typicalPrice",
        "params": [
          "input"
        ],
        "exports": [
          "typicalPrice"
        ],
        "archetype": "series-transform",
        "signature": "typicalPrice(input)"
      },
      "api": {
        "summary": "Averages each bar's high, low and close into a single representative price.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `high`, `low` and `close`. This topic reads no keys from `parameters`, though `parameters` must still be an object when supplied.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single `value`, `(high + low + close) / 3` for every bar, and `latest` its last element. Every bar produces a value, so there is no warm-up."
        },
        "warmup": {
          "count": "none",
          "value": "not applicable",
          "note": "`ready_at` is 0. The transform is per-bar with no state and no window."
        },
        "errors": [
          {
            "when": "a bar's `high`, `low` or `close` is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "a `high` is below the bar's `open`, `low` or `close`",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty or not an array",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "typicalPrice({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F08-A01",
          "title": "Typical Price",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "value": [
              100.04833333333333,
              101.74217643000001,
              102.84553092333333,
              103.11026585,
              102.75204238333333,
              102.27411882333332
            ]
          },
          "latest": {
            "value": 100.16305426666668
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a01/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a01/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a01/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Typical Price calculation flow",
            "source": "flowchart LR\n    A[\"finite, basis-consistent OHLC observations and any require\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Typical Price convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Typical Price readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/price-transforms/typical-price/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/price-transforms/typical-price/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F08-A02",
      "name": "Median Price Transform",
      "headline": null,
      "slug": "median-price-transform",
      "path": "technical-indicators/price-transforms/median-price-transform",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F08",
        "family": "Price Transforms",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/price-transforms/median-price-transform",
        "entry": "medianPriceTransform",
        "params": [
          "input"
        ],
        "exports": [
          "medianPriceTransform"
        ],
        "archetype": "series-transform",
        "signature": "medianPriceTransform(input)"
      },
      "api": {
        "summary": "Takes the midpoint of each bar's high and low.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `high` and `low`. This topic reads no keys from `parameters`, though `parameters` must still be an object when supplied.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single `value`, `(high + low) / 2` for every bar, and `latest` its last element. Every bar produces a value, so there is no warm-up."
        },
        "warmup": {
          "count": "none",
          "value": "not applicable",
          "note": "`ready_at` is 0. The close is deliberately not part of this midpoint."
        },
        "errors": [
          {
            "when": "a bar's `high` or `low` is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "a `low` is above the bar's `open`, `high` or `close`",
            "behaviour": "throws Error"
          },
          {
            "when": "a `timestamp` is missing or not text",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "medianPriceTransform({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F08-A02",
          "title": "Median Price Transform",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "value": [
              100.07249999999999,
              101.719308575,
              102.790826935,
              103.04925743,
              102.71241351,
              102.27681525
            ]
          },
          "latest": {
            "value": 100.249174165
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a02/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a02/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a02/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Median Price Transform calculation flow",
            "source": "flowchart LR\n    A[\"finite, basis-consistent OHLC observations and any require\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Median Price Transform convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Median Price Transform readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/price-transforms/median-price-transform/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/price-transforms/median-price-transform/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F08-A03",
      "name": "Weighted Close",
      "headline": null,
      "slug": "weighted-close",
      "path": "technical-indicators/price-transforms/weighted-close",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F08",
        "family": "Price Transforms",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/price-transforms/weighted-close",
        "entry": "weightedClose",
        "params": [
          "input"
        ],
        "exports": [
          "weightedClose"
        ],
        "archetype": "series-transform",
        "signature": "weightedClose(input)"
      },
      "api": {
        "summary": "Averages high, low and a double-weighted close so the settlement price dominates the bar.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `high`, `low` and `close`. This topic reads no keys from `parameters`, though `parameters` must still be an object when supplied.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single `value`, `(high + low + 2 * close) / 4` for every bar, and `latest` its last element. Every bar produces a value, so there is no warm-up."
        },
        "warmup": {
          "count": "none",
          "value": "not applicable",
          "note": "`ready_at` is 0. The close carries half the weight, the extremes a quarter each."
        },
        "errors": [
          {
            "when": "a bar's `high`, `low` or `close` is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "a `high` is below the bar's `open`, `low` or `close`",
            "behaviour": "throws Error"
          },
          {
            "when": "bars do not share one adjustment `basis`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "weightedClose({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F08-A03",
          "title": "Weighted Close",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "value": [
              100.03625,
              101.75361035750001,
              102.8728829175,
              103.14077006,
              102.77185682000001,
              102.27277061000001
            ]
          },
          "latest": {
            "value": 100.1199943175
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a03/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a03/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a03/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Weighted Close calculation flow",
            "source": "flowchart LR\n    A[\"finite, basis-consistent OHLC observations and any require\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Weighted Close convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Weighted Close readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/price-transforms/weighted-close/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/price-transforms/weighted-close/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F08-A04",
      "name": "Average Price Transform",
      "headline": null,
      "slug": "average-price-transform",
      "path": "technical-indicators/price-transforms/average-price-transform",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F08",
        "family": "Price Transforms",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/price-transforms/average-price-transform",
        "entry": "averagePriceTransform",
        "params": [
          "input"
        ],
        "exports": [
          "averagePriceTransform"
        ],
        "archetype": "series-transform",
        "signature": "averagePriceTransform(input)"
      },
      "api": {
        "summary": "Averages all four OHLC prices into one value per bar.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `open`, `high`, `low` and `close`. This topic reads no keys from `parameters`, though `parameters` must still be an object when supplied.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single `value`, `(open + high + low + close) / 4` for every bar, and `latest` its last element. Every bar produces a value, so there is no warm-up."
        },
        "warmup": {
          "count": "none",
          "value": "not applicable",
          "note": "`ready_at` is 0. This is the same quantity Heikin-Ashi uses as its smoothed close."
        },
        "errors": [
          {
            "when": "a bar's `open`, `high`, `low` or `close` is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "a `low` is above the bar's `open`, `high` or `close`",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "averagePriceTransform({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F08-A04",
          "title": "Average Price Transform",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "value": [
              100.03625,
              101.6794109525,
              102.7479458125,
              103.0046001225,
              102.6675107225,
              102.233242385
            ]
          },
          "latest": {
            "value": 100.21300550000001
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a04/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a04/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a04/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Average Price Transform calculation flow",
            "source": "flowchart LR\n    A[\"finite, basis-consistent OHLC observations and any require\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Average Price Transform convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Average Price Transform readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/price-transforms/average-price-transform/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/price-transforms/average-price-transform/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F08-A05",
      "name": "Heikin-Ashi Transform",
      "headline": null,
      "slug": "heikin-ashi-transform",
      "path": "technical-indicators/price-transforms/heikin-ashi-transform",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F08",
        "family": "Price Transforms",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/price-transforms/heikin-ashi-transform",
        "entry": "heikinAshiTransform",
        "params": [
          "input"
        ],
        "exports": [
          "heikinAshiTransform"
        ],
        "archetype": "series-transform",
        "signature": "heikinAshiTransform(input)"
      },
      "api": {
        "summary": "Rebuilds each bar as a Heikin-Ashi candle, averaging OHLC into the smoothed close and carrying the smoothed open forward from the previous candle.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `open`, `high`, `low` and `close`. This topic reads no keys from `parameters`, though `parameters` must still be an object when supplied.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `open`, `high`, `low` and `close`, the four smoothed candle legs, and `latest` carries the last element of each. The smoothed close is `(open + high + low + close) / 4`; the smoothed open is the midpoint of the raw open and close on the first bar and thereafter the midpoint of the previous smoothed open and close; the smoothed high and low extend the raw ones to include both. Every bar produces values, so there is no positional warm-up."
        },
        "warmup": {
          "count": "none",
          "value": "the first smoothed open is seeded from the first bar's own open and close",
          "note": "`ready_at` is 0, but the smoothed open is recursive, so the whole series depends on which bar the input starts at. Two runs over different slices of the same history do not agree exactly until the seed has decayed."
        },
        "errors": [
          {
            "when": "a bar's `open`, `high`, `low` or `close` is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "a `high` is below the bar's `open`, `low` or `close`",
            "behaviour": "throws Error"
          },
          {
            "when": "timestamps are not strictly increasing",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "heikinAshiTransform({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F08-A05",
          "title": "Heikin-Ashi Transform",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "open": [
              100,
              100.018125,
              100.84876797625,
              101.798356894375,
              102.40147850843749,
              102.53449461546874
            ],
            "high": [
              101.45,
              103.38381693,
              104.6701838,
              105.01857496,
              104.62741155,
              104.01164055
            ],
            "low": [
              98.695,
              100.018125,
              100.84876797625,
              101.0799399,
              100.79741547,
              100.54198995
            ],
            "close": [
              100.03625,
              101.6794109525,
              102.7479458125,
              103.0046001225,
              102.6675107225,
              102.233242385
            ]
          },
          "latest": {
            "open": 102.4337036124137,
            "high": 102.4337036124137,
            "low": 98.68874251,
            "close": 100.21300550000001
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a05/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a05/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a05/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Heikin-Ashi Transform calculation flow",
            "source": "flowchart LR\n    A[\"finite, basis-consistent OHLC observations and any require\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Heikin-Ashi Transform convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Heikin-Ashi Transform readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/price-transforms/heikin-ashi-transform/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/price-transforms/heikin-ashi-transform/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F08-A06",
      "name": "Log Price Transform",
      "headline": null,
      "slug": "log-price-transform",
      "path": "technical-indicators/price-transforms/log-price-transform",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F08",
        "family": "Price Transforms",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/price-transforms/log-price-transform",
        "entry": "logPriceTransform",
        "params": [
          "input"
        ],
        "exports": [
          "logPriceTransform"
        ],
        "archetype": "series-transform",
        "signature": "logPriceTransform(input)"
      },
      "api": {
        "summary": "Takes the natural logarithm of each close and the first difference of those logs.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp` and `close`, and every close must be strictly positive. This topic reads no keys from `parameters`, though `parameters` must still be an object when supplied.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `log_price`, the natural log of close on every bar, and `log_return`, the difference between consecutive logs. `latest` carries the last element of each. `log_return` is null on the first bar only, which is the whole warm-up."
        },
        "warmup": {
          "count": "1 bar for `log_return`; none for `log_price`",
          "value": "null",
          "note": "`ready_at` is 0 because `log_price` is available immediately."
        },
        "errors": [
          {
            "when": "any `close` is zero or negative",
            "behaviour": "throws Error"
          },
          {
            "when": "a `close` is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "logPriceTransform({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F08-A06",
          "title": "Log Price Transform",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "log_price": [
              4.605170185988092,
              4.622891355808754,
              4.634291406096771,
              4.6369816208940655,
              4.633089782650425,
              4.627603917225904
            ],
            "log_return": [
              null,
              0.017721169820662297,
              0.011400050288016494,
              0.002690214797294921,
              -0.0038918382436401444,
              -0.005485865424521563
            ]
          },
          "latest": {
            "log_price": 4.605078326469135,
            "log_return": -0.0146799922919163
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a06/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a06/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a06/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a06/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Log Price Transform calculation flow",
            "source": "flowchart LR\n    A[\"finite, basis-consistent OHLC observations and any require\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Log Price Transform convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Log Price Transform readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/price-transforms/log-price-transform/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/price-transforms/log-price-transform/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F08-A07",
      "name": "Price Relative",
      "headline": null,
      "slug": "price-relative",
      "path": "technical-indicators/price-transforms/price-relative",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F08",
        "family": "Price Transforms",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/price-transforms/price-relative",
        "entry": "priceRelative",
        "params": [
          "input"
        ],
        "exports": [
          "priceRelative"
        ],
        "archetype": "series-transform",
        "signature": "priceRelative(input)"
      },
      "api": {
        "summary": "Rebases the ratio of close to a benchmark level so the first bar equals `base`, producing a relative-strength line.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp`, `close` and a positive `benchmark` on every bar. From `parameters` this topic reads `base` (default 100, a finite number of at least 0).",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds a single `value`, `base` times the close-to-benchmark ratio divided by that ratio on the first bar, and `latest` its last element. Every bar produces a value, so there is no warm-up."
        },
        "warmup": {
          "count": "none",
          "value": "`base` on the first bar, 100 by default",
          "note": "`ready_at` is 0. The rebasing anchor is the first bar of the input, so the line is only comparable across runs that start at the same bar."
        },
        "errors": [
          {
            "when": "any bar is missing `benchmark`, or carries one that is zero or negative",
            "behaviour": "throws Error"
          },
          {
            "when": "the first bar's close divided by its benchmark is 0",
            "behaviour": "throws Error"
          },
          {
            "when": "`base` is negative or not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "priceRelative({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F08-A07",
          "title": "Price Relative",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "value": [
              100,
              101.50205122798776,
              102.38658628558109,
              102.40022103095427,
              101.76610843670669,
              101.0050531589489
            ]
          },
          "latest": {
            "value": 95.80918058424696
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a07/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a07/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a07/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a07/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Price Relative calculation flow",
            "source": "flowchart LR\n    A[\"finite, basis-consistent OHLC observations and any require\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Price Relative convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Price Relative readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/price-transforms/price-relative/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/price-transforms/price-relative/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F08-A08",
      "name": "Normalized Price Transform",
      "headline": null,
      "slug": "normalized-price-transform",
      "path": "technical-indicators/price-transforms/normalized-price-transform",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F08",
        "family": "Price Transforms",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/price-transforms/normalized-price-transform",
        "entry": "normalizedPriceTransform",
        "params": [
          "input"
        ],
        "exports": [
          "normalizedPriceTransform"
        ],
        "archetype": "series-transform",
        "signature": "normalizedPriceTransform(input)"
      },
      "api": {
        "summary": "Converts close into a rolling z-score against its own moving average and standard deviation.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` needs `timestamp` and `close`. From `parameters` this topic reads `period` (default 20, an integer of at least 2).",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` holds `value`, the z-score, alongside the `mean` and `std` it was built from; `latest` carries the last element of each. `std` is the population standard deviation over the window, and a window whose `std` is 0 yields a null `value` while still reporting `mean` and `std`. The warm-up is the window."
        },
        "warmup": {
          "count": "`period` - 1 bars (19 with the default 20)",
          "value": "null",
          "note": "`ready_at` is 19 on default parameters, set by `mean` and `std` becoming available on the same index as `value`."
        },
        "errors": [
          {
            "when": "`period` is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a `close` is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "fewer than one bar is supplied",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "normalizedPriceTransform({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F08-A08",
          "title": "Normalized Price Transform",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "mean": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "std": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -1.9447777278294258,
            "mean": 104.20055051999998,
            "std": 2.164636086561151
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a08/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a08/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a08/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f08-a08/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Normalized Price Transform calculation flow",
            "source": "flowchart LR\n    A[\"finite, basis-consistent OHLC observations and any require\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Normalized Price Transform convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Normalized Price Transform readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/price-transforms/normalized-price-transform/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/price-transforms/normalized-price-transform/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F09-A01",
      "name": "Rolling Percentile",
      "headline": null,
      "slug": "rolling-percentile",
      "path": "technical-indicators/rolling-statistical-indicators/rolling-percentile",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F09",
        "family": "Rolling Statistical Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/rolling-statistical-indicators/rolling-percentile",
        "entry": "rollingPercentile",
        "params": [
          "input"
        ],
        "exports": [
          "rollingPercentile"
        ],
        "archetype": "series-transform",
        "signature": "rollingPercentile(input)"
      },
      "api": {
        "summary": "Reports where the current close sits inside its own trailing window, as the percentage of window values below it plus a configurable share of the values equal to it.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the OHLCV series, validated for finite prices, strictly increasing `timestamp`, a single adjustment `basis`, non-negative `volume`, and a high and low that bracket the other prices; only `close` is used. From `parameters` this topic reads `period` (integer, minimum 2, default 20), the window length, and `tie_weight` (number between 0 and 1, default 0.5), the credit given to window values that equal the current close.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key, a percentage between 0 and 100. After the warm-up every bar has a value, since the current close is always in its own window and the denominator can never be zero."
        },
        "warmup": {
          "count": "period - 1 bars (19 by default)",
          "value": "null",
          "note": "The first full window closes at index `period - 1`, so with the default period indices 0 to 18 are null and `ready_at` is 19."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.tie_weight` is not a finite number between 0 and 1",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, a timestamp not greater than the previous one, or a high below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "rollingPercentile({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F09-A01",
          "title": "Rolling Percentile",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 2.5
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f09-a01/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f09-a01/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f09-a01/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f09-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Rolling Percentile calculation flow",
            "source": "flowchart LR\n    A[\"time-aligned observations, window length, minimum count, e\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Rolling Percentile convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Rolling Percentile readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/rolling-statistical-indicators/rolling-percentile/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/rolling-statistical-indicators/rolling-percentile/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F09-A02",
      "name": "Rolling Quantile",
      "headline": null,
      "slug": "rolling-quantile",
      "path": "technical-indicators/rolling-statistical-indicators/rolling-quantile",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F09",
        "family": "Rolling Statistical Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/rolling-statistical-indicators/rolling-quantile",
        "entry": "rollingQuantile",
        "params": [
          "input"
        ],
        "exports": [
          "rollingQuantile"
        ],
        "archetype": "series-transform",
        "signature": "rollingQuantile(input)"
      },
      "api": {
        "summary": "Returns the requested quantile of the close over a trailing window, sorting each window and interpolating linearly between the two neighbouring ranks.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the OHLCV series, validated for finite prices, strictly increasing `timestamp`, a single adjustment `basis`, non-negative `volume`, and a high and low that bracket the other prices; only `close` is used. From `parameters` this topic reads `period` (integer, minimum 2, default 20), the window length, and `q` (number between 0 and 1, default 0.5, so the default output is the median).",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key, in price units. After the warm-up every bar has a value."
        },
        "warmup": {
          "count": "period - 1 bars (19 by default)",
          "value": "null",
          "note": "The first full window closes at index `period - 1`, so with the default period indices 0 to 18 are null and `ready_at` is 19."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.q` is not a finite number between 0 and 1",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, a timestamp not greater than the previous one, or a high below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period * log period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "rollingQuantile({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F09-A02",
          "title": "Rolling Quantile",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 103.797121585
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f09-a02/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f09-a02/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f09-a02/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f09-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Rolling Quantile calculation flow",
            "source": "flowchart LR\n    A[\"time-aligned observations, window length, minimum count, e\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Rolling Quantile convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Rolling Quantile readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/rolling-statistical-indicators/rolling-quantile/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/rolling-statistical-indicators/rolling-quantile/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F09-A03",
      "name": "Rolling Beta",
      "headline": null,
      "slug": "rolling-beta",
      "path": "technical-indicators/rolling-statistical-indicators/rolling-beta",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F09",
        "family": "Rolling Statistical Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/rolling-statistical-indicators/rolling-beta",
        "entry": "rollingBeta",
        "params": [
          "input"
        ],
        "exports": [
          "rollingBeta"
        ],
        "archetype": "series-transform",
        "signature": "rollingBeta(input)"
      },
      "api": {
        "summary": "Regresses the asset's simple returns on the benchmark's over a trailing window and returns the slope, using the population covariance and variance of the window.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the OHLCV series, validated for finite prices, strictly increasing `timestamp`, a single adjustment `basis`, non-negative `volume`, and a high and low that bracket the other prices. Every bar must additionally carry a `benchmark` field, a finite positive number, from which the benchmark return series is built. From `parameters` this topic reads only `period` (integer, minimum 2, default 20), the regression window in returns.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `beta` key; the intercept is not emitted by this topic. A bar is null when the benchmark returns in its window have zero variance. Returns cost one bar, which lengthens the warm-up by one over a plain window."
        },
        "warmup": {
          "count": "period bars (20 by default)",
          "value": "null",
          "note": "Both return series start at index 1, so the first window with `period` paired returns closes at index `period`: with the default period indices 0 to 19 are null and `ready_at` is 20."
        },
        "errors": [
          {
            "when": "any bar omits `benchmark`, so the benchmark return series cannot be built",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `benchmark` is present but is not a finite number, or is not greater than zero",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.period` is present but is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, a timestamp not greater than the previous one, or a high below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "rollingBeta({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F09-A03",
          "title": "Rolling Beta",
          "state": "calculated",
          "ready": true,
          "ready_at": 20,
          "series": {
            "beta": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "beta": -5.216643800648915
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f09-a03/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f09-a03/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f09-a03/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f09-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Rolling Beta calculation flow",
            "source": "flowchart LR\n    A[\"time-aligned observations, window length, minimum count, e\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Rolling Beta convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Rolling Beta readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/rolling-statistical-indicators/rolling-beta/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/rolling-statistical-indicators/rolling-beta/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F09-A04",
      "name": "Rolling Alpha",
      "headline": null,
      "slug": "rolling-alpha",
      "path": "technical-indicators/rolling-statistical-indicators/rolling-alpha",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F09",
        "family": "Rolling Statistical Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/rolling-statistical-indicators/rolling-alpha",
        "entry": "rollingAlpha",
        "params": [
          "input"
        ],
        "exports": [
          "rollingAlpha"
        ],
        "archetype": "series-transform",
        "signature": "rollingAlpha(input)"
      },
      "api": {
        "summary": "Runs the same trailing regression of asset returns on benchmark returns as rolling beta, and returns the intercept, the mean asset return left over after the beta-weighted mean benchmark return is removed.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the OHLCV series, validated for finite prices, strictly increasing `timestamp`, a single adjustment `basis`, non-negative `volume`, and a high and low that bracket the other prices. Every bar must additionally carry a `benchmark` field, a finite positive number, from which the benchmark return series is built. From `parameters` this topic reads only `period` (integer, minimum 2, default 20), the regression window in returns.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `alpha` and, because the intercept is meaningless without it, `beta` as well. Both are null on a bar whose benchmark returns have zero variance. Returns cost one bar, which lengthens the warm-up by one over a plain window."
        },
        "warmup": {
          "count": "period bars (20 by default)",
          "value": "null",
          "note": "Both return series start at index 1, so the first window with `period` paired returns closes at index `period`: with the default period indices 0 to 19 are null and `ready_at` is 20."
        },
        "errors": [
          {
            "when": "any bar omits `benchmark`, so the benchmark return series cannot be built",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `benchmark` is present but is not a finite number, or is not greater than zero",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters.period` is present but is not an integer of at least 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, or a bar has a non-finite price, a negative volume, a timestamp not greater than the previous one, or a high below its open, low, or close",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "rollingAlpha({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D07-F09-A04",
          "title": "Rolling Alpha",
          "state": "calculated",
          "ready": true,
          "ready_at": 20,
          "series": {
            "alpha": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "beta": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "alpha": -0.002944675603614832,
            "beta": -5.216643800648915
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f09-a04/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f09-a04/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f09-a04/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f09-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Rolling Alpha calculation flow",
            "source": "flowchart LR\n    A[\"time-aligned observations, window length, minimum count, e\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Rolling Alpha convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Rolling Alpha readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib function groups",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib C/C++ API",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/rolling-statistical-indicators/rolling-alpha/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/rolling-statistical-indicators/rolling-alpha/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": [
          {
            "file": "calculation-flow.md",
            "caption": "Causal Pivot Detection calculation flow",
            "source": "flowchart LR\n    A[\"Finalized OHLC bar t\"] --> B[\"Candidate i = t - right span\"]\n    B --> C{\"Complete left and right windows?\"}\n    C -- \"no\" --> D[\"Unavailable\"]\n    C -- \"yes\" --> E{\"Strict-left and inclusive-right extremum?\"}\n    E -- \"no\" --> F[\"Reject with reason\"]\n    E -- \"yes\" --> G{\"Separation floor met?\"}\n    G -- \"no\" --> F\n    G -- \"yes\" --> H[\"Publish event i and confirmation t\"]"
          }
        ]
      },
      "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": false,
            "description": "Minimum retracement, as a fraction strictly between 0 and 1, before a reversal is accepted. The comparison is inclusive: an exact touch of the threshold confirms.",
            "constraints": {
              "exclusive_min": 0,
              "exclusive_max": 1
            },
            "nulls": null,
            "default": 0.05
          },
          {
            "name": "minBars",
            "type": "number",
            "required": false,
            "description": "Minimum bars between a pivot's event index and its confirmation index.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": 3
          }
        ],
        "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": "closes is empty, or any close is nonfinite or not strictly positive",
            "behaviour": "throws"
          },
          {
            "when": "threshold is not strictly between 0 and 1",
            "behaviour": "throws"
          },
          {
            "when": "minBars is not an integer >= 1",
            "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": [
          {
            "file": "calculation-flow.md",
            "caption": "ZigZag Segmentation calculation flow",
            "source": "stateDiagram-v2\n    [*] --> Searching\n    Searching --> Up: low reverses upward by tau and min bars\n    Searching --> Down: high reverses downward by tau and min bars\n    Up --> Up: strictly higher close moves provisional high\n    Up --> Down: decline reaches tau and confirms high\n    Down --> Down: strictly lower close moves provisional low\n    Down --> Up: advance reaches tau and confirms low"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Support/Resistance Clustering calculation flow",
            "source": "flowchart LR\n    A[\"Confirmed pivots at knowledge cutoff\"] --> B[\"Reject malformed clocks and prices\"]\n    B --> C[\"Split lows from highs\"]\n    C --> D[\"Transform price to log price\"]\n    D --> E[\"Build inclusive epsilon neighborhoods\"]\n    E --> F{\"At least min touches including self?\"}\n    F -- \"yes\" --> G[\"Core; expand density reachability\"]\n    F -- \"no\" --> H[\"Border if reachable, otherwise noise\"]\n    G --> I[\"Median level, member bounds, touch and clock diagnostics\"]\n    H --> I"
          }
        ]
      },
      "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",
          "projectionIndex"
        ],
        "exports": [
          "detectCausalPivots",
          "fitRobustTrendline"
        ],
        "archetype": "record-transform",
        "signature": "fitRobustTrendline(pivots, kind, toleranceBps, minInliers, maxPoints, projectionIndex)"
      },
      "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
          },
          {
            "name": "projectionIndex",
            "type": "number",
            "required": false,
            "description": "Bar index to project the fitted line to. Defaults to one past the highest pivot index, so the line is extended a single bar beyond its support.",
            "constraints": null,
            "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, undefined)",
        "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
          },
          {
            "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Robust Trendline Fitting calculation flow",
            "source": "flowchart LR\n    A[\"Confirmed same-kind pivots\"] --> B[\"Validate clocks, unique event indexes, and positive prices\"]\n    B --> C[\"Keep most recent max points; transform to log price\"]\n    C --> D[\"Enumerate every two-point hypothesis\"]\n    D --> E[\"Build inclusive residual consensus\"]\n    E --> F[\"Score: count, median residual, slope magnitude, pair order\"]\n    F --> G{\"Enough inliers?\"}\n    G -- \"no\" --> H[\"No fit\"]\n    G -- \"yes\" --> I[\"Lock winning membership\"]\n    I --> J[\"One OLS refit and exact residual-bps diagnostics\"]"
          }
        ]
      },
      "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-F01-A05",
      "name": "Classic and Floor-Trader Pivot Points",
      "headline": null,
      "slug": "classic-and-floor-trader-pivot-points",
      "path": "geometric-chart-patterns/pivots-and-levels/classic-and-floor-trader-pivot-points",
      "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/classic-and-floor-trader-pivot-points",
        "entry": "classicAndFloorTraderPivotPoints",
        "params": [
          "input"
        ],
        "exports": [
          "classicAndFloorTraderPivotPoints"
        ],
        "archetype": "record-transform",
        "signature": "classicAndFloorTraderPivotPoints(input)"
      },
      "api": {
        "summary": "Projects the classic floor-trader pivot and two resistance/support pairs for each bar from the previous bar's high, low, and close. The pivot is `(H + L + C) / 3`, `r1`/`s1` reflect it across the prior low and high, and `r2`/`s2` add and subtract the prior bar's range.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. This variant reads no keys from `parameters`, but the family still validates `period` (default `20`) as an integer of at least 2 whenever it is supplied.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `pivot`, `r1`, `s1`, `r2` and `s2`. The warm-up is one bar: index 0 has no prior bar to derive levels from, so `ready_at` is 1 for any input of two or more bars."
        },
        "warmup": {
          "count": "1 bar",
          "value": "null",
          "note": "Every level at index i is computed from bar i-1 only, so index 0 is null across all five series and `ready_at` settles at 1."
        },
        "errors": [
          {
            "when": "a bar's `high` is below its own `open`, `close`, or `low` (or `low` is above them)",
            "behaviour": "throws Error"
          },
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "classicAndFloorTraderPivotPoints({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F01-A05",
          "title": "Classic and Floor-Trader Pivot Points",
          "state": "calculated",
          "ready": true,
          "ready_at": 1,
          "series": {
            "pivot": [
              null,
              100.04833333333333,
              101.74217643000001,
              102.84553092333333,
              103.11026585,
              102.75204238333333
            ],
            "r1": [
              null,
              101.40166666666667,
              103.42955264000003,
              104.77959177666666,
              105.14059180000001,
              104.70666929666666
            ],
            "s1": [
              null,
              98.64666666666666,
              100.10053593000004,
              101.02087804666665,
              101.20195674000001,
              100.87667321666666
            ],
            "r2": [
              null,
              102.80333333333334,
              105.07119314,
              106.60424465333334,
              107.04890091,
              106.58203846333333
            ],
            "s2": [
              null,
              97.29333333333332,
              98.41315972000002,
              99.08681719333332,
              99.17163079000001,
              98.92204630333333
            ]
          },
          "latest": {
            "pivot": 101.55414906333333,
            "r1": 103.07243937666665,
            "s1": 99.95121557666666,
            "r2": 104.67537286333332,
            "s2": 98.43292526333333
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a05/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a05/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a05/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Classic and Floor-Trader Pivot Points calculation flow",
            "source": "flowchart LR\n    A[\"closed OHLC bars or causally confirmed pivots with session\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Classic and Floor-Trader Pivot Points convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Classic and Floor-Trader Pivot Points readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pivots-and-levels/classic-and-floor-trader-pivot-points/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pivots-and-levels/classic-and-floor-trader-pivot-points/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F01-A06",
      "name": "Fibonacci Pivot Points",
      "headline": null,
      "slug": "fibonacci-pivot-points",
      "path": "geometric-chart-patterns/pivots-and-levels/fibonacci-pivot-points",
      "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/fibonacci-pivot-points",
        "entry": "fibonacciPivotPoints",
        "params": [
          "input"
        ],
        "exports": [
          "fibonacciPivotPoints"
        ],
        "archetype": "record-transform",
        "signature": "fibonacciPivotPoints(input)"
      },
      "api": {
        "summary": "Takes the same `(H + L + C) / 3` pivot as the classic variant but places the bands at Fibonacci fractions of the previous bar's range: `r1`/`s1` at 0.382 of it and `r2`/`s2` at 0.618.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. This variant reads no keys from `parameters`; the 0.382 and 0.618 fractions are fixed in the implementation. `period` (default `20`) is still validated as an integer of at least 2 if supplied.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `pivot`, `r1`, `s1`, `r2` and `s2`. The warm-up is one bar, because every value is derived from the preceding bar."
        },
        "warmup": {
          "count": "1 bar",
          "value": "null",
          "note": "Index 0 is null across all five series; `ready_at` is 1 for any input of two or more bars."
        },
        "errors": [
          {
            "when": "a bar's `high` is below its own `open`, `close`, or `low` (or `low` is above them)",
            "behaviour": "throws Error"
          },
          {
            "when": "`parameters` is supplied as something other than a plain object",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "fibonacciPivotPoints({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F01-A06",
          "title": "Fibonacci Pivot Points",
          "state": "calculated",
          "ready": true,
          "ready_at": 1,
          "series": {
            "pivot": [
              null,
              100.04833333333333,
              101.74217643000001,
              102.84553092333333,
              103.11026585,
              102.75204238333333
            ],
            "r1": [
              null,
              101.10074333333334,
              103.01386081322,
              104.28135956819334,
              104.61482444292,
              104.21510088589334
            ],
            "s1": [
              null,
              98.99592333333332,
              100.47049204678002,
              101.40970227847332,
              101.60570725708001,
              101.28898388077333
            ],
            "r2": [
              null,
              101.75092333333333,
              103.79950875678001,
              105.16841600847333,
              105.54434231708001,
              105.11897996077333
            ],
            "s2": [
              null,
              98.34574333333333,
              99.68484410322002,
              100.52264583819333,
              100.67618938292,
              100.38510480589333
            ]
          },
          "latest": {
            "pivot": 101.55414906333333,
            "r1": 102.74645655493333,
            "s1": 100.36184157173332,
            "r2": 103.48306537173332,
            "s2": 99.62523275493334
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a06/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a06/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a06/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a06/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Fibonacci Pivot Points calculation flow",
            "source": "flowchart LR\n    A[\"closed OHLC bars or causally confirmed pivots with session\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Fibonacci Pivot Points convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Fibonacci Pivot Points readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pivots-and-levels/fibonacci-pivot-points/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pivots-and-levels/fibonacci-pivot-points/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F01-A07",
      "name": "Camarilla Pivot Points",
      "headline": null,
      "slug": "camarilla-pivot-points",
      "path": "geometric-chart-patterns/pivots-and-levels/camarilla-pivot-points",
      "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/camarilla-pivot-points",
        "entry": "camarillaPivotPoints",
        "params": [
          "input"
        ],
        "exports": [
          "camarillaPivotPoints"
        ],
        "archetype": "record-transform",
        "signature": "camarillaPivotPoints(input)"
      },
      "api": {
        "summary": "Anchors its bands on the previous bar's close rather than on the pivot: `r1`/`s1` sit at `close ± 1.1 × range / 12` and `r2`/`s2` at `close ± 1.1 × range / 6`. The `pivot` series is still the conventional `(H + L + C) / 3`, which is why the bands are not symmetric around it.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. This variant reads no keys from `parameters`; the 1.1 coefficient and the /12 and /6 divisors are fixed. `period` (default `20`) is still validated as an integer of at least 2 if supplied.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `pivot`, `r1`, `s1`, `r2` and `s2`. The warm-up is one bar, because every value is derived from the preceding bar."
        },
        "warmup": {
          "count": "1 bar",
          "value": "null",
          "note": "Index 0 is null across all five series; `ready_at` is 1 for any input of two or more bars."
        },
        "errors": [
          {
            "when": "bars are not strictly increasing by `timestamp`",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `high` is below its own `open`, `close`, or `low` (or `low` is above them)",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "camarillaPivotPoints({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F01-A07",
          "title": "Camarilla Pivot Points",
          "state": "calculated",
          "ready": true,
          "ready_at": 1,
          "series": {
            "pivot": [
              null,
              100.04833333333333,
              101.74217643000001,
              102.84553092333333,
              103.11026585,
              102.75204238333333
            ],
            "r1": [
              null,
              100.25254166666667,
              102.09307200508333,
              103.29948765858333,
              103.59332423716667,
              103.182383104
            ],
            "s1": [
              null,
              99.74745833333333,
              101.48275227491668,
              102.61039014141667,
              102.87124114283334,
              102.48021715600001
            ],
            "r2": [
              null,
              100.50508333333333,
              102.39823187016667,
              103.64403641716667,
              103.95436578433333,
              103.533466078
            ],
            "s2": [
              null,
              99.49491666666667,
              101.17759240983334,
              102.26584138283333,
              102.51019959566668,
              102.129134182
            ]
          },
          "latest": {
            "pivot": 101.55414906333333,
            "r1": 101.75561807166666,
            "s1": 101.18339370833333,
            "r2": 102.04173025333333,
            "s2": 100.89728152666666
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a07/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a07/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a07/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a07/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Camarilla Pivot Points calculation flow",
            "source": "flowchart LR\n    A[\"closed OHLC bars or causally confirmed pivots with session\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Camarilla Pivot Points convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Camarilla Pivot Points readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pivots-and-levels/camarilla-pivot-points/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pivots-and-levels/camarilla-pivot-points/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F01-A08",
      "name": "Woodie Pivot Points",
      "headline": null,
      "slug": "woodie-pivot-points",
      "path": "geometric-chart-patterns/pivots-and-levels/woodie-pivot-points",
      "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/woodie-pivot-points",
        "entry": "woodiePivotPoints",
        "params": [
          "input"
        ],
        "exports": [
          "woodiePivotPoints"
        ],
        "archetype": "record-transform",
        "signature": "woodiePivotPoints(input)"
      },
      "api": {
        "summary": "Weights the current bar's open into the pivot, `(H_prev + L_prev + 2 × open) / 4`, then derives `r1`/`s1` by reflecting that pivot across the previous low and high and `r2`/`s2` by adding and subtracting the previous bar's range.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. This variant reads no keys from `parameters`, though `period` (default `20`) is still validated as an integer of at least 2 if supplied. Note that the current bar's `open` is an input, so a Woodie level is only knowable once that bar has opened.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `pivot`, `r1`, `s1`, `r2` and `s2`. The warm-up is one bar, since the previous bar's high and low are required."
        },
        "warmup": {
          "count": "1 bar",
          "value": "null",
          "note": "Index 0 is null across all five series; `ready_at` is 1 for any input of two or more bars."
        },
        "errors": [
          {
            "when": "a bar's `open` is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "woodiePivotPoints({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F01-A08",
          "title": "Woodie Pivot Points",
          "state": "calculated",
          "ready": true,
          "ready_at": 1,
          "series": {
            "pivot": [
              null,
              100.78180726,
              102.0872495275,
              102.73921493750001,
              102.731586585,
              102.41151329
            ],
            "r1": [
              null,
              102.86861452,
              104.11969883500001,
              104.56695980500002,
              104.38323327,
              104.02561111
            ],
            "s1": [
              null,
              100.11361451999998,
              100.79068212500002,
              100.80824607500001,
              100.44459821000001,
              100.19561503
            ],
            "r2": [
              null,
              103.53680726,
              105.4162662375,
              106.49792866750002,
              106.670221645,
              106.24150937
            ],
            "s2": [
              null,
              98.02680725999998,
              98.75823281750002,
              98.9805012075,
              98.792951525,
              98.58151721
            ]
          },
          "latest": {
            "pivot": 100.97966492500001,
            "r1": 101.92347110000001,
            "s1": 98.80224730000002,
            "r2": 104.100888725,
            "s2": 97.85844112500001
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a08/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a08/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a08/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a08/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Woodie Pivot Points calculation flow",
            "source": "flowchart LR\n    A[\"closed OHLC bars or causally confirmed pivots with session\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Woodie Pivot Points convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Woodie Pivot Points readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pivots-and-levels/woodie-pivot-points/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pivots-and-levels/woodie-pivot-points/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F01-A09",
      "name": "DeMark Pivot Points",
      "headline": null,
      "slug": "demark-pivot-points",
      "path": "geometric-chart-patterns/pivots-and-levels/demark-pivot-points",
      "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/demark-pivot-points",
        "entry": "demarkPivotPoints",
        "params": [
          "input"
        ],
        "exports": [
          "demarkPivotPoints"
        ],
        "archetype": "record-transform",
        "signature": "demarkPivotPoints(input)"
      },
      "api": {
        "summary": "Chooses one of three formulas for the intermediate `X` depending on whether the previous bar closed below, above, or level with its open, then reports `pivot = X / 4` with a single band pair `r1 = X / 2 - L_prev` and `s1 = X / 2 - H_prev`.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. This variant reads no keys from `parameters`; the branch is selected purely from the previous bar's close-versus-open relationship. `period` (default `20`) is still validated as an integer of at least 2 if supplied.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `pivot`, `r1`, `s1`, `r2` and `s2`, but DeMark defines only one band pair, so `r2` and `s2` are null at every index including the last. The warm-up is one bar."
        },
        "warmup": {
          "count": "1 bar",
          "value": "null",
          "note": "Index 0 is null in every series and `ready_at` is 1; `r2` and `s2` never leave null, which is the formula and not an unfinished warm-up."
        },
        "errors": [
          {
            "when": "a bar's `high` is below its own `open`, `close`, or `low` (or `low` is above them)",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty or is not an array",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "demarkPivotPoints({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F01-A09",
          "title": "DeMark Pivot Points",
          "state": "calculated",
          "ready": true,
          "ready_at": 1,
          "series": {
            "pivot": [
              null,
              100.03625,
              102.152586555,
              103.3016941425,
              103.58734312749999,
              103.220884675
            ],
            "r1": [
              null,
              101.3775,
              104.25037289,
              105.691918215,
              106.09474635499998,
              105.64435387999998
            ],
            "s1": [
              null,
              98.62249999999999,
              100.92135618,
              101.93320448499999,
              102.15611129499999,
              101.81435779999998
            ],
            "r2": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "s2": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "pivot": 101.174576485,
            "r1": 102.31329422,
            "s1": 99.19207042000001,
            "r2": null,
            "s2": null
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a09/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a09/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a09/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a09/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "DeMark Pivot Points calculation flow",
            "source": "flowchart LR\n    A[\"closed OHLC bars or causally confirmed pivots with session\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected DeMark Pivot Points convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "DeMark Pivot Points readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pivots-and-levels/demark-pivot-points/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pivots-and-levels/demark-pivot-points/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F01-A10",
      "name": "Rolling Support and Resistance",
      "headline": null,
      "slug": "rolling-support-and-resistance",
      "path": "geometric-chart-patterns/pivots-and-levels/rolling-support-and-resistance",
      "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/rolling-support-and-resistance",
        "entry": "rollingSupportAndResistance",
        "params": [
          "input"
        ],
        "exports": [
          "rollingSupportAndResistance"
        ],
        "archetype": "record-transform",
        "signature": "rollingSupportAndResistance(input)"
      },
      "api": {
        "summary": "Reports, for each bar, the lowest low and highest high of the `period` bars that came strictly before it. Excluding the current bar is what makes the level a thing price can break rather than a level price defines.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.period` (default `20`, integer of at least 2) sets the lookback window.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `support` (rolling minimum low) and `resistance` (rolling maximum high). The warm-up is `period` bars, so with the default `ready_at` is 20."
        },
        "warmup": {
          "count": "period bars (20 by default)",
          "value": "null",
          "note": "The window looks back over indices i-period through i-1, so index period is the first bar with a full prior window and `ready_at` equals `period`."
        },
        "errors": [
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "bars are not strictly increasing by `timestamp`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n × period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "rollingSupportAndResistance({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F01-A10",
          "title": "Rolling Support and Resistance",
          "state": "calculated",
          "ready": true,
          "ready_at": 20,
          "series": {
            "support": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "resistance": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "support": 99.69159419,
            "resistance": 109.83623682
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a10/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a10/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a10/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a10/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Rolling Support and Resistance calculation flow",
            "source": "flowchart LR\n    A[\"closed OHLC bars or causally confirmed pivots with session\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Rolling Support and Resistance convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Rolling Support and Resistance readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pivots-and-levels/rolling-support-and-resistance/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pivots-and-levels/rolling-support-and-resistance/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F01-A11",
      "name": "Fractal Support and Resistance",
      "headline": null,
      "slug": "fractal-support-and-resistance",
      "path": "geometric-chart-patterns/pivots-and-levels/fractal-support-and-resistance",
      "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/fractal-support-and-resistance",
        "entry": "fractalSupportAndResistance",
        "params": [
          "input"
        ],
        "exports": [
          "fractalSupportAndResistance"
        ],
        "archetype": "record-transform",
        "signature": "fractalSupportAndResistance(input)"
      },
      "api": {
        "summary": "Holds the most recent confirmed five-bar fractal high and low forward as resistance and support. This deliberately delegates to the same causal five-bar confirmation used by Fractal Chaos Bands, so a fractal at bar p is only reported from bar p+2 onward.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. The fractal window is fixed at five bars and no `parameters` key changes it, though `period` (default `20`, integer of at least 2) and `multiplier` (default `2`, at least `0`) are still validated when supplied.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `upper` and `lower`. The warm-up is at least four bars and then runs until the first fractal actually confirms, so `ready_at` is data-dependent (5 on the canonical fixture); once set, each level is held forward until the next fractal replaces it."
        },
        "warmup": {
          "count": "4 bars minimum, then until the first fractal confirms",
          "value": "null",
          "note": "Indices 0 to 3 can never confirm a centred five-bar window. From index 4 the pivot under test is i-2, so `ready_at` is the first index at or after 4 whose centre bar is the extreme of its five-bar neighbourhood."
        },
        "errors": [
          {
            "when": "`bars` is empty or is not an array",
            "behaviour": "throws Error"
          },
          {
            "when": "`multiplier` is supplied as a negative number or is not finite",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "fractalSupportAndResistance({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F01-A11",
          "title": "Fractal Support and Resistance",
          "state": "calculated",
          "ready": true,
          "ready_at": 5,
          "series": {
            "upper": [
              null,
              null,
              null,
              null,
              null,
              105.01857496
            ],
            "lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "upper": 109.83623682,
            "lower": 101.07584902
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a11/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a11/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a11/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a11/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Fractal Support and Resistance calculation flow",
            "source": "flowchart LR\n    A[\"closed OHLC bars or causally confirmed pivots with session\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Fractal Support and Resistance convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Fractal Support and Resistance readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pivots-and-levels/fractal-support-and-resistance/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pivots-and-levels/fractal-support-and-resistance/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F01-A12",
      "name": "ATR Support and Resistance",
      "headline": null,
      "slug": "atr-support-and-resistance",
      "path": "geometric-chart-patterns/pivots-and-levels/atr-support-and-resistance",
      "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/atr-support-and-resistance",
        "entry": "atrSupportAndResistance",
        "params": [
          "input"
        ],
        "exports": [
          "atrSupportAndResistance"
        ],
        "archetype": "record-transform",
        "signature": "atrSupportAndResistance(input)"
      },
      "api": {
        "summary": "Places support and resistance a volatility-scaled distance either side of a simple moving average of close: `center ± multiplier × ATR(period)`, where the ATR is Wilder-smoothed true range.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.period` (default `20`, integer of at least 2) sets both the moving average and the ATR length; `parameters.multiplier` (default `2`, finite and at least `0`) sets the band width.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `center`, `support` and `resistance`. The warm-up is `period - 1` bars, because the moving average and the ATR seed both complete at index `period - 1`, so with the default `ready_at` is 19."
        },
        "warmup": {
          "count": "period - 1 bars (19 by default)",
          "value": "null",
          "note": "The simple moving average and the Wilder ATR seed both need `period` observations, and true range is defined from index 0, so all three series turn non-null together at index `period - 1`."
        },
        "errors": [
          {
            "when": "`multiplier` is supplied as a negative number or is not finite",
            "behaviour": "throws Error"
          },
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n × period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "atrSupportAndResistance({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F01-A12",
          "title": "ATR Support and Resistance",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "center": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "support": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "resistance": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "center": 104.20055051999998,
            "support": 97.75337766966595,
            "resistance": 110.647723370334
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a12/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a12/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a12/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a12/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "ATR Support and Resistance calculation flow",
            "source": "flowchart LR\n    A[\"closed OHLC bars or causally confirmed pivots with session\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected ATR Support and Resistance convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "ATR Support and Resistance readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pivots-and-levels/atr-support-and-resistance/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pivots-and-levels/atr-support-and-resistance/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F01-A13",
      "name": "Pivot Range Width",
      "headline": null,
      "slug": "pivot-range-width",
      "path": "geometric-chart-patterns/pivots-and-levels/pivot-range-width",
      "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/pivot-range-width",
        "entry": "pivotRangeWidth",
        "params": [
          "input"
        ],
        "exports": [
          "pivotRangeWidth"
        ],
        "archetype": "record-transform",
        "signature": "pivotRangeWidth(input)"
      },
      "api": {
        "summary": "Measures the central pivot range rather than its bands: `bottom` is the previous bar's midpoint `(H + L) / 2`, `top` is that midpoint reflected through the pivot, and `width` is the absolute distance between them.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. This topic reads no keys from `parameters`, though `period` (default `20`) is still validated as an integer of at least 2 if supplied.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `pivot`, `bottom`, `top` and `width` - note this variant emits no `r1`/`s1` keys. The warm-up is one bar, because all four values come from the preceding bar."
        },
        "warmup": {
          "count": "1 bar",
          "value": "null",
          "note": "Index 0 is null across all four series; `ready_at` is 1 for any input of two or more bars."
        },
        "errors": [
          {
            "when": "a bar's `high` is below its own `open`, `close`, or `low` (or `low` is above them)",
            "behaviour": "throws Error"
          },
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "pivotRangeWidth({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F01-A13",
          "title": "Pivot Range Width",
          "state": "calculated",
          "ready": true,
          "ready_at": 1,
          "series": {
            "pivot": [
              null,
              100.04833333333333,
              101.74217643000001,
              102.84553092333333,
              103.11026585,
              102.75204238333333
            ],
            "bottom": [
              null,
              100.07249999999999,
              101.719308575,
              102.790826935,
              103.04925743,
              102.71241351
            ],
            "top": [
              null,
              100.02416666666667,
              101.76504428500003,
              102.90023491166666,
              103.17127427000001,
              102.79167125666666
            ],
            "width": [
              null,
              0.048333333333317796,
              0.04573571000003085,
              0.10940797666665958,
              0.12201684000001478,
              0.07925774666665575
            ]
          },
          "latest": {
            "pivot": 101.55414906333333,
            "bottom": 101.59647065,
            "top": 101.51182747666665,
            "width": 0.08464317333334748
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a13/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a13/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a13/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a13/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Pivot Range Width calculation flow",
            "source": "flowchart LR\n    A[\"closed OHLC bars or causally confirmed pivots with session\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Pivot Range Width convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Pivot Range Width readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pivots-and-levels/pivot-range-width/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pivots-and-levels/pivot-range-width/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": [
          {
            "file": "double-top-states.md",
            "caption": "Double Top causal state flow",
            "source": "\nflowchart LR\n  A[\"Finalized close arrives\"] --> B[\"Update strict pivots after right-window delay\"]\n  B --> C{\"Required sequence available?\"}\n  C -- \"No\" --> S[\"SEARCHING\"]\n  C -- \"Yes\" --> D{\"Spacing, width, and prior trend pass?\"}\n  D -- \"No\" --> R[\"REJECTED with reason\"]\n  D -- \"Yes\" --> E{\"Similarity, retracement, and dominance pass?\"}\n  E -- \"No\" --> R\n  E -- \"Yes\" --> K[\"CANDIDATE: project neckline\"]\n  K --> N{\"close below neckline within window?\"}\n  N -- \"Yes\" --> F[\"CONFIRMED bearish event\"]\n  N -- \"Not yet\" --> K\n  N -- \"Window expired\" --> R"
          }
        ]
      },
      "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": [
          {
            "file": "double-bottom-states.md",
            "caption": "Double Bottom causal state flow",
            "source": "\nflowchart LR\n  A[\"Finalized close arrives\"] --> B[\"Update strict pivots after right-window delay\"]\n  B --> C{\"Required sequence available?\"}\n  C -- \"No\" --> S[\"SEARCHING\"]\n  C -- \"Yes\" --> D{\"Spacing, width, and prior trend pass?\"}\n  D -- \"No\" --> R[\"REJECTED with reason\"]\n  D -- \"Yes\" --> E{\"Similarity, retracement, and dominance pass?\"}\n  E -- \"No\" --> R\n  E -- \"Yes\" --> K[\"CANDIDATE: project neckline\"]\n  K --> N{\"close above neckline within window?\"}\n  N -- \"Yes\" --> F[\"CONFIRMED bullish event\"]\n  N -- \"Not yet\" --> K\n  N -- \"Window expired\" --> R"
          }
        ]
      },
      "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": [
          {
            "file": "triple-top-states.md",
            "caption": "Triple Top causal state flow",
            "source": "\nflowchart LR\n  A[\"Finalized close arrives\"] --> B[\"Update strict pivots after right-window delay\"]\n  B --> C{\"Required sequence available?\"}\n  C -- \"No\" --> S[\"SEARCHING\"]\n  C -- \"Yes\" --> D{\"Spacing, width, and prior trend pass?\"}\n  D -- \"No\" --> R[\"REJECTED with reason\"]\n  D -- \"Yes\" --> E{\"Similarity, retracement, and dominance pass?\"}\n  E -- \"No\" --> R\n  E -- \"Yes\" --> K[\"CANDIDATE: project neckline\"]\n  K --> N{\"close below neckline within window?\"}\n  N -- \"Yes\" --> F[\"CONFIRMED bearish event\"]\n  N -- \"Not yet\" --> K\n  N -- \"Window expired\" --> R"
          }
        ]
      },
      "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": [
          {
            "file": "triple-bottom-states.md",
            "caption": "Triple Bottom causal state flow",
            "source": "\nflowchart LR\n  A[\"Finalized close arrives\"] --> B[\"Update strict pivots after right-window delay\"]\n  B --> C{\"Required sequence available?\"}\n  C -- \"No\" --> S[\"SEARCHING\"]\n  C -- \"Yes\" --> D{\"Spacing, width, and prior trend pass?\"}\n  D -- \"No\" --> R[\"REJECTED with reason\"]\n  D -- \"Yes\" --> E{\"Similarity, retracement, and dominance pass?\"}\n  E -- \"No\" --> R\n  E -- \"Yes\" --> K[\"CANDIDATE: project neckline\"]\n  K --> N{\"close above neckline within window?\"}\n  N -- \"Yes\" --> F[\"CONFIRMED bullish event\"]\n  N -- \"Not yet\" --> K\n  N -- \"Window expired\" --> R"
          }
        ]
      },
      "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": [
          {
            "file": "head-and-shoulders-states.md",
            "caption": "Head and Shoulders causal state flow",
            "source": "\nflowchart LR\n  A[\"Finalized close arrives\"] --> B[\"Update strict pivots after right-window delay\"]\n  B --> C{\"Required sequence available?\"}\n  C -- \"No\" --> S[\"SEARCHING\"]\n  C -- \"Yes\" --> D{\"Spacing, width, and prior trend pass?\"}\n  D -- \"No\" --> R[\"REJECTED with reason\"]\n  D -- \"Yes\" --> E{\"Similarity, retracement, and dominance pass?\"}\n  E -- \"No\" --> R\n  E -- \"Yes\" --> K[\"CANDIDATE: project neckline\"]\n  K --> N{\"close below neckline within window?\"}\n  N -- \"Yes\" --> F[\"CONFIRMED bearish event\"]\n  N -- \"Not yet\" --> K\n  N -- \"Window expired\" --> R"
          }
        ]
      },
      "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": [
          {
            "file": "inverse-head-and-shoulders-states.md",
            "caption": "Inverse Head and Shoulders causal state flow",
            "source": "\nflowchart LR\n  A[\"Finalized close arrives\"] --> B[\"Update strict pivots after right-window delay\"]\n  B --> C{\"Required sequence available?\"}\n  C -- \"No\" --> S[\"SEARCHING\"]\n  C -- \"Yes\" --> D{\"Spacing, width, and prior trend pass?\"}\n  D -- \"No\" --> R[\"REJECTED with reason\"]\n  D -- \"Yes\" --> E{\"Similarity, retracement, and dominance pass?\"}\n  E -- \"No\" --> R\n  E -- \"Yes\" --> K[\"CANDIDATE: project neckline\"]\n  K --> N{\"close above neckline within window?\"}\n  N -- \"Yes\" --> F[\"CONFIRMED bullish event\"]\n  N -- \"Not yet\" --> K\n  N -- \"Window expired\" --> R"
          }
        ]
      },
      "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-F03-A01",
      "name": "Ascending Triangle",
      "headline": null,
      "slug": "ascending-triangle",
      "path": "geometric-chart-patterns/continuation-structures/ascending-triangle",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F03",
        "family": "Continuation Structures",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/continuation-structures/ascending-triangle",
        "entry": "detectAscendingTriangle",
        "params": [
          "close",
          "parameters"
        ],
        "exports": [
          "detectAscendingTriangle",
          "traceAscendingTriangle"
        ],
        "archetype": "row-classify",
        "signature": "detectAscendingTriangle(close, parameters)"
      },
      "api": {
        "summary": "Scans a close series for an ascending triangle - a flat ceiling sitting over a rising floor - and reports whether that shape is still forming, has broken out, or was rejected. The two boundaries are least-squares lines fitted through the confirmed swing highs and swing lows of a pivot window; the shape passes when the ceiling's relative slope is within `flat_tolerance` of zero, the floor's is at least `min_slope`, and the channel narrows by at least `min_convergence`. A close beyond either boundary by `break_buffer` within `max_confirmation_bars` of the last pivot ends the search, and only a bullish break confirms.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "The closing price series in chronological order, oldest bar first. Every value must be a finite number strictly greater than zero.",
            "constraints": {
              "exclusive_min": 0,
              "finite": true
            },
            "nulls": "reject",
            "default": null
          },
          {
            "name": "parameters",
            "type": "Partial<Parameters>",
            "required": false,
            "description": "Overrides merged over `DEFAULTS`. The pivot scan uses `pivot_left` (2) and `pivot_right` (2) bars on each side and a window needs `pivots_per_side` (3) confirmed highs and the same number of lows; `max_pattern_bars` (44) caps the span from the first pivot to the last, `max_confirmation_bars` (4) caps how far past the last pivot a breakout is still accepted, and `impulse_lookback` (12) sets how far back the prior move is measured. The shape budget is `flat_tolerance` (0.00045), `min_slope` (0.00022), `parallel_tolerance` (0.00035), `min_convergence` (0.18), `min_impulse` (0.055) and `break_buffer` (0.001); the three slope figures are compared against a fitted slope divided by the window's mean pivot price, `min_convergence` against the fraction of channel width lost across the window, `min_impulse` against the return over `impulse_lookback` bars, and `break_buffer` against the fraction by which a close must clear a boundary. Any key outside this set is rejected.",
            "constraints": null,
            "nulls": null,
            "default": "{}"
          }
        ],
        "returns": {
          "type": "{ pattern: string; state: string; reason: string; event: Detection | null; events: Detection[]; pivots: Pivot[]; parameters: Parameters }",
          "description": "An object carrying `pattern`, the overall `state` (`searching`, `rejected`, `candidate` or `confirmed`), the `reason` behind that state, the selected `event`, the `events` that reached `confirmed`, every alternating `pivots` entry found so far, and the resolved `parameters`. Each event holds `pivot_indices`, `pivot_prices`, `pivot_types`, `candidate_available_index`, `confirmation_index`, `breakout_direction`, `expected_direction`, `subtype`, `upper_boundary`, `lower_boundary` and a `metrics` map with `upper_slope`, `lower_slope`, `upper_relative_slope`, `lower_relative_slope`, `upper_intercept`, `lower_intercept`, `width_start`, `width_end`, `convergence`, `parallel_gap`, `impulse`, `impulse_direction` and `formation_bars`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "close is not an array, or is empty",
            "behaviour": "throws Error"
          },
          {
            "when": "any close value is not a finite number, or is not strictly positive",
            "behaviour": "throws Error"
          },
          {
            "when": "parameters carries a key that is not one of the twelve in DEFAULTS",
            "behaviour": "throws Error"
          },
          {
            "when": "pivot_left, pivot_right, pivots_per_side, max_pattern_bars, max_confirmation_bars or impulse_lookback is not a positive integer, or pivots_per_side is below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "flat_tolerance, min_slope, parallel_tolerance, min_convergence, min_impulse or break_buffer is negative or not finite, or min_convergence or break_buffer is 1 or more",
            "behaviour": "throws Error"
          },
          {
            "when": "fewer than pivots_per_side * 2 alternating pivots have been confirmed",
            "behaviour": "returns state `searching` rather than throwing"
          }
        ],
        "complexity": {
          "time": "O(n * (pivot_left + pivot_right))",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "derived",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "detectAscendingTriangle([90,91.75,93.5,95.25,97,98.75])",
        "args": [
          {
            "value": [
              90,
              91.75,
              93.5,
              95.25,
              97,
              98.75
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 96
            }
          }
        ],
        "output": {
          "pattern": "ascending_triangle",
          "state": "confirmed",
          "reason": "breakout-confirmed",
          "event": {
            "pattern": "ascending_triangle",
            "state": "confirmed",
            "reason": "breakout-confirmed",
            "pivot_indices": [
              16,
              22,
              28,
              34,
              40,
              46
            ],
            "pivot_prices": [
              118,
              108,
              118.1,
              112,
              118,
              115
            ],
            "pivot_types": [
              "high",
              "low",
              "high",
              "low",
              "high",
              "low"
            ],
            "candidate_available_index": 48,
            "confirmation_index": 49,
            "breakout_direction": "bullish",
            "expected_direction": "bullish",
            "subtype": null,
            "upper_boundary": 118.03333333333335,
            "lower_boundary": 116.04166666666667,
            "metrics": {
              "upper_slope": 0,
              "lower_slope": 0.2916666666666667,
              "upper_relative_slope": 0,
              "lower_relative_slope": 0.0025395443331882165,
              "upper_intercept": 118.03333333333335,
              "lower_intercept": 101.75,
              "width_start": 11.616666666666674,
              "width_end": 2.8666666666666742,
              "convergence": 0.7532281205164988,
              "parallel_gap": 0.0025395443331882165,
              "impulse": 0.21649484536082475,
              "impulse_direction": "bullish",
              "formation_bars": 30
            }
          },
          "events": [
            {
              "pattern": "ascending_triangle",
              "state": "confirmed",
              "reason": "breakout-confirmed",
              "pivot_indices": [
                16,
                22,
                28,
                34,
                40,
                46
              ],
              "pivot_prices": [
                118,
                108,
                118.1,
                112,
                118,
                115
              ],
              "pivot_types": [
                "high",
                "low",
                "high",
                "low",
                "high",
                "low"
              ],
              "candidate_available_index": 48,
              "confirmation_index": 49,
              "breakout_direction": "bullish",
              "expected_direction": "bullish",
              "subtype": null,
              "upper_boundary": 118.03333333333335,
              "lower_boundary": 116.04166666666667,
              "metrics": {
                "upper_slope": 0,
                "lower_slope": 0.2916666666666667,
                "upper_relative_slope": 0,
                "lower_relative_slope": 0.0025395443331882165,
                "upper_intercept": 118.03333333333335,
                "lower_intercept": 101.75,
                "width_start": 11.616666666666674,
                "width_end": 2.8666666666666742,
                "convergence": 0.7532281205164988,
                "parallel_gap": 0.0025395443331882165,
                "impulse": 0.21649484536082475,
                "impulse_direction": "bullish",
                "formation_bars": 30
              }
            }
          ],
          "pivots": [
            {
              "kind": "high",
              "index": 16,
              "confirmation_index": 18,
              "price": 118
            },
            {
              "kind": "low",
              "index": 22,
              "confirmation_index": 24,
              "price": 108
            },
            {
              "kind": "high",
              "index": 28,
              "confirmation_index": 30,
              "price": 118.1
            }
          ],
          "parameters": {
            "pivot_left": 2,
            "pivot_right": 2,
            "pivots_per_side": 3,
            "max_pattern_bars": 44,
            "max_confirmation_bars": 4,
            "impulse_lookback": 12,
            "flat_tolerance": 0.00045,
            "min_slope": 0.00022,
            "parallel_tolerance": 0.00035,
            "min_convergence": 0.18,
            "min_impulse": 0.055,
            "break_buffer": 0.001
          }
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: pattern, state, reason, event, events, pivots, parameters"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "algorithm-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a01/static/algorithm-anatomy.svg"
          },
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a01/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a01/static/calculation-ledger.svg"
          },
          {
            "file": "causal-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a01/static/causal-timeline.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a01/static/failure-boundary.svg"
          },
          {
            "file": "method-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a01/static/method-comparison.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning Flow — Ascending Triangle",
            "source": "flowchart LR\n    A[\"Finalized close arrives\"] --> B[\"Confirm strict pivots after right-window delay\"]\n    B --> C{\"Six alternating pivots available?\"}\n    C -->|No| S[\"SEARCHING\"]\n    C -->|Yes| D[\"Fit upper and lower boundaries\"]\n    D --> E{\"Topic geometry contract passes?\"}\n    E -->|No| R[\"REJECTED with reason\"]\n    E -->|Yes| K[\"CANDIDATE at latest pivot confirmation\"]\n    K --> F{\"Later strict buffered crossing?\"}\n    F -->|Accepted side| G[\"CONFIRMED\"]\n    F -->|Opposite side or expired| R\n    F -->|Not yet| K"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613 and https://doi.org/10.3386/w7613"
        },
        {
          "key": "S2",
          "title": "SciPy `find_peaks`",
          "author": "SciPy project",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S3",
          "title": "The Probability of Backtest Overfitting",
          "author": "David H. Bailey, Jonathan M. Borwein, Marcos López de Prado, and Qiji Jim Zhu",
          "url": "https://papers.ssrn.com/sol3/Papers.cfm?abstract_id=2326253 and https://doi.org/10.2139/ssrn.2326253"
        },
        {
          "key": "Applicability decision",
          "title": "Applicability decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/continuation-structures/ascending-triangle/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/continuation-structures/ascending-triangle/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F03-A02",
      "name": "Descending Triangle",
      "headline": null,
      "slug": "descending-triangle",
      "path": "geometric-chart-patterns/continuation-structures/descending-triangle",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F03",
        "family": "Continuation Structures",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/continuation-structures/descending-triangle",
        "entry": "detectDescendingTriangle",
        "params": [
          "close",
          "parameters"
        ],
        "exports": [
          "detectDescendingTriangle",
          "traceDescendingTriangle"
        ],
        "archetype": "row-classify",
        "signature": "detectDescendingTriangle(close, parameters)"
      },
      "api": {
        "summary": "Scans a close series for a descending triangle - a falling ceiling pressing down on a flat floor - and reports whether that shape is still forming, has broken out, or was rejected. The two boundaries are least-squares lines fitted through the confirmed swing highs and swing lows of a pivot window; the shape passes when the floor's relative slope is within `flat_tolerance` of zero, the ceiling's is at most `-min_slope`, and the channel narrows by at least `min_convergence`. A close beyond either boundary by `break_buffer` within `max_confirmation_bars` of the last pivot ends the search, and only a bearish break confirms.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "The closing price series in chronological order, oldest bar first. Every value must be a finite number strictly greater than zero.",
            "constraints": {
              "exclusive_min": 0,
              "finite": true
            },
            "nulls": "reject",
            "default": null
          },
          {
            "name": "parameters",
            "type": "Partial<Parameters>",
            "required": false,
            "description": "Overrides merged over `DEFAULTS`. The pivot scan uses `pivot_left` (2) and `pivot_right` (2) bars on each side and a window needs `pivots_per_side` (3) confirmed highs and the same number of lows; `max_pattern_bars` (44) caps the span from the first pivot to the last, `max_confirmation_bars` (4) caps how far past the last pivot a breakout is still accepted, and `impulse_lookback` (12) sets how far back the prior move is measured. The shape budget is `flat_tolerance` (0.00045), `min_slope` (0.00022), `parallel_tolerance` (0.00035), `min_convergence` (0.18), `min_impulse` (0.055) and `break_buffer` (0.001); the three slope figures are compared against a fitted slope divided by the window's mean pivot price, `min_convergence` against the fraction of channel width lost across the window, `min_impulse` against the return over `impulse_lookback` bars, and `break_buffer` against the fraction by which a close must clear a boundary. Any key outside this set is rejected.",
            "constraints": null,
            "nulls": null,
            "default": "{}"
          }
        ],
        "returns": {
          "type": "{ pattern: string; state: string; reason: string; event: Detection | null; events: Detection[]; pivots: Pivot[]; parameters: Parameters }",
          "description": "An object carrying `pattern`, the overall `state` (`searching`, `rejected`, `candidate` or `confirmed`), the `reason` behind that state, the selected `event`, the `events` that reached `confirmed`, every alternating `pivots` entry found so far, and the resolved `parameters`. Each event holds `pivot_indices`, `pivot_prices`, `pivot_types`, `candidate_available_index`, `confirmation_index`, `breakout_direction`, `expected_direction`, `subtype`, `upper_boundary`, `lower_boundary` and a `metrics` map with `upper_slope`, `lower_slope`, `upper_relative_slope`, `lower_relative_slope`, `upper_intercept`, `lower_intercept`, `width_start`, `width_end`, `convergence`, `parallel_gap`, `impulse`, `impulse_direction` and `formation_bars`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "close is not an array, or is empty",
            "behaviour": "throws Error"
          },
          {
            "when": "any close value is not a finite number, or is not strictly positive",
            "behaviour": "throws Error"
          },
          {
            "when": "parameters carries a key that is not one of the twelve in DEFAULTS",
            "behaviour": "throws Error"
          },
          {
            "when": "pivot_left, pivot_right, pivots_per_side, max_pattern_bars, max_confirmation_bars or impulse_lookback is not a positive integer, or pivots_per_side is below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "flat_tolerance, min_slope, parallel_tolerance, min_convergence, min_impulse or break_buffer is negative or not finite, or min_convergence or break_buffer is 1 or more",
            "behaviour": "throws Error"
          },
          {
            "when": "fewer than pivots_per_side * 2 alternating pivots have been confirmed",
            "behaviour": "returns state `searching` rather than throwing"
          }
        ],
        "complexity": {
          "time": "O(n * (pivot_left + pivot_right))",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "derived",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "detectDescendingTriangle([140,138,136,134,132,130])",
        "args": [
          {
            "value": [
              140,
              138,
              136,
              134,
              132,
              130
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 96
            }
          }
        ],
        "output": {
          "pattern": "descending_triangle",
          "state": "confirmed",
          "reason": "breakout-confirmed",
          "event": {
            "pattern": "descending_triangle",
            "state": "confirmed",
            "reason": "breakout-confirmed",
            "pivot_indices": [
              16,
              22,
              28,
              34,
              40,
              46
            ],
            "pivot_prices": [
              108,
              122,
              108,
              118,
              108.1,
              115
            ],
            "pivot_types": [
              "low",
              "high",
              "low",
              "high",
              "low",
              "high"
            ],
            "candidate_available_index": 48,
            "confirmation_index": 50,
            "breakout_direction": "bearish",
            "expected_direction": "bearish",
            "subtype": null,
            "upper_boundary": 113.66666666666667,
            "lower_boundary": 108.125,
            "metrics": {
              "upper_slope": -0.2916666666666667,
              "lower_slope": 0.00416666666666643,
              "upper_relative_slope": -0.0025769400677367106,
              "lower_relative_slope": 0.00003681342953909377,
              "upper_intercept": 128.25,
              "lower_intercept": 107.91666666666669,
              "width_start": 15.59999999999998,
              "width_end": 6.72499999999998,
              "convergence": 0.5689102564102572,
              "parallel_gap": 0.002613753497275804,
              "impulse": -0.18181818181818182,
              "impulse_direction": "bearish",
              "formation_bars": 30
            }
          },
          "events": [
            {
              "pattern": "descending_triangle",
              "state": "confirmed",
              "reason": "breakout-confirmed",
              "pivot_indices": [
                16,
                22,
                28,
                34,
                40,
                46
              ],
              "pivot_prices": [
                108,
                122,
                108,
                118,
                108.1,
                115
              ],
              "pivot_types": [
                "low",
                "high",
                "low",
                "high",
                "low",
                "high"
              ],
              "candidate_available_index": 48,
              "confirmation_index": 50,
              "breakout_direction": "bearish",
              "expected_direction": "bearish",
              "subtype": null,
              "upper_boundary": 113.66666666666667,
              "lower_boundary": 108.125,
              "metrics": {
                "upper_slope": -0.2916666666666667,
                "lower_slope": 0.00416666666666643,
                "upper_relative_slope": -0.0025769400677367106,
                "lower_relative_slope": 0.00003681342953909377,
                "upper_intercept": 128.25,
                "lower_intercept": 107.91666666666669,
                "width_start": 15.59999999999998,
                "width_end": 6.72499999999998,
                "convergence": 0.5689102564102572,
                "parallel_gap": 0.002613753497275804,
                "impulse": -0.18181818181818182,
                "impulse_direction": "bearish",
                "formation_bars": 30
              }
            }
          ],
          "pivots": [
            {
              "kind": "low",
              "index": 16,
              "confirmation_index": 18,
              "price": 108
            },
            {
              "kind": "high",
              "index": 22,
              "confirmation_index": 24,
              "price": 122
            },
            {
              "kind": "low",
              "index": 28,
              "confirmation_index": 30,
              "price": 108
            }
          ],
          "parameters": {
            "pivot_left": 2,
            "pivot_right": 2,
            "pivots_per_side": 3,
            "max_pattern_bars": 44,
            "max_confirmation_bars": 4,
            "impulse_lookback": 12,
            "flat_tolerance": 0.00045,
            "min_slope": 0.00022,
            "parallel_tolerance": 0.00035,
            "min_convergence": 0.18,
            "min_impulse": 0.055,
            "break_buffer": 0.001
          }
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: pattern, state, reason, event, events, pivots, parameters"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "algorithm-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a02/static/algorithm-anatomy.svg"
          },
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a02/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a02/static/calculation-ledger.svg"
          },
          {
            "file": "causal-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a02/static/causal-timeline.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a02/static/failure-boundary.svg"
          },
          {
            "file": "method-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a02/static/method-comparison.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning Flow — Descending Triangle",
            "source": "flowchart LR\n    A[\"Finalized close arrives\"] --> B[\"Confirm strict pivots after right-window delay\"]\n    B --> C{\"Six alternating pivots available?\"}\n    C -->|No| S[\"SEARCHING\"]\n    C -->|Yes| D[\"Fit upper and lower boundaries\"]\n    D --> E{\"Topic geometry contract passes?\"}\n    E -->|No| R[\"REJECTED with reason\"]\n    E -->|Yes| K[\"CANDIDATE at latest pivot confirmation\"]\n    K --> F{\"Later strict buffered crossing?\"}\n    F -->|Accepted side| G[\"CONFIRMED\"]\n    F -->|Opposite side or expired| R\n    F -->|Not yet| K"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613 and https://doi.org/10.3386/w7613"
        },
        {
          "key": "S2",
          "title": "SciPy `find_peaks`",
          "author": "SciPy project",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S3",
          "title": "The Probability of Backtest Overfitting",
          "author": "David H. Bailey, Jonathan M. Borwein, Marcos López de Prado, and Qiji Jim Zhu",
          "url": "https://papers.ssrn.com/sol3/Papers.cfm?abstract_id=2326253 and https://doi.org/10.2139/ssrn.2326253"
        },
        {
          "key": "Applicability decision",
          "title": "Applicability decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/continuation-structures/descending-triangle/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/continuation-structures/descending-triangle/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F03-A03",
      "name": "Symmetrical Triangle",
      "headline": null,
      "slug": "symmetrical-triangle",
      "path": "geometric-chart-patterns/continuation-structures/symmetrical-triangle",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F03",
        "family": "Continuation Structures",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/continuation-structures/symmetrical-triangle",
        "entry": "detectSymmetricalTriangle",
        "params": [
          "close",
          "parameters"
        ],
        "exports": [
          "detectSymmetricalTriangle",
          "traceSymmetricalTriangle"
        ],
        "archetype": "row-classify",
        "signature": "detectSymmetricalTriangle(close, parameters)"
      },
      "api": {
        "summary": "Scans a close series for a symmetrical triangle - a falling ceiling and a rising floor closing on each other - and reports whether that shape is still forming, has broken out, or was rejected. The shape passes when the fitted ceiling's relative slope is at most `-min_slope`, the floor's is at least `min_slope`, and the channel narrows by at least `min_convergence`. The prior move over `impulse_lookback` bars sets the expected side only when its size reaches `min_impulse`; without that, a break through either boundary by `break_buffer` confirms.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "The closing price series in chronological order, oldest bar first. Every value must be a finite number strictly greater than zero.",
            "constraints": {
              "exclusive_min": 0,
              "finite": true
            },
            "nulls": "reject",
            "default": null
          },
          {
            "name": "parameters",
            "type": "Partial<Parameters>",
            "required": false,
            "description": "Overrides merged over `DEFAULTS`. The pivot scan uses `pivot_left` (2) and `pivot_right` (2) bars on each side and a window needs `pivots_per_side` (3) confirmed highs and the same number of lows; `max_pattern_bars` (44) caps the span from the first pivot to the last, `max_confirmation_bars` (4) caps how far past the last pivot a breakout is still accepted, and `impulse_lookback` (12) sets how far back the prior move is measured. The shape budget is `flat_tolerance` (0.00045), `min_slope` (0.00022), `parallel_tolerance` (0.00035), `min_convergence` (0.18), `min_impulse` (0.055) and `break_buffer` (0.001); the three slope figures are compared against a fitted slope divided by the window's mean pivot price, `min_convergence` against the fraction of channel width lost across the window, `min_impulse` against the return over `impulse_lookback` bars, and `break_buffer` against the fraction by which a close must clear a boundary. Any key outside this set is rejected.",
            "constraints": null,
            "nulls": null,
            "default": "{}"
          }
        ],
        "returns": {
          "type": "{ pattern: string; state: string; reason: string; event: Detection | null; events: Detection[]; pivots: Pivot[]; parameters: Parameters }",
          "description": "An object carrying `pattern`, the overall `state` (`searching`, `rejected`, `candidate` or `confirmed`), the `reason` behind that state, the selected `event`, the `events` that reached `confirmed`, every alternating `pivots` entry found so far, and the resolved `parameters`. Each event holds `pivot_indices`, `pivot_prices`, `pivot_types`, `candidate_available_index`, `confirmation_index`, `breakout_direction`, `expected_direction`, `subtype`, `upper_boundary`, `lower_boundary` and a `metrics` map with `upper_slope`, `lower_slope`, `upper_relative_slope`, `lower_relative_slope`, `upper_intercept`, `lower_intercept`, `width_start`, `width_end`, `convergence`, `parallel_gap`, `impulse`, `impulse_direction` and `formation_bars`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "close is not an array, or is empty",
            "behaviour": "throws Error"
          },
          {
            "when": "any close value is not a finite number, or is not strictly positive",
            "behaviour": "throws Error"
          },
          {
            "when": "parameters carries a key that is not one of the twelve in DEFAULTS",
            "behaviour": "throws Error"
          },
          {
            "when": "pivot_left, pivot_right, pivots_per_side, max_pattern_bars, max_confirmation_bars or impulse_lookback is not a positive integer, or pivots_per_side is below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "flat_tolerance, min_slope, parallel_tolerance, min_convergence, min_impulse or break_buffer is negative or not finite, or min_convergence or break_buffer is 1 or more",
            "behaviour": "throws Error"
          },
          {
            "when": "fewer than pivots_per_side * 2 alternating pivots have been confirmed",
            "behaviour": "returns state `searching` rather than throwing"
          }
        ],
        "complexity": {
          "time": "O(n * (pivot_left + pivot_right))",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "derived",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "detectSymmetricalTriangle([90,92,94,96,98,100])",
        "args": [
          {
            "value": [
              90,
              92,
              94,
              96,
              98,
              100
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 96
            }
          }
        ],
        "output": {
          "pattern": "symmetrical_triangle",
          "state": "confirmed",
          "reason": "breakout-confirmed",
          "event": {
            "pattern": "symmetrical_triangle",
            "state": "confirmed",
            "reason": "breakout-confirmed",
            "pivot_indices": [
              16,
              22,
              28,
              34,
              40,
              46
            ],
            "pivot_prices": [
              122,
              106,
              119,
              109,
              117,
              111
            ],
            "pivot_types": [
              "high",
              "low",
              "high",
              "low",
              "high",
              "low"
            ],
            "candidate_available_index": 48,
            "confirmation_index": 49,
            "breakout_direction": "bullish",
            "expected_direction": "bullish",
            "subtype": null,
            "upper_boundary": 114.95833333333333,
            "lower_boundary": 111.79166666666667,
            "metrics": {
              "upper_slope": -0.20833333333333334,
              "lower_slope": 0.20833333333333334,
              "upper_relative_slope": -0.0018274853801169592,
              "lower_relative_slope": 0.0018274853801169592,
              "upper_intercept": 125.16666666666666,
              "lower_intercept": 101.58333333333334,
              "width_start": 16.916666666666657,
              "width_end": 4.416666666666657,
              "convergence": 0.7389162561576359,
              "parallel_gap": 0.0036549707602339184,
              "impulse": 0.24489795918367346,
              "impulse_direction": "bullish",
              "formation_bars": 30
            }
          },
          "events": [
            {
              "pattern": "symmetrical_triangle",
              "state": "confirmed",
              "reason": "breakout-confirmed",
              "pivot_indices": [
                16,
                22,
                28,
                34,
                40,
                46
              ],
              "pivot_prices": [
                122,
                106,
                119,
                109,
                117,
                111
              ],
              "pivot_types": [
                "high",
                "low",
                "high",
                "low",
                "high",
                "low"
              ],
              "candidate_available_index": 48,
              "confirmation_index": 49,
              "breakout_direction": "bullish",
              "expected_direction": "bullish",
              "subtype": null,
              "upper_boundary": 114.95833333333333,
              "lower_boundary": 111.79166666666667,
              "metrics": {
                "upper_slope": -0.20833333333333334,
                "lower_slope": 0.20833333333333334,
                "upper_relative_slope": -0.0018274853801169592,
                "lower_relative_slope": 0.0018274853801169592,
                "upper_intercept": 125.16666666666666,
                "lower_intercept": 101.58333333333334,
                "width_start": 16.916666666666657,
                "width_end": 4.416666666666657,
                "convergence": 0.7389162561576359,
                "parallel_gap": 0.0036549707602339184,
                "impulse": 0.24489795918367346,
                "impulse_direction": "bullish",
                "formation_bars": 30
              }
            }
          ],
          "pivots": [
            {
              "kind": "high",
              "index": 16,
              "confirmation_index": 18,
              "price": 122
            },
            {
              "kind": "low",
              "index": 22,
              "confirmation_index": 24,
              "price": 106
            },
            {
              "kind": "high",
              "index": 28,
              "confirmation_index": 30,
              "price": 119
            }
          ],
          "parameters": {
            "pivot_left": 2,
            "pivot_right": 2,
            "pivots_per_side": 3,
            "max_pattern_bars": 44,
            "max_confirmation_bars": 4,
            "impulse_lookback": 12,
            "flat_tolerance": 0.00045,
            "min_slope": 0.00022,
            "parallel_tolerance": 0.00035,
            "min_convergence": 0.18,
            "min_impulse": 0.055,
            "break_buffer": 0.001
          }
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: pattern, state, reason, event, events, pivots, parameters"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "algorithm-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a03/static/algorithm-anatomy.svg"
          },
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a03/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a03/static/calculation-ledger.svg"
          },
          {
            "file": "causal-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a03/static/causal-timeline.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a03/static/failure-boundary.svg"
          },
          {
            "file": "method-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a03/static/method-comparison.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning Flow — Symmetrical Triangle",
            "source": "flowchart LR\n    A[\"Finalized close arrives\"] --> B[\"Confirm strict pivots after right-window delay\"]\n    B --> C{\"Six alternating pivots available?\"}\n    C -->|No| S[\"SEARCHING\"]\n    C -->|Yes| D[\"Fit upper and lower boundaries\"]\n    D --> E{\"Topic geometry contract passes?\"}\n    E -->|No| R[\"REJECTED with reason\"]\n    E -->|Yes| K[\"CANDIDATE at latest pivot confirmation\"]\n    K --> F{\"Later strict buffered crossing?\"}\n    F -->|Accepted side| G[\"CONFIRMED\"]\n    F -->|Opposite side or expired| R\n    F -->|Not yet| K"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613 and https://doi.org/10.3386/w7613"
        },
        {
          "key": "S2",
          "title": "SciPy `find_peaks`",
          "author": "SciPy project",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S3",
          "title": "The Probability of Backtest Overfitting",
          "author": "David H. Bailey, Jonathan M. Borwein, Marcos López de Prado, and Qiji Jim Zhu",
          "url": "https://papers.ssrn.com/sol3/Papers.cfm?abstract_id=2326253 and https://doi.org/10.2139/ssrn.2326253"
        },
        {
          "key": "Applicability decision",
          "title": "Applicability decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/continuation-structures/symmetrical-triangle/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/continuation-structures/symmetrical-triangle/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F03-A04",
      "name": "Flag",
      "headline": null,
      "slug": "flag",
      "path": "geometric-chart-patterns/continuation-structures/flag",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F03",
        "family": "Continuation Structures",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/continuation-structures/flag",
        "entry": "detectFlag",
        "params": [
          "close",
          "parameters"
        ],
        "exports": [
          "detectFlag",
          "traceFlag"
        ],
        "archetype": "row-classify",
        "signature": "detectFlag(close, parameters)"
      },
      "api": {
        "summary": "Scans a close series for a flag - a strong prior move followed by a narrow channel drifting against it - and reports whether that shape is still forming, has broken out, or was rejected. The shape passes when the move over `impulse_lookback` bars reaches `min_impulse`, both fitted boundaries slope against it by more than `min_slope`, the gap between their relative slopes is within `parallel_tolerance`, and the channel ends between 0.65 and 1.35 times its starting width. Only a break in the impulse's own direction, by `break_buffer` within `max_confirmation_bars` of the last pivot, confirms.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "The closing price series in chronological order, oldest bar first. Every value must be a finite number strictly greater than zero.",
            "constraints": {
              "exclusive_min": 0,
              "finite": true
            },
            "nulls": "reject",
            "default": null
          },
          {
            "name": "parameters",
            "type": "Partial<Parameters>",
            "required": false,
            "description": "Overrides merged over `DEFAULTS`. The pivot scan uses `pivot_left` (2) and `pivot_right` (2) bars on each side and a window needs `pivots_per_side` (3) confirmed highs and the same number of lows; `max_pattern_bars` (44) caps the span from the first pivot to the last, `max_confirmation_bars` (4) caps how far past the last pivot a breakout is still accepted, and `impulse_lookback` (12) sets how far back the prior move is measured. The shape budget is `flat_tolerance` (0.00045), `min_slope` (0.00022), `parallel_tolerance` (0.00035), `min_convergence` (0.18), `min_impulse` (0.055) and `break_buffer` (0.001); the three slope figures are compared against a fitted slope divided by the window's mean pivot price, `min_convergence` against the fraction of channel width lost across the window, `min_impulse` against the return over `impulse_lookback` bars, and `break_buffer` against the fraction by which a close must clear a boundary. Any key outside this set is rejected.",
            "constraints": null,
            "nulls": null,
            "default": "{}"
          }
        ],
        "returns": {
          "type": "{ pattern: string; state: string; reason: string; event: Detection | null; events: Detection[]; pivots: Pivot[]; parameters: Parameters }",
          "description": "An object carrying `pattern`, the overall `state` (`searching`, `rejected`, `candidate` or `confirmed`), the `reason` behind that state, the selected `event`, the `events` that reached `confirmed`, every alternating `pivots` entry found so far, and the resolved `parameters`. Each event holds `pivot_indices`, `pivot_prices`, `pivot_types`, `candidate_available_index`, `confirmation_index`, `breakout_direction`, `expected_direction`, `subtype`, `upper_boundary`, `lower_boundary` and a `metrics` map with `upper_slope`, `lower_slope`, `upper_relative_slope`, `lower_relative_slope`, `upper_intercept`, `lower_intercept`, `width_start`, `width_end`, `convergence`, `parallel_gap`, `impulse`, `impulse_direction` and `formation_bars`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "close is not an array, or is empty",
            "behaviour": "throws Error"
          },
          {
            "when": "any close value is not a finite number, or is not strictly positive",
            "behaviour": "throws Error"
          },
          {
            "when": "parameters carries a key that is not one of the twelve in DEFAULTS",
            "behaviour": "throws Error"
          },
          {
            "when": "pivot_left, pivot_right, pivots_per_side, max_pattern_bars, max_confirmation_bars or impulse_lookback is not a positive integer, or pivots_per_side is below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "flat_tolerance, min_slope, parallel_tolerance, min_convergence, min_impulse or break_buffer is negative or not finite, or min_convergence or break_buffer is 1 or more",
            "behaviour": "throws Error"
          },
          {
            "when": "fewer than pivots_per_side * 2 alternating pivots have been confirmed",
            "behaviour": "returns state `searching` rather than throwing"
          }
        ],
        "complexity": {
          "time": "O(n * (pivot_left + pivot_right))",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "derived",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "detectFlag([92,94.416667,96.833333,99.25,101.666667,104.083333])",
        "args": [
          {
            "value": [
              92,
              94.416667,
              96.833333,
              99.25,
              101.666667,
              104.083333
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 96
            }
          }
        ],
        "output": {
          "pattern": "flag",
          "state": "confirmed",
          "reason": "breakout-confirmed",
          "event": {
            "pattern": "flag",
            "state": "confirmed",
            "reason": "breakout-confirmed",
            "pivot_indices": [
              16,
              22,
              28,
              34,
              40,
              46
            ],
            "pivot_prices": [
              125,
              117,
              123,
              115,
              121,
              113
            ],
            "pivot_types": [
              "high",
              "low",
              "high",
              "low",
              "high",
              "low"
            ],
            "candidate_available_index": 48,
            "confirmation_index": 50,
            "breakout_direction": "bullish",
            "expected_direction": "bullish",
            "subtype": null,
            "upper_boundary": 119.33333333333334,
            "lower_boundary": 112.33333333333334,
            "metrics": {
              "upper_slope": -0.16666666666666666,
              "lower_slope": -0.16666666666666666,
              "upper_relative_slope": -0.0014005602240896359,
              "lower_relative_slope": -0.0014005602240896359,
              "upper_intercept": 127.66666666666667,
              "lower_intercept": 120.66666666666667,
              "width_start": 7,
              "width_end": 7,
              "convergence": 0,
              "parallel_gap": 0,
              "impulse": 0.22950819269013703,
              "impulse_direction": "bullish",
              "formation_bars": 30
            }
          },
          "events": [
            {
              "pattern": "flag",
              "state": "confirmed",
              "reason": "breakout-confirmed",
              "pivot_indices": [
                16,
                22,
                28,
                34,
                40,
                46
              ],
              "pivot_prices": [
                125,
                117,
                123,
                115,
                121,
                113
              ],
              "pivot_types": [
                "high",
                "low",
                "high",
                "low",
                "high",
                "low"
              ],
              "candidate_available_index": 48,
              "confirmation_index": 50,
              "breakout_direction": "bullish",
              "expected_direction": "bullish",
              "subtype": null,
              "upper_boundary": 119.33333333333334,
              "lower_boundary": 112.33333333333334,
              "metrics": {
                "upper_slope": -0.16666666666666666,
                "lower_slope": -0.16666666666666666,
                "upper_relative_slope": -0.0014005602240896359,
                "lower_relative_slope": -0.0014005602240896359,
                "upper_intercept": 127.66666666666667,
                "lower_intercept": 120.66666666666667,
                "width_start": 7,
                "width_end": 7,
                "convergence": 0,
                "parallel_gap": 0,
                "impulse": 0.22950819269013703,
                "impulse_direction": "bullish",
                "formation_bars": 30
              }
            }
          ],
          "pivots": [
            {
              "kind": "high",
              "index": 16,
              "confirmation_index": 18,
              "price": 125
            },
            {
              "kind": "low",
              "index": 22,
              "confirmation_index": 24,
              "price": 117
            },
            {
              "kind": "high",
              "index": 28,
              "confirmation_index": 30,
              "price": 123
            }
          ],
          "parameters": {
            "pivot_left": 2,
            "pivot_right": 2,
            "pivots_per_side": 3,
            "max_pattern_bars": 44,
            "max_confirmation_bars": 4,
            "impulse_lookback": 12,
            "flat_tolerance": 0.00045,
            "min_slope": 0.00022,
            "parallel_tolerance": 0.00035,
            "min_convergence": 0.18,
            "min_impulse": 0.055,
            "break_buffer": 0.001
          }
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: pattern, state, reason, event, events, pivots, parameters"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "algorithm-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a04/static/algorithm-anatomy.svg"
          },
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a04/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a04/static/calculation-ledger.svg"
          },
          {
            "file": "causal-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a04/static/causal-timeline.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a04/static/failure-boundary.svg"
          },
          {
            "file": "method-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a04/static/method-comparison.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning Flow — Flag",
            "source": "flowchart LR\n    A[\"Finalized close arrives\"] --> B[\"Confirm strict pivots after right-window delay\"]\n    B --> C{\"Six alternating pivots available?\"}\n    C -->|No| S[\"SEARCHING\"]\n    C -->|Yes| D[\"Fit upper and lower boundaries\"]\n    D --> E{\"Topic geometry contract passes?\"}\n    E -->|No| R[\"REJECTED with reason\"]\n    E -->|Yes| K[\"CANDIDATE at latest pivot confirmation\"]\n    K --> F{\"Later strict buffered crossing?\"}\n    F -->|Accepted side| G[\"CONFIRMED\"]\n    F -->|Opposite side or expired| R\n    F -->|Not yet| K"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613 and https://doi.org/10.3386/w7613"
        },
        {
          "key": "S2",
          "title": "SciPy `find_peaks`",
          "author": "SciPy project",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S3",
          "title": "The Probability of Backtest Overfitting",
          "author": "David H. Bailey, Jonathan M. Borwein, Marcos López de Prado, and Qiji Jim Zhu",
          "url": "https://papers.ssrn.com/sol3/Papers.cfm?abstract_id=2326253 and https://doi.org/10.2139/ssrn.2326253"
        },
        {
          "key": "Applicability decision",
          "title": "Applicability decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/continuation-structures/flag/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/continuation-structures/flag/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F03-A05",
      "name": "Pennant",
      "headline": null,
      "slug": "pennant",
      "path": "geometric-chart-patterns/continuation-structures/pennant",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F03",
        "family": "Continuation Structures",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/continuation-structures/pennant",
        "entry": "detectPennant",
        "params": [
          "close",
          "parameters"
        ],
        "exports": [
          "detectPennant",
          "tracePennant"
        ],
        "archetype": "row-classify",
        "signature": "detectPennant(close, parameters)"
      },
      "api": {
        "summary": "Scans a close series for a pennant - a strong prior move followed by a small converging triangle - and reports whether that shape is still forming, has broken out, or was rejected. The shape passes when the move over `impulse_lookback` bars reaches `min_impulse`, the fitted ceiling's relative slope is at most `-min_slope`, the floor's is at least `min_slope`, and the channel narrows by at least `min_convergence`. Only a break in the impulse's own direction, by `break_buffer` within `max_confirmation_bars` of the last pivot, confirms.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "The closing price series in chronological order, oldest bar first. Every value must be a finite number strictly greater than zero.",
            "constraints": {
              "exclusive_min": 0,
              "finite": true
            },
            "nulls": "reject",
            "default": null
          },
          {
            "name": "parameters",
            "type": "Partial<Parameters>",
            "required": false,
            "description": "Overrides merged over `DEFAULTS`. The pivot scan uses `pivot_left` (2) and `pivot_right` (2) bars on each side and a window needs `pivots_per_side` (3) confirmed highs and the same number of lows; `max_pattern_bars` (44) caps the span from the first pivot to the last, `max_confirmation_bars` (4) caps how far past the last pivot a breakout is still accepted, and `impulse_lookback` (12) sets how far back the prior move is measured. The shape budget is `flat_tolerance` (0.00045), `min_slope` (0.00022), `parallel_tolerance` (0.00035), `min_convergence` (0.18), `min_impulse` (0.055) and `break_buffer` (0.001); the three slope figures are compared against a fitted slope divided by the window's mean pivot price, `min_convergence` against the fraction of channel width lost across the window, `min_impulse` against the return over `impulse_lookback` bars, and `break_buffer` against the fraction by which a close must clear a boundary. Any key outside this set is rejected.",
            "constraints": null,
            "nulls": null,
            "default": "{}"
          }
        ],
        "returns": {
          "type": "{ pattern: string; state: string; reason: string; event: Detection | null; events: Detection[]; pivots: Pivot[]; parameters: Parameters }",
          "description": "An object carrying `pattern`, the overall `state` (`searching`, `rejected`, `candidate` or `confirmed`), the `reason` behind that state, the selected `event`, the `events` that reached `confirmed`, every alternating `pivots` entry found so far, and the resolved `parameters`. Each event holds `pivot_indices`, `pivot_prices`, `pivot_types`, `candidate_available_index`, `confirmation_index`, `breakout_direction`, `expected_direction`, `subtype`, `upper_boundary`, `lower_boundary` and a `metrics` map with `upper_slope`, `lower_slope`, `upper_relative_slope`, `lower_relative_slope`, `upper_intercept`, `lower_intercept`, `width_start`, `width_end`, `convergence`, `parallel_gap`, `impulse`, `impulse_direction` and `formation_bars`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "close is not an array, or is empty",
            "behaviour": "throws Error"
          },
          {
            "when": "any close value is not a finite number, or is not strictly positive",
            "behaviour": "throws Error"
          },
          {
            "when": "parameters carries a key that is not one of the twelve in DEFAULTS",
            "behaviour": "throws Error"
          },
          {
            "when": "pivot_left, pivot_right, pivots_per_side, max_pattern_bars, max_confirmation_bars or impulse_lookback is not a positive integer, or pivots_per_side is below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "flat_tolerance, min_slope, parallel_tolerance, min_convergence, min_impulse or break_buffer is negative or not finite, or min_convergence or break_buffer is 1 or more",
            "behaviour": "throws Error"
          },
          {
            "when": "fewer than pivots_per_side * 2 alternating pivots have been confirmed",
            "behaviour": "returns state `searching` rather than throwing"
          }
        ],
        "complexity": {
          "time": "O(n * (pivot_left + pivot_right))",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "derived",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "detectPennant([92,94.416667,96.833333,99.25,101.666667,104.083333])",
        "args": [
          {
            "value": [
              92,
              94.416667,
              96.833333,
              99.25,
              101.666667,
              104.083333
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 96
            }
          }
        ],
        "output": {
          "pattern": "pennant",
          "state": "confirmed",
          "reason": "breakout-confirmed",
          "event": {
            "pattern": "pennant",
            "state": "confirmed",
            "reason": "breakout-confirmed",
            "pivot_indices": [
              16,
              22,
              28,
              34,
              40,
              46
            ],
            "pivot_prices": [
              125,
              115,
              123,
              116.5,
              121,
              118
            ],
            "pivot_types": [
              "high",
              "low",
              "high",
              "low",
              "high",
              "low"
            ],
            "candidate_available_index": 48,
            "confirmation_index": 49,
            "breakout_direction": "bullish",
            "expected_direction": "bullish",
            "subtype": null,
            "upper_boundary": 119.5,
            "lower_boundary": 118.375,
            "metrics": {
              "upper_slope": -0.16666666666666666,
              "lower_slope": 0.125,
              "upper_relative_slope": -0.0013917884481558802,
              "lower_relative_slope": 0.0010438413361169101,
              "upper_intercept": 127.66666666666667,
              "lower_intercept": 112.25,
              "width_start": 10.75,
              "width_end": 2,
              "convergence": 0.813953488372093,
              "parallel_gap": 0.0024356297842727903,
              "impulse": 0.22950819269013703,
              "impulse_direction": "bullish",
              "formation_bars": 30
            }
          },
          "events": [
            {
              "pattern": "pennant",
              "state": "confirmed",
              "reason": "breakout-confirmed",
              "pivot_indices": [
                16,
                22,
                28,
                34,
                40,
                46
              ],
              "pivot_prices": [
                125,
                115,
                123,
                116.5,
                121,
                118
              ],
              "pivot_types": [
                "high",
                "low",
                "high",
                "low",
                "high",
                "low"
              ],
              "candidate_available_index": 48,
              "confirmation_index": 49,
              "breakout_direction": "bullish",
              "expected_direction": "bullish",
              "subtype": null,
              "upper_boundary": 119.5,
              "lower_boundary": 118.375,
              "metrics": {
                "upper_slope": -0.16666666666666666,
                "lower_slope": 0.125,
                "upper_relative_slope": -0.0013917884481558802,
                "lower_relative_slope": 0.0010438413361169101,
                "upper_intercept": 127.66666666666667,
                "lower_intercept": 112.25,
                "width_start": 10.75,
                "width_end": 2,
                "convergence": 0.813953488372093,
                "parallel_gap": 0.0024356297842727903,
                "impulse": 0.22950819269013703,
                "impulse_direction": "bullish",
                "formation_bars": 30
              }
            }
          ],
          "pivots": [
            {
              "kind": "high",
              "index": 16,
              "confirmation_index": 18,
              "price": 125
            },
            {
              "kind": "low",
              "index": 22,
              "confirmation_index": 24,
              "price": 115
            },
            {
              "kind": "high",
              "index": 28,
              "confirmation_index": 30,
              "price": 123
            }
          ],
          "parameters": {
            "pivot_left": 2,
            "pivot_right": 2,
            "pivots_per_side": 3,
            "max_pattern_bars": 44,
            "max_confirmation_bars": 4,
            "impulse_lookback": 12,
            "flat_tolerance": 0.00045,
            "min_slope": 0.00022,
            "parallel_tolerance": 0.00035,
            "min_convergence": 0.18,
            "min_impulse": 0.055,
            "break_buffer": 0.001
          }
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: pattern, state, reason, event, events, pivots, parameters"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "algorithm-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a05/static/algorithm-anatomy.svg"
          },
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a05/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a05/static/calculation-ledger.svg"
          },
          {
            "file": "causal-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a05/static/causal-timeline.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a05/static/failure-boundary.svg"
          },
          {
            "file": "method-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a05/static/method-comparison.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning Flow — Pennant",
            "source": "flowchart LR\n    A[\"Finalized close arrives\"] --> B[\"Confirm strict pivots after right-window delay\"]\n    B --> C{\"Six alternating pivots available?\"}\n    C -->|No| S[\"SEARCHING\"]\n    C -->|Yes| D[\"Fit upper and lower boundaries\"]\n    D --> E{\"Topic geometry contract passes?\"}\n    E -->|No| R[\"REJECTED with reason\"]\n    E -->|Yes| K[\"CANDIDATE at latest pivot confirmation\"]\n    K --> F{\"Later strict buffered crossing?\"}\n    F -->|Accepted side| G[\"CONFIRMED\"]\n    F -->|Opposite side or expired| R\n    F -->|Not yet| K"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613 and https://doi.org/10.3386/w7613"
        },
        {
          "key": "S2",
          "title": "SciPy `find_peaks`",
          "author": "SciPy project",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S3",
          "title": "The Probability of Backtest Overfitting",
          "author": "David H. Bailey, Jonathan M. Borwein, Marcos López de Prado, and Qiji Jim Zhu",
          "url": "https://papers.ssrn.com/sol3/Papers.cfm?abstract_id=2326253 and https://doi.org/10.2139/ssrn.2326253"
        },
        {
          "key": "Applicability decision",
          "title": "Applicability decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/continuation-structures/pennant/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/continuation-structures/pennant/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F03-A06",
      "name": "Rising/Falling Wedge",
      "headline": null,
      "slug": "rising-falling-wedge",
      "path": "geometric-chart-patterns/continuation-structures/rising-falling-wedge",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F03",
        "family": "Continuation Structures",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/continuation-structures/rising-falling-wedge",
        "entry": "detectRisingFallingWedge",
        "params": [
          "close",
          "parameters"
        ],
        "exports": [
          "detectRisingFallingWedge",
          "traceRisingFallingWedge"
        ],
        "archetype": "row-classify",
        "signature": "detectRisingFallingWedge(close, parameters)"
      },
      "api": {
        "summary": "Scans a close series for a wedge - two boundaries tilted the same way while converging - and reports whether that shape is still forming, has broken out, or was rejected. A rising wedge needs both fitted slopes at or above `min_slope` with the floor rising faster than the ceiling, and expects a bearish break; a falling wedge needs both at or below `-min_slope` with the ceiling falling faster than the floor, and expects a bullish break. Either way the channel must narrow by at least `min_convergence`, the matching `subtype` (`rising` or `falling`) is reported on the event, and a break the other way is recorded as rejected.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "The closing price series in chronological order, oldest bar first. Every value must be a finite number strictly greater than zero.",
            "constraints": {
              "exclusive_min": 0,
              "finite": true
            },
            "nulls": "reject",
            "default": null
          },
          {
            "name": "parameters",
            "type": "Partial<Parameters>",
            "required": false,
            "description": "Overrides merged over `DEFAULTS`. The pivot scan uses `pivot_left` (2) and `pivot_right` (2) bars on each side and a window needs `pivots_per_side` (3) confirmed highs and the same number of lows; `max_pattern_bars` (44) caps the span from the first pivot to the last, `max_confirmation_bars` (4) caps how far past the last pivot a breakout is still accepted, and `impulse_lookback` (12) sets how far back the prior move is measured. The shape budget is `flat_tolerance` (0.00045), `min_slope` (0.00022), `parallel_tolerance` (0.00035), `min_convergence` (0.18), `min_impulse` (0.055) and `break_buffer` (0.001); the three slope figures are compared against a fitted slope divided by the window's mean pivot price, `min_convergence` against the fraction of channel width lost across the window, `min_impulse` against the return over `impulse_lookback` bars, and `break_buffer` against the fraction by which a close must clear a boundary. Any key outside this set is rejected.",
            "constraints": null,
            "nulls": null,
            "default": "{}"
          }
        ],
        "returns": {
          "type": "{ pattern: string; state: string; reason: string; event: Detection | null; events: Detection[]; pivots: Pivot[]; parameters: Parameters }",
          "description": "An object carrying `pattern`, the overall `state` (`searching`, `rejected`, `candidate` or `confirmed`), the `reason` behind that state, the selected `event`, the `events` that reached `confirmed`, every alternating `pivots` entry found so far, and the resolved `parameters`. Each event holds `pivot_indices`, `pivot_prices`, `pivot_types`, `candidate_available_index`, `confirmation_index`, `breakout_direction`, `expected_direction`, `subtype`, `upper_boundary`, `lower_boundary` and a `metrics` map with `upper_slope`, `lower_slope`, `upper_relative_slope`, `lower_relative_slope`, `upper_intercept`, `lower_intercept`, `width_start`, `width_end`, `convergence`, `parallel_gap`, `impulse`, `impulse_direction` and `formation_bars`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "close is not an array, or is empty",
            "behaviour": "throws Error"
          },
          {
            "when": "any close value is not a finite number, or is not strictly positive",
            "behaviour": "throws Error"
          },
          {
            "when": "parameters carries a key that is not one of the twelve in DEFAULTS",
            "behaviour": "throws Error"
          },
          {
            "when": "pivot_left, pivot_right, pivots_per_side, max_pattern_bars, max_confirmation_bars or impulse_lookback is not a positive integer, or pivots_per_side is below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "flat_tolerance, min_slope, parallel_tolerance, min_convergence, min_impulse or break_buffer is negative or not finite, or min_convergence or break_buffer is 1 or more",
            "behaviour": "throws Error"
          },
          {
            "when": "fewer than pivots_per_side * 2 alternating pivots have been confirmed",
            "behaviour": "returns state `searching` rather than throwing"
          }
        ],
        "complexity": {
          "time": "O(n * (pivot_left + pivot_right))",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "derived",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "detectRisingFallingWedge([90,91.5,93,94.5,96,97.5])",
        "args": [
          {
            "value": [
              90,
              91.5,
              93,
              94.5,
              96,
              97.5
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 96
            }
          }
        ],
        "output": {
          "pattern": "wedge",
          "state": "confirmed",
          "reason": "breakout-confirmed",
          "event": {
            "pattern": "wedge",
            "state": "confirmed",
            "reason": "breakout-confirmed",
            "pivot_indices": [
              16,
              22,
              28,
              34,
              40,
              46
            ],
            "pivot_prices": [
              105,
              113,
              109,
              116,
              113,
              118
            ],
            "pivot_types": [
              "low",
              "high",
              "low",
              "high",
              "low",
              "high"
            ],
            "candidate_available_index": 48,
            "confirmation_index": 49,
            "breakout_direction": "bearish",
            "expected_direction": "bearish",
            "subtype": "rising",
            "upper_boundary": 118.79166666666667,
            "lower_boundary": 116,
            "metrics": {
              "upper_slope": 0.20833333333333334,
              "lower_slope": 0.3333333333333333,
              "upper_relative_slope": 0.00185459940652819,
              "lower_relative_slope": 0.002967359050445104,
              "upper_intercept": 108.58333333333334,
              "lower_intercept": 99.66666666666667,
              "width_start": 6.916666666666671,
              "width_end": 3.1666666666666714,
              "convergence": 0.5421686746987948,
              "parallel_gap": 0.001112759643916914,
              "impulse": 0.09375,
              "impulse_direction": "bullish",
              "formation_bars": 30
            }
          },
          "events": [
            {
              "pattern": "wedge",
              "state": "confirmed",
              "reason": "breakout-confirmed",
              "pivot_indices": [
                16,
                22,
                28,
                34,
                40,
                46
              ],
              "pivot_prices": [
                105,
                113,
                109,
                116,
                113,
                118
              ],
              "pivot_types": [
                "low",
                "high",
                "low",
                "high",
                "low",
                "high"
              ],
              "candidate_available_index": 48,
              "confirmation_index": 49,
              "breakout_direction": "bearish",
              "expected_direction": "bearish",
              "subtype": "rising",
              "upper_boundary": 118.79166666666667,
              "lower_boundary": 116,
              "metrics": {
                "upper_slope": 0.20833333333333334,
                "lower_slope": 0.3333333333333333,
                "upper_relative_slope": 0.00185459940652819,
                "lower_relative_slope": 0.002967359050445104,
                "upper_intercept": 108.58333333333334,
                "lower_intercept": 99.66666666666667,
                "width_start": 6.916666666666671,
                "width_end": 3.1666666666666714,
                "convergence": 0.5421686746987948,
                "parallel_gap": 0.001112759643916914,
                "impulse": 0.09375,
                "impulse_direction": "bullish",
                "formation_bars": 30
              }
            }
          ],
          "pivots": [
            {
              "kind": "high",
              "index": 12,
              "confirmation_index": 14,
              "price": 108
            },
            {
              "kind": "low",
              "index": 16,
              "confirmation_index": 18,
              "price": 105
            },
            {
              "kind": "high",
              "index": 22,
              "confirmation_index": 24,
              "price": 113
            }
          ],
          "parameters": {
            "pivot_left": 2,
            "pivot_right": 2,
            "pivots_per_side": 3,
            "max_pattern_bars": 44,
            "max_confirmation_bars": 4,
            "impulse_lookback": 12,
            "flat_tolerance": 0.00045,
            "min_slope": 0.00022,
            "parallel_tolerance": 0.00035,
            "min_convergence": 0.18,
            "min_impulse": 0.055,
            "break_buffer": 0.001
          }
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: pattern, state, reason, event, events, pivots, parameters"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "algorithm-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a06/static/algorithm-anatomy.svg"
          },
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a06/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a06/static/calculation-ledger.svg"
          },
          {
            "file": "causal-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a06/static/causal-timeline.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a06/static/failure-boundary.svg"
          },
          {
            "file": "method-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f03-a06/static/method-comparison.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning Flow — Rising/Falling Wedge",
            "source": "flowchart LR\n    A[\"Finalized close arrives\"] --> B[\"Confirm strict pivots after right-window delay\"]\n    B --> C{\"Six alternating pivots available?\"}\n    C -->|No| S[\"SEARCHING\"]\n    C -->|Yes| D[\"Fit upper and lower boundaries\"]\n    D --> E{\"Topic geometry contract passes?\"}\n    E -->|No| R[\"REJECTED with reason\"]\n    E -->|Yes| K[\"CANDIDATE at latest pivot confirmation\"]\n    K --> F{\"Later strict buffered crossing?\"}\n    F -->|Accepted side| G[\"CONFIRMED\"]\n    F -->|Opposite side or expired| R\n    F -->|Not yet| K"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613 and https://doi.org/10.3386/w7613"
        },
        {
          "key": "S2",
          "title": "SciPy `find_peaks`",
          "author": "SciPy project",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S3",
          "title": "The Probability of Backtest Overfitting",
          "author": "David H. Bailey, Jonathan M. Borwein, Marcos López de Prado, and Qiji Jim Zhu",
          "url": "https://papers.ssrn.com/sol3/Papers.cfm?abstract_id=2326253 and https://doi.org/10.2139/ssrn.2326253"
        },
        {
          "key": "Applicability decision",
          "title": "Applicability decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/continuation-structures/rising-falling-wedge/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/continuation-structures/rising-falling-wedge/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F04-A01",
      "name": "Normalized Template Matching",
      "headline": null,
      "slug": "normalized-template-matching",
      "path": "geometric-chart-patterns/pattern-matching/normalized-template-matching",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F04",
        "family": "Pattern Matching",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/pattern-matching/normalized-template-matching",
        "entry": "match",
        "params": [
          "series",
          "template"
        ],
        "exports": [
          "match"
        ],
        "archetype": "record-transform",
        "signature": "match(series, template)"
      },
      "api": {
        "summary": "Slides a template over a series and finds the window whose shape is closest to it. Both the template and every candidate window are z-normalized with the population standard deviation first, so the match is on shape alone and is blind to level and scale.",
        "params": [
          {
            "name": "series",
            "type": "number[]",
            "required": true,
            "description": "The series to search, in order. Needs at least three finite values and must be no shorter than the template.",
            "constraints": {
              "min_length": 3,
              "finite": true
            },
            "nulls": "reject",
            "default": null
          },
          {
            "name": "template",
            "type": "number[]",
            "required": true,
            "description": "The shape being looked for. Needs at least three finite values, and cannot be constant, since a constant sequence has no z-score.",
            "constraints": {
              "min_length": 3,
              "finite": true
            },
            "nulls": "reject",
            "default": null
          }
        ],
        "returns": {
          "type": "{ template_length: number; best_start: number; best_end: number; correlation: number | null; distance: number | null; profile: Array<{ start: number; correlation: number | null; distance: number | null; eligible: boolean }>; normalization: string }",
          "description": "An object naming the winning window by `best_start` and `best_end` with its `correlation` and Euclidean `distance` in normalized space, alongside `template_length`, the full `profile` of one row per window start, and `normalization`, which is always `population-z-score-per-window`. A window that is constant is scored `eligible: false` with null `correlation` and `distance`; the winner is the eligible window of least distance, earliest start breaking ties."
        },
        "warmup": null,
        "errors": [
          {
            "when": "series or template holds fewer than three values, or any value is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "template is longer than series",
            "behaviour": "throws Error"
          },
          {
            "when": "template is constant, so its z-normalization is undefined",
            "behaviour": "throws Error"
          },
          {
            "when": "every window of series is constant, leaving nothing eligible",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * m)",
          "space": "O(n + m)"
        }
      },
      "example": {
        "origin": "derived",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "match([99.874987,100.159243,100.421014,100.350703,100.560173,100.558238], [0,1,2.5,4.5,6,5])",
        "args": [
          {
            "value": [
              99.874987,
              100.159243,
              100.421014,
              100.350703,
              100.560173,
              100.558238
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 96
            }
          },
          {
            "value": [
              0,
              1,
              2.5,
              4.5,
              6,
              5
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 12
            }
          }
        ],
        "output": {
          "template_length": 12,
          "best_start": 58,
          "best_end": 69,
          "correlation": 0.9999999999999999,
          "distance": 8.382057464382987e-15,
          "profile": [
            {
              "start": 0,
              "correlation": 0.5900738849254371,
              "distance": 3.136594771689436,
              "eligible": true
            },
            {
              "start": 1,
              "correlation": 0.3358103596358022,
              "distance": 3.9925620056225477,
              "eligible": true
            },
            {
              "start": 2,
              "correlation": -0.07196549176585781,
              "distance": 5.072195954651257,
              "eligible": true
            }
          ],
          "normalization": "population-z-score-per-window"
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: template_length, best_start, best_end, correlation, distance, profile, normalization"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "algorithm-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a01/static/algorithm-anatomy.svg"
          },
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a01/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a01/static/calculation-ledger.svg"
          },
          {
            "file": "causal-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a01/static/causal-timeline.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a01/static/failure-boundary.svg"
          },
          {
            "file": "method-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a01/static/method-comparison.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning Flow — Normalized Template Matching",
            "source": "flowchart LR\n    A[\"Validate sequence roles and clocks\"] --> B[\"Apply declared local normalization\"]\n    B --> C[\"Enumerate eligible search space\"]\n    C --> D[\"Calculate distance, path, profile, or gain\"]\n    D --> E{\"Candidate eligible?\"}\n    E -->|No| R[\"INELIGIBLE with reason\"]\n    E -->|Yes| F[\"Apply exclusion, radius, threshold, and tie rules\"]\n    F --> G[\"Return result plus complete diagnostics\"]\n    G --> H[\"Evaluate separately from financial usefulness\"]"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613 and https://doi.org/10.3386/w7613"
        },
        {
          "key": "S2",
          "title": "SciPy `find_peaks`",
          "author": "SciPy project",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S3",
          "title": "The Probability of Backtest Overfitting",
          "author": "David H. Bailey, Jonathan M. Borwein, Marcos López de Prado, and Qiji Jim Zhu",
          "url": "https://papers.ssrn.com/sol3/Papers.cfm?abstract_id=2326253 and https://doi.org/10.2139/ssrn.2326253"
        },
        {
          "key": "S4",
          "title": "UCR Suite for Time-Series Subsequence Search",
          "author": "Eamonn Keogh and the University of California, Riverside time-series group",
          "url": "https://www.cs.ucr.edu/~eamonn/UCRsuite.html"
        },
        {
          "key": "Applicability decision",
          "title": "Applicability decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pattern-matching/normalized-template-matching/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pattern-matching/normalized-template-matching/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F04-A02",
      "name": "Dynamic-Time-Warping Pattern Match",
      "headline": null,
      "slug": "dynamic-time-warping-pattern-match",
      "path": "geometric-chart-patterns/pattern-matching/dynamic-time-warping-pattern-match",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F04",
        "family": "Pattern Matching",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/pattern-matching/dynamic-time-warping-pattern-match",
        "entry": "match",
        "params": [
          "query",
          "candidate",
          "radius",
          "normalize"
        ],
        "exports": [
          "match"
        ],
        "archetype": "record-transform",
        "signature": "match(query, candidate, radius, normalize)"
      },
      "api": {
        "summary": "Measures how far a query is from a candidate under dynamic time warping, which lets the two series stretch against each other in time instead of comparing them bar for bar. It returns the distance together with the warping path and the full cost matrix that produced it.",
        "params": [
          {
            "name": "query",
            "type": "number[]",
            "required": true,
            "description": "The reference series. Needs at least two finite values.",
            "constraints": {
              "min_length": 2,
              "finite": true
            },
            "nulls": "reject",
            "default": null
          },
          {
            "name": "candidate",
            "type": "number[]",
            "required": true,
            "description": "The series being compared against the query. Needs at least two finite values; it does not have to be the same length.",
            "constraints": {
              "min_length": 2,
              "finite": true
            },
            "nulls": "reject",
            "default": null
          },
          {
            "name": "radius",
            "type": "number",
            "required": false,
            "description": "Sakoe-Chiba band half-width, in bars. Defaults to the longer of the two series, which leaves the warping path unconstrained. Must be an integer no smaller than the length difference.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "normalize",
            "type": "boolean",
            "required": false,
            "description": "Whether to z-normalize both inputs before warping, which compares shape rather than level. It is passed after the optional `radius` argument, the Sakoe-Chiba band half-width, which defaults to the length of the longer input and so leaves the path unconstrained.",
            "constraints": null,
            "nulls": null,
            "default": true
          }
        ],
        "returns": {
          "type": "{ distance: number; path_rms: number; path_length: number; path: number[][]; radius: number; normalized: boolean; cost_matrix: Array<Array<number | null>> }",
          "description": "An object holding `distance`, the square root of the accumulated squared cost, `path_rms`, the root of that same total divided by the number of aligned pairs, and `path_length`, that count. `path` lists the aligned index pairs from start to end, `radius` and `normalized` echo what was applied, and `cost_matrix` gives the accumulated cost per cell with cells outside the band as null."
        },
        "warmup": null,
        "errors": [
          {
            "when": "query or candidate holds fewer than two values, or any value is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "radius is not an integer, or is smaller than the difference in length between the two inputs",
            "behaviour": "throws Error"
          },
          {
            "when": "normalization is on and either input is constant",
            "behaviour": "throws Error"
          },
          {
            "when": "the band admits no warping path reaching the final cell",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * m)",
          "space": "O(n * m)"
        }
      },
      "example": {
        "origin": "derived",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "match([0,0.5,1.6,3.2,5,6.1], [0,0.2,0.7,1.5,2.7,4.2], 5)",
        "args": [
          {
            "value": [
              0,
              0.5,
              1.6,
              3.2,
              5,
              6.1
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 16
            }
          },
          {
            "value": [
              0,
              0.2,
              0.7,
              1.5,
              2.7,
              4.2
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 20
            }
          },
          {
            "value": 5,
            "elided": null
          }
        ],
        "output": {
          "distance": 0.8828777062798496,
          "path_rms": 0.19265971040078095,
          "path_length": 21,
          "path": [
            [
              0,
              0
            ],
            [
              1,
              1
            ],
            [
              1,
              2
            ]
          ],
          "radius": 5,
          "normalized": true,
          "cost_matrix": [
            [
              0.005392023895877613,
              0.036191498358618325,
              0.22166492791858747,
              0.9254782337120473,
              3.0318664648048,
              7.946270727248203
            ],
            [
              0.03942879310652065,
              0.012185604161087042,
              0.04202654074278329,
              0.3796047955087834,
              1.8038541385002964,
              5.641239716500235
            ],
            [
              0.6048075127728977,
              0.4344897279549777,
              0.16795856695383304,
              0.04221119401162229,
              0.4340784939436583,
              2.370346476931225
            ]
          ]
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: distance, path_rms, path_length, path, radius, normalized, cost_matrix"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "algorithm-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a02/static/algorithm-anatomy.svg"
          },
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a02/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a02/static/calculation-ledger.svg"
          },
          {
            "file": "causal-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a02/static/causal-timeline.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a02/static/failure-boundary.svg"
          },
          {
            "file": "method-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a02/static/method-comparison.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning Flow — Dynamic-Time-Warping Pattern Match",
            "source": "flowchart LR\n    A[\"Validate sequence roles and clocks\"] --> B[\"Apply declared local normalization\"]\n    B --> C[\"Enumerate eligible search space\"]\n    C --> D[\"Calculate distance, path, profile, or gain\"]\n    D --> E{\"Candidate eligible?\"}\n    E -->|No| R[\"INELIGIBLE with reason\"]\n    E -->|Yes| F[\"Apply exclusion, radius, threshold, and tie rules\"]\n    F --> G[\"Return result plus complete diagnostics\"]\n    G --> H[\"Evaluate separately from financial usefulness\"]"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613 and https://doi.org/10.3386/w7613"
        },
        {
          "key": "S2",
          "title": "SciPy `find_peaks`",
          "author": "SciPy project",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S3",
          "title": "The Probability of Backtest Overfitting",
          "author": "David H. Bailey, Jonathan M. Borwein, Marcos López de Prado, and Qiji Jim Zhu",
          "url": "https://papers.ssrn.com/sol3/Papers.cfm?abstract_id=2326253 and https://doi.org/10.2139/ssrn.2326253"
        },
        {
          "key": "S4",
          "title": "Dynamic Programming Algorithm Optimization for Spoken Word Recognition",
          "author": "Hiroaki Sakoe and Seibi Chiba",
          "url": "https://doi.org/10.1109/TASSP.1978.1163055 and https://jeffe.cs.illinois.edu/teaching/compgeom/2022/refs/Sakoe-Chiba-DTW.pdf"
        },
        {
          "key": "Applicability decision",
          "title": "Applicability decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pattern-matching/dynamic-time-warping-pattern-match/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pattern-matching/dynamic-time-warping-pattern-match/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F04-A03",
      "name": "Matrix-Profile Motif Discovery",
      "headline": null,
      "slug": "matrix-profile-motif-discovery",
      "path": "geometric-chart-patterns/pattern-matching/matrix-profile-motif-discovery",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F04",
        "family": "Pattern Matching",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/pattern-matching/matrix-profile-motif-discovery",
        "entry": "discover",
        "params": [
          "series",
          "window",
          "exclusionZone"
        ],
        "exports": [
          "discover"
        ],
        "archetype": "record-transform",
        "signature": "discover(series, window, exclusionZone)"
      },
      "api": {
        "summary": "Computes the matrix profile of a series for a given subsequence length - for each window, the distance to its nearest non-overlapping neighbour - and reports the closest pair, the motif. Every subsequence is z-normalized first, so repeated shapes are found regardless of level.",
        "params": [
          {
            "name": "series",
            "type": "number[]",
            "required": true,
            "description": "The series to search, in order. Needs at least six finite values.",
            "constraints": {
              "min_length": 6,
              "finite": true
            },
            "nulls": "reject",
            "default": null
          },
          {
            "name": "window",
            "type": "number",
            "required": true,
            "description": "The subsequence length, an integer from 3 up to half the series length. It also sets the default exclusion zone, `ceil(window / 2)`, which is how many index positions on each side count as trivially overlapping and are skipped; the optional third argument overrides that zone.",
            "constraints": {
              "integer": true,
              "min": 3
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "exclusionZone",
            "type": "number",
            "required": false,
            "description": "Bars either side of a position excluded as a trivial self-match. Defaults to `ceil(window / 2)`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ window: number; exclusion_zone: number; profile: Array<number | null>; profile_index: Array<number | null>; motif_pair: number[]; motif_distance: number; normalization: string }",
          "description": "An object echoing `window` and the resolved `exclusion_zone`, with `profile` giving each subsequence's nearest-neighbour distance and `profile_index` the index of that neighbour, both null where a constant subsequence made the comparison impossible. `motif_pair` is the closest admissible pair of start indexes in ascending order, `motif_distance` their distance, and `normalization` is always `population-z-score-per-subsequence`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "series holds fewer than six values, or any value is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "window is not an integer, is below 3, or exceeds half the series length",
            "behaviour": "throws Error"
          },
          {
            "when": "the exclusion zone override is not a nonnegative integer",
            "behaviour": "throws Error"
          },
          {
            "when": "no pair of subsequences survives the constant and exclusion-zone filters",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n^2 * window)",
          "space": "O(n * window)"
        }
      },
      "example": {
        "origin": "derived",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "discover([99.881237,100.116364,100.33311,100.355799,100.226037,100.187182], 16, null)",
        "args": [
          {
            "value": [
              99.881237,
              100.116364,
              100.33311,
              100.355799,
              100.226037,
              100.187182
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": 16,
            "elided": null
          },
          {
            "value": null,
            "elided": null
          }
        ],
        "output": {
          "window": 16,
          "exclusion_zone": 8,
          "profile": [
            1.442017209318879,
            1.4259996875986038,
            1.5353435003673506,
            1.6155150461182326,
            1.885889075174815,
            3.93842156909414
          ],
          "profile_index": [
            12,
            13,
            14,
            15,
            15,
            53
          ],
          "motif_pair": [
            20,
            72
          ],
          "motif_distance": 3.6400104112014625e-15,
          "normalization": "population-z-score-per-subsequence"
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: window, exclusion_zone, profile, profile_index, motif_pair, motif_distance, normalization"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "algorithm-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a03/static/algorithm-anatomy.svg"
          },
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a03/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a03/static/calculation-ledger.svg"
          },
          {
            "file": "causal-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a03/static/causal-timeline.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a03/static/failure-boundary.svg"
          },
          {
            "file": "method-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a03/static/method-comparison.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning Flow — Matrix-Profile Motif Discovery",
            "source": "flowchart LR\n    A[\"Validate sequence roles and clocks\"] --> B[\"Apply declared local normalization\"]\n    B --> C[\"Enumerate eligible search space\"]\n    C --> D[\"Calculate distance, path, profile, or gain\"]\n    D --> E{\"Candidate eligible?\"}\n    E -->|No| R[\"INELIGIBLE with reason\"]\n    E -->|Yes| F[\"Apply exclusion, radius, threshold, and tie rules\"]\n    F --> G[\"Return result plus complete diagnostics\"]\n    G --> H[\"Evaluate separately from financial usefulness\"]"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613 and https://doi.org/10.3386/w7613"
        },
        {
          "key": "S2",
          "title": "SciPy `find_peaks`",
          "author": "SciPy project",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S3",
          "title": "The Probability of Backtest Overfitting",
          "author": "David H. Bailey, Jonathan M. Borwein, Marcos López de Prado, and Qiji Jim Zhu",
          "url": "https://papers.ssrn.com/sol3/Papers.cfm?abstract_id=2326253 and https://doi.org/10.2139/ssrn.2326253"
        },
        {
          "key": "S4",
          "title": "Matrix Profile I: All Pairs Similarity Joins for Time Series",
          "author": "Chin-Chia Michael Yeh, Yan Zhu, Liudmila Ulanova, Nurjahan Begum, Yifei Ding, Hoang Anh Dau, Diego Furtado Silva, Abdullah Mueen, and Eamonn Keogh",
          "url": "https://doi.org/10.1109/ICDM.2016.0179 and https://www.cs.ucr.edu/~eamonn/PID4481997_extend_Matrix%20Profile_I.pdf"
        },
        {
          "key": "Applicability decision",
          "title": "Applicability decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pattern-matching/matrix-profile-motif-discovery/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pattern-matching/matrix-profile-motif-discovery/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F04-A04",
      "name": "Shapelet Pattern Classifier",
      "headline": null,
      "slug": "shapelet-pattern-classifier",
      "path": "geometric-chart-patterns/pattern-matching/shapelet-pattern-classifier",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F04",
        "family": "Pattern Matching",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/pattern-matching/shapelet-pattern-classifier",
        "entry": "classify",
        "params": [
          "series",
          "shapelet",
          "threshold",
          "belowLabel"
        ],
        "exports": [
          "train",
          "classify",
          "distance"
        ],
        "archetype": "row-classify",
        "signature": "classify(series, shapelet, threshold, belowLabel)"
      },
      "api": {
        "summary": "Labels a series by how closely its best-matching window resembles a shapelet. It slides the z-normalized shapelet across the series, takes the smallest Euclidean distance, and turns that into a class by comparing it against a threshold.",
        "params": [
          {
            "name": "series",
            "type": "number[]",
            "required": true,
            "description": "The series being classified, in order. Needs at least three finite values and must be no shorter than the shapelet.",
            "constraints": {
              "min_length": 3,
              "finite": true
            },
            "nulls": "reject",
            "default": null
          },
          {
            "name": "shapelet",
            "type": "number[]",
            "required": true,
            "description": "The discriminative subsequence to look for. Needs at least two finite values and cannot be constant.",
            "constraints": {
              "min_length": 2,
              "finite": true
            },
            "nulls": "reject",
            "default": null
          },
          {
            "name": "threshold",
            "type": "number",
            "required": true,
            "description": "The distance at or below which the series counts as a match, normally the cut point learned by `train`. Must be finite and nonnegative.",
            "constraints": {
              "min": 0,
              "finite": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "belowLabel",
            "type": "boolean",
            "required": false,
            "description": "The class assigned to series at or below the threshold. Series above it get the opposite label.",
            "constraints": null,
            "nulls": null,
            "default": true
          }
        ],
        "returns": {
          "type": "{ distance: number; best_start: number; profile: Array<number | null>; threshold: number; matched: boolean; predicted_label: boolean }",
          "description": "An object giving the winning `distance` and the `best_start` index it was found at, the full `profile` of one distance per window start with null where a window was constant, the `threshold` used, `matched` for whether the distance fell at or below it, and the resulting `predicted_label`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "threshold is negative or not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "series holds fewer than three values or shapelet fewer than two, or any value is not a finite number",
            "behaviour": "throws Error"
          },
          {
            "when": "shapelet is longer than series",
            "behaviour": "throws Error"
          },
          {
            "when": "shapelet is constant, so its z-normalization is undefined",
            "behaviour": "throws Error"
          },
          {
            "when": "every window of series is constant, leaving no distance to take",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n * m)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "derived",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "classify([99.870299,100.065403,100.108942,100.094882,100.306776,100.33253], [0,1,3,6,8,6], 0.6024320464983021)",
        "args": [
          {
            "value": [
              99.870299,
              100.065403,
              100.108942,
              100.094882,
              100.306776,
              100.33253
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 48
            }
          },
          {
            "value": [
              0,
              1,
              3,
              6,
              8,
              6
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 10
            }
          },
          {
            "value": 0.6024320464983021,
            "elided": null
          }
        ],
        "output": {
          "distance": 8.81773713357542e-15,
          "best_start": 20,
          "profile": [
            4.4429515304009595,
            4.021249553691412,
            3.1883762365539186,
            2.4542268418798887,
            2.742051350159151,
            2.8389981766588135
          ],
          "threshold": 0.6024320464983021,
          "matched": true,
          "predicted_label": true
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: distance, best_start, profile, threshold, matched, predicted_label"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "algorithm-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a04/static/algorithm-anatomy.svg"
          },
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a04/static/article-hero.svg"
          },
          {
            "file": "calculation-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a04/static/calculation-ledger.svg"
          },
          {
            "file": "causal-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a04/static/causal-timeline.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a04/static/failure-boundary.svg"
          },
          {
            "file": "method-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f04-a04/static/method-comparison.svg"
          }
        ],
        "mermaid": [
          {
            "file": "reasoning-flow.md",
            "caption": "Reasoning Flow — Shapelet Pattern Classifier",
            "source": "flowchart LR\n    A[\"Validate sequence roles and clocks\"] --> B[\"Apply declared local normalization\"]\n    B --> C[\"Enumerate eligible search space\"]\n    C --> D[\"Calculate distance, path, profile, or gain\"]\n    D --> E{\"Candidate eligible?\"}\n    E -->|No| R[\"INELIGIBLE with reason\"]\n    E -->|Yes| F[\"Apply exclusion, radius, threshold, and tie rules\"]\n    F --> G[\"Return result plus complete diagnostics\"]\n    G --> H[\"Evaluate separately from financial usefulness\"]"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613 and https://doi.org/10.3386/w7613"
        },
        {
          "key": "S2",
          "title": "SciPy `find_peaks`",
          "author": "SciPy project",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S3",
          "title": "The Probability of Backtest Overfitting",
          "author": "David H. Bailey, Jonathan M. Borwein, Marcos López de Prado, and Qiji Jim Zhu",
          "url": "https://papers.ssrn.com/sol3/Papers.cfm?abstract_id=2326253 and https://doi.org/10.2139/ssrn.2326253"
        },
        {
          "key": "S4",
          "title": "Time Series Shapelets: A New Primitive for Data Mining",
          "author": "Lexiang Ye and Eamonn Keogh",
          "url": "https://doi.org/10.1145/1557019.1557122 and https://www.cs.ucr.edu/~lexiangy/Shapelet/Shapelet.pdf"
        },
        {
          "key": "Applicability decision",
          "title": "Applicability decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pattern-matching/shapelet-pattern-classifier/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pattern-matching/shapelet-pattern-classifier/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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f05-a01/static/map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Price–Indicator Pivot Alignment calculation flow",
            "source": "flowchart LR\n    P[\"Confirmed price pivot i\"] --> K{\"Same kind?\"}\n    I[\"Confirmed indicator candidates\"] --> K\n    K -->|No| X[\"Reject candidate\"]\n    K -->|Yes| L{\"Absolute event lag ≤ L?\"}\n    L -->|No| X\n    L -->|Yes| N[\"Choose minimum lag\"]\n    N --> T[\"Tie: earlier event\"]\n    T --> U[\"Mark indicator pivot used\"]\n    U --> M[\"Knowledge = max confirmations\"]\n    M --> O[\"Auditable alignment\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f05-a02/static/map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Regular Bullish/Bearish Divergence Detection calculation flow",
            "source": "flowchart LR\n    A[\"Two aligned lows or highs\"] --> P[\"Compute fractional ΔP\"]\n    A --> I[\"Compute adapted ΔI\"]\n    P --> B{\"Low pair: ΔP ≤ -τP and ΔI ≥ τI?\"}\n    I --> B\n    B -->|Yes| U[\"Regular bullish\"]\n    B -->|No| H{\"High pair: ΔP ≥ τP and ΔI ≤ -τI?\"}\n    H -->|Yes| D[\"Regular bearish\"]\n    H -->|No| N[\"No regular event\"]\n    U --> K[\"Publish at later knowledge time\"]\n    D --> K"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f05-a03/static/map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Hidden Bullish/Bearish Divergence Detection calculation flow",
            "source": "flowchart LR\n    A[\"Aligned same-kind pivot pair\"] --> P{\"Price preserves structure?\"}\n    P -->|Higher low| I{\"Indicator makes lower low?\"}\n    I -->|Yes, thresholds pass| B[\"Hidden bullish\"]\n    P -->|Lower high| J{\"Indicator makes higher high?\"}\n    J -->|Yes, thresholds pass| S[\"Hidden bearish\"]\n    I -->|No| N[\"No hidden event\"]\n    J -->|No| N\n    B --> C[\"Continuation-context geometry only\"]\n    S --> C"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f05-a04/static/map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Multi-Indicator Divergence Adapters calculation flow",
            "source": "flowchart LR\n    R[\"Raw pivot + source identity\"] --> V{\"Finite value, scale > 0, polarity declared?\"}\n    V -->|No| X[\"Invalid adapter\"]\n    V -->|Yes| N[\"I* = polarity × raw / scale\"]\n    N --> P[\"Preserve raw value\"]\n    N --> F[\"Preserve indicator family\"]\n    N --> K[\"Preserve confirmation time\"]\n    P --> O[\"Auditable adapter record\"]\n    F --> O\n    K --> O\n    O --> W[\"Common interface, not equivalent evidence\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f05-a05/static/map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Divergence Strength and Quality Scoring calculation flow",
            "source": "flowchart LR\n    E[\"Valid divergence event\"] --> P[\"Price geometry P\"]\n    E --> I[\"Indicator geometry I\"]\n    E --> R[\"Prominence R\"]\n    E --> A[\"Alignment A\"]\n    E --> S[\"Separation S\"]\n    P --> C[\"Clip each component to 0–1\"]\n    I --> C\n    R --> C\n    A --> C\n    S --> C\n    C --> Q[\"Weighted Q on 0–100 scale\"]\n    Q --> B[\"Definition strength, not probability\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f05-a06/static/map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Divergence Confirmation and Invalidation State Machine calculation flow",
            "source": "stateDiagram-v2\n    [*] --> Searching\n    Searching --> Candidate: geometry knowable\n    Candidate --> Confirmed: finalized close strictly breaks structure\n    Candidate --> Invalidated: finalized close strictly breaches pivot buffer\n    Candidate --> Expired: deadline arrives first\n    Candidate --> Candidate: equality or no crossing\n    Confirmed --> [*]\n    Invalidated --> [*]\n    Expired --> [*]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f05-a07/static/map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Multi-Indicator Divergence Confluence calculation flow",
            "source": "flowchart LR\n    E[\"Detected events\"] --> G[\"Group by exact type + price pair\"]\n    G --> M{\"Minimum indicator count met?\"}\n    M -->|No| N[\"Insufficient confluence\"]\n    M -->|Yes| Q[\"Weighted quality\"]\n    M --> W[\"Weight coverage\"]\n    M --> F[\"Family coverage\"]\n    Q --> C[\"Confluence score\"]\n    W --> C\n    F --> C\n    C --> K[\"Knowledge = latest member confirmation\"]\n    K --> B[\"Agreement, not independent evidence\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f05-a08/static/map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Market-Wide Divergence Scanner and Ranking calculation flow",
            "source": "flowchart LR\n    U[\"As-of universe snapshot\"] --> A{\"eligible and available_index ≤ as_of?\"}\n    A -->|No| X[\"Exclude with reason\"]\n    A -->|Yes| V{\"Supported state and valid components?\"}\n    V -->|No| X\n    V -->|Yes| R[\"Compute rank components\"]\n    R --> S[\"Sort score descending\"]\n    S --> T[\"Exact tie: symbol ascending\"]\n    T --> O[\"Review queue\"]\n    O --> B[\"Triage priority, not order or forecast\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a01/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Price-by-Volume Profile Construction calculation flow",
            "source": "flowchart LR\n    S1[\"Validate ordered unique finalized trades against windo\"]\n    S2[\"Convert each price to an integer tick index\"]\n    S3[\"Map the tick index to one halfopen bin\"]\n    S4[\"Accumulate positive trade volume and retain emptyprint\"]\n    S5[\"Sort rows and reconcile shares to eligible total volum\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"a price exactly on a bin boundary enters the upper halfope\"}\n    D --> O[\"rows + diagnostics\"]\n    O --> A[\"Audit: The output is a deterministic function of validated inputs\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a02/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Point of Control, Value Area, HVN, and LVN Detection calculation flow",
            "source": "flowchart LR\n    S1[\"Validate a sorted contiguous completed profile\"]\n    S2[\"Select the maximumvolume row with midpoint then lowerp\"]\n    S3[\"Expand from POC toward the larger adjacent row and cho\"]\n    S4[\"Include the row that first reaches or exceeds target v\"]\n    S5[\"Detect thresholded interior nodes and return the expan\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"value area includes the selected adjacent row that first r\"}\n    D --> O[\"poc_price + diagnostics\"]\n    O --> A[\"Audit: The output is a deterministic function of validated inputs\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a03/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Fibonacci Retracement and Extension Projection calculation flow",
            "source": "flowchart LR\n    S1[\"Validate distinct leg anchors and positive tick size\"]\n    S2[\"Resolve leg direction and absolute magnitude\"]\n    S3[\"Project each declared retracement from B\"]\n    S4[\"Project each declared extension from C\"]\n    S5[\"Snap raw prices half away from zero and retain both va\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"raw projected prices are snapped to the nearest declared i\"}\n    D --> O[\"retracement_levels + diagnostics\"]\n    O --> A[\"Audit: The output is a deterministic function of validated inputs\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a04/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Psychological Round-Number Level Generation calculation flow",
            "source": "flowchart LR\n    S1[\"Validate current price ordered bounds tick size and ba\"]\n    S2[\"Convert bounds and base unit to integer ticks\"]\n    S3[\"Enumerate inrange multiples of the base unit\"]\n    S4[\"Classify each multiple and calculate pricebps distance\"]\n    S5[\"Choose distance then salience then lowerprice determin\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"the base unit must itself be an integer number of ticks\"}\n    D --> O[\"closest_level + diagnostics\"]\n    O --> A[\"Audit: The output is a deterministic function of validated inputs\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a05/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Multi-Source Support/Resistance Zone Fusion calculation flow",
            "source": "flowchart LR\n    S1[\"Validate candidate IDs source families prices weights \"]\n    S2[\"Sort candidates deterministically by price source and \"]\n    S3[\"Start a new cluster whenever diameter would exceed twi\"]\n    S4[\"Compute bounds members sources and weighted or unweigh\"]\n    S5[\"Apply the distinctsource minimum and rank eligible zon\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"cluster diameter may not exceed twice the fusion tolerance\"}\n    D --> O[\"zones + diagnostics\"]\n    O --> A[\"Audit: The output is a deterministic function of validated inputs\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a06/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Support/Resistance Zone Strength and Decay Scoring calculation flow",
            "source": "flowchart LR\n    S1[\"Validate normalized source touch age halflife and brea\"]\n    S2[\"Decay each touch by its own age\"]\n    S3[\"Cap rejection magnitude at the ATR target\"]\n    S4[\"Calculate source touch rejection durability and break \"]\n    S5[\"Clip to 0100 assign grade and return the full ledger\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"each rejection contribution is capped at its declared ATR \"}\n    D --> O[\"score + diagnostics\"]\n    O --> A[\"Audit: The output is a deterministic function of validated inputs\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a07/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Support/Resistance Role-Reversal State Machine calculation flow",
            "source": "flowchart LR\n    S1[\"Validate zone buffer close count initial role and orde\"]\n    S2[\"Count only strict buffered closes on the break side\"]\n    S3[\"Enter the rolespecific awaitingretest state\"]\n    S4[\"Record inclusive zone contact without confirming yet\"]\n    S5[\"Confirm on a hold outside or invalidate on a farside c\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"a close exactly on a buffered threshold does not count as \"}\n    D --> O[\"final_role + diagnostics\"]\n    O --> A[\"Audit: The output is a deterministic function of validated inputs\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a08/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Breakout and Retest Detection calculation flow",
            "source": "flowchart LR\n    S1[\"Validate zone direction buffers counts expiry and OHLC\"]\n    S2[\"Count consecutive closes strictly beyond the breakout \"]\n    S3[\"Record breakoutindex and arm the retest window\"]\n    S4[\"Detect inclusive OHLC contact with the tolerance band\"]\n    S5[\"Confirm away from the zone fail through the far side o\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"buffered close comparisons are strict while OHLC contact w\"}\n    D --> O[\"confirmed + diagnostics\"]\n    O --> A[\"Audit: The output is a deterministic function of validated inputs\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a09/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Market-Wide Zone-Proximity Scanner and Ranking calculation flow",
            "source": "flowchart LR\n    S1[\"Validate asof unique instrument IDs positive prices zo\"]\n    S2[\"Compute zero distance inside each zone and edge distan\"]\n    S3[\"Convert distance to bps and apply the eligibility radi\"]\n    S4[\"Decay freshness and calculate the threecomponent score\"]\n    S5[\"Sort by score distance and instrument ID while retaini\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"records observed after asof are invalid rather than silent\"}\n    D --> O[\"ranked + diagnostics\"]\n    O --> A[\"Audit: The output is a deterministic function of validated inputs\"]"
          }
        ]
      },
      "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": "D08-F07-A01",
      "name": "Highest-High and Lowest-Low Primitives",
      "headline": null,
      "slug": "highest-high-and-lowest-low-primitives",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/highest-high-and-lowest-low-primitives",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/highest-high-and-lowest-low-primitives",
        "entry": "highestHighAndLowestLowPrimitives",
        "params": [
          "input"
        ],
        "exports": [
          "highestHighAndLowestLowPrimitives"
        ],
        "archetype": "record-transform",
        "signature": "highestHighAndLowestLowPrimitives(input)"
      },
      "api": {
        "summary": "The two rolling extremes every breakout rule is built on: the highest high and lowest low over a window of `period` bars ending at, and including, the current bar.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.period` (default `20`, integer of at least 2) sets the window length.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `highest` and `lowest`. The warm-up is `period - 1` bars because the window includes the current bar, so with the default `ready_at` is 19 - one bar earlier than the breakout topics that exclude it."
        },
        "warmup": {
          "count": "period - 1 bars (19 by default)",
          "value": "null",
          "note": "The window spans indices i-period+1 through i inclusive, so index `period - 1` is the first with a full window."
        },
        "errors": [
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `high` or `low` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n × period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "highestHighAndLowestLowPrimitives({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A01",
          "title": "Highest-High and Lowest-Low Primitives",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "highest": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "lowest": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "highest": 109.83623682,
            "lowest": 98.68874251
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a01/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a01/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a01/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Highest-High and Lowest-Low Primitives calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Highest-High and Lowest-Low Primitives convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Highest-High and Lowest-Low Primitives readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/highest-high-and-lowest-low-primitives/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/highest-high-and-lowest-low-primitives/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A02",
      "name": "Single-Asset New-High/New-Low Signal",
      "headline": null,
      "slug": "single-asset-new-high-new-low-signal",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/single-asset-new-high-new-low-signal",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/single-asset-new-high-new-low-signal",
        "entry": "singleAssetNewHighNewLowSignal",
        "params": [
          "input"
        ],
        "exports": [
          "singleAssetNewHighNewLowSignal"
        ],
        "archetype": "record-transform",
        "signature": "singleAssetNewHighNewLowSignal(input)"
      },
      "api": {
        "summary": "Flags whether a single instrument's close has cleared the highest high or undercut the lowest low of the preceding `period` bars. The channel excludes the current bar, so the comparison is against a level that was already known.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.period` (default `20`, integer of at least 2) sets the lookback channel.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `upper`, `lower`, and the booleans `new_high` and `new_low`. The warm-up is `period` bars, so with the default `ready_at` is 20."
        },
        "warmup": {
          "count": "period bars (20 by default)",
          "value": "null",
          "note": "The channel is built from indices i-period through i-1, so index `period` is the first bar with a complete prior window; the two boolean series turn non-null on the same bar as the two level series."
        },
        "errors": [
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "bars are not strictly increasing by `timestamp`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n × period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "singleAssetNewHighNewLowSignal({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A02",
          "title": "Single-Asset New-High/New-Low Signal",
          "state": "calculated",
          "ready": true,
          "ready_at": 20,
          "series": {
            "upper": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "new_high": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "new_low": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "upper": 109.83623682,
            "lower": 99.69159419,
            "new_high": false,
            "new_low": false
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a02/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a02/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a02/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Single-Asset New-High/New-Low Signal calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Single-Asset New-High/New-Low Signal convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Single-Asset New-High/New-Low Signal readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/single-asset-new-high-new-low-signal/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/single-asset-new-high-new-low-signal/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A03",
      "name": "Breakout Strength",
      "headline": null,
      "slug": "breakout-strength",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/breakout-strength",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/breakout-strength",
        "entry": "breakoutStrength",
        "params": [
          "input"
        ],
        "exports": [
          "breakoutStrength"
        ],
        "archetype": "record-transform",
        "signature": "breakoutStrength(input)"
      },
      "api": {
        "summary": "Expresses how far a close sits beyond its Donchian channel in units of ATR, so a two-tick break in a quiet market and a two-tick break in a violent one do not score the same. Values are negative while price is inside the channel.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.period` (default `20`, integer of at least 2) sets both the channel lookback and the ATR length.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `up_strength` - `(close - upper) / ATR` - and `down_strength` - `(lower - close) / ATR`. The channel levels themselves are not emitted. The warm-up is `period` bars, so with the default `ready_at` is 20; either series is additionally null on any bar where the ATR is zero."
        },
        "warmup": {
          "count": "period bars (20 by default)",
          "value": "null",
          "note": "The ATR seed completes at index `period - 1` but the channel needs a full prior window, so the binding constraint is index `period`."
        },
        "errors": [
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `high`, `low`, or `close` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n × period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "breakoutStrength({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A03",
          "title": "Breakout Strength",
          "state": "calculated",
          "ready": true,
          "ready_at": 20,
          "series": {
            "up_strength": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "down_strength": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "up_strength": -3.054182842170858,
            "down_strength": -0.09282216777684109
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a03/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a03/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a03/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Breakout Strength calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Breakout Strength convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Breakout Strength readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/breakout-strength/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/breakout-strength/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A04",
      "name": "Donchian Breakout",
      "headline": null,
      "slug": "donchian-breakout",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/donchian-breakout",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/donchian-breakout",
        "entry": "donchianBreakout",
        "params": [
          "input"
        ],
        "exports": [
          "donchianBreakout"
        ],
        "archetype": "record-transform",
        "signature": "donchianBreakout(input)"
      },
      "api": {
        "summary": "The Donchian channel over the preceding `period` bars plus the two breakout booleans it implies. This shares a byte-identical implementation with the single-asset new-high/new-low signal.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.period` (default `20`, integer of at least 2) sets the channel lookback.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `upper`, `lower`, `new_high` and `new_low`. The warm-up is `period` bars because the channel excludes the current bar, so with the default `ready_at` is 20."
        },
        "warmup": {
          "count": "period bars (20 by default)",
          "value": "null",
          "note": "The channel spans indices i-period through i-1, so index `period` is the first bar that has one."
        },
        "errors": [
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty or is not an array",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n × period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "donchianBreakout({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A04",
          "title": "Donchian Breakout",
          "state": "calculated",
          "ready": true,
          "ready_at": 20,
          "series": {
            "upper": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "lower": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "new_high": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "new_low": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "upper": 109.83623682,
            "lower": 99.69159419,
            "new_high": false,
            "new_low": false
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a04/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a04/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a04/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Donchian Breakout calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Donchian Breakout convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Donchian Breakout readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/donchian-breakout/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/donchian-breakout/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A05",
      "name": "Opening Range Breakout",
      "headline": null,
      "slug": "opening-range-breakout",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/opening-range-breakout",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/opening-range-breakout",
        "entry": "openingRangeBreakout",
        "params": [
          "input"
        ],
        "exports": [
          "openingRangeBreakout"
        ],
        "archetype": "record-transform",
        "signature": "openingRangeBreakout(input)"
      },
      "api": {
        "summary": "Fixes the high and low of the session's first `opening_bars` bars and then tests every later close against that frozen range. Unlike the rolling breakout topics the level never moves once the opening range is set.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.opening_bars` (default `5`, integer of at least 1) sets how many leading bars form the range; `period` (default `20`, integer of at least 2) is validated by the family but unused here.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `upper`, `lower`, `up_break` and `down_break`. The warm-up is `opening_bars` bars, so with the default `ready_at` is 5; `upper` and `lower` are then constant for the rest of the series."
        },
        "warmup": {
          "count": "opening_bars bars (5 by default)",
          "value": "null",
          "note": "Indices 0 through `opening_bars - 1` are the range itself and stay null in all four series; emission starts at index `opening_bars`."
        },
        "errors": [
          {
            "when": "`opening_bars` is supplied as a non-integer or as a value below 1",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `high` or `low` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n × opening_bars)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "openingRangeBreakout({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A05",
          "title": "Opening Range Breakout",
          "state": "calculated",
          "ready": true,
          "ready_at": 5,
          "series": {
            "upper": [
              null,
              null,
              null,
              null,
              null,
              105.01857496
            ],
            "lower": [
              null,
              null,
              null,
              null,
              null,
              98.695
            ],
            "up_break": [
              null,
              null,
              null,
              null,
              null,
              false
            ],
            "down_break": [
              null,
              null,
              null,
              null,
              null,
              false
            ]
          },
          "latest": {
            "upper": 105.01857496,
            "lower": 98.695,
            "up_break": false,
            "down_break": false
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a05/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a05/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a05/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Opening Range Breakout calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Opening Range Breakout convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Opening Range Breakout readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/opening-range-breakout/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/opening-range-breakout/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A06",
      "name": "Price Compression Index",
      "headline": null,
      "slug": "price-compression-index",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/price-compression-index",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/price-compression-index",
        "entry": "priceCompressionIndex",
        "params": [
          "input"
        ],
        "exports": [
          "priceCompressionIndex"
        ],
        "archetype": "record-transform",
        "signature": "priceCompressionIndex(input)"
      },
      "api": {
        "summary": "Compares short-horizon volatility to long-horizon volatility as `100 × ATR(short_period) / ATR(long_period)`. Readings well under 100 mark a market whose recent ranges have compressed against its own baseline.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.short_period` (default `5`, integer of at least 2) and `parameters.long_period` (default `20`, integer of at least 6) set the two ATR lengths; `period` (default `20`) is validated by the family but unused here.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key. The warm-up is `long_period - 1` bars, since the slower Wilder ATR seeds last, so with the defaults `ready_at` is 19; `value` is also null on any bar where the long ATR is zero."
        },
        "warmup": {
          "count": "long_period - 1 bars (19 by default)",
          "value": "null",
          "note": "Both ATRs seed on `period` true-range observations starting at index 0, so the longer one determines the first non-null at index `long_period - 1`."
        },
        "errors": [
          {
            "when": "`long_period` is supplied as a non-integer or as a value below 6",
            "behaviour": "throws Error"
          },
          {
            "when": "`short_period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "priceCompressionIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A06",
          "title": "Price Compression Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 103.23357388295663
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a06/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a06/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a06/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a06/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Price Compression Index calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Price Compression Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Price Compression Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/price-compression-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/price-compression-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A07",
      "name": "Range Expansion Index",
      "headline": null,
      "slug": "range-expansion-index",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/range-expansion-index",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/range-expansion-index",
        "entry": "rangeExpansionIndex",
        "params": [
          "input"
        ],
        "exports": [
          "rangeExpansionIndex"
        ],
        "archetype": "record-transform",
        "signature": "rangeExpansionIndex(input)"
      },
      "api": {
        "summary": "Scores directional conviction as the signed sum of close-to-close changes over `period` bars divided by the sum of their absolute values, scaled to ±100. It is the net move as a percentage of the distance actually travelled.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.period` (default `20`, integer of at least 2) sets the summation window.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key. The warm-up is `period` bars, because the first close-to-close change is undefined at index 0 and the window needs `period` of them, so with the default `ready_at` is 20; `value` is also null on any window whose absolute changes sum to zero."
        },
        "warmup": {
          "count": "period bars (20 by default)",
          "value": "null",
          "note": "The change series is null at index 0 and the rolling sum refuses any window containing a null, so the first complete window ends at index `period`."
        },
        "errors": [
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `close` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n × period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "rangeExpansionIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A07",
          "title": "Range Expansion Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 20,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -8.09257352049753
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a07/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a07/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a07/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a07/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Range Expansion Index calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Range Expansion Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Range Expansion Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/range-expansion-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/range-expansion-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A08",
      "name": "Fractal Dimension Index",
      "headline": null,
      "slug": "fractal-dimension-index",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/fractal-dimension-index",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/fractal-dimension-index",
        "entry": "fractalDimensionIndex",
        "params": [
          "input"
        ],
        "exports": [
          "fractalDimensionIndex"
        ],
        "archetype": "record-transform",
        "signature": "fractalDimensionIndex(input)"
      },
      "api": {
        "summary": "Compares the total path length walked by close over a window against the straight-line span of that window, on a log scale, and clamps the result to [1, 2]. Near 1 the path is a line; near 2 it fills the range.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.period` (default `20`, integer of at least 2) sets the window and is also the log base of the normalisation.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key, always between 1 and 2. The warm-up is `period` bars, so with the default `ready_at` is 20; a window with zero path length or zero span yields exactly 1 rather than a null."
        },
        "warmup": {
          "count": "period bars (20 by default)",
          "value": "null",
          "note": "The window spans indices i-period through i inclusive - `period + 1` closes - so the first computable index is `period`."
        },
        "errors": [
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `close` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n × period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "fractalDimensionIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A08",
          "title": "Fractal Dimension Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 20,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 1.209221037242474
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a08/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a08/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a08/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a08/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Fractal Dimension Index calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Fractal Dimension Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Fractal Dimension Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/fractal-dimension-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/fractal-dimension-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A09",
      "name": "Hurst Exponent",
      "headline": null,
      "slug": "hurst-exponent",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/hurst-exponent",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/hurst-exponent",
        "entry": "hurstExponent",
        "params": [
          "input"
        ],
        "exports": [
          "hurstExponent"
        ],
        "archetype": "record-transform",
        "signature": "hurstExponent(input)"
      },
      "api": {
        "summary": "A rolling rescaled-range estimate: over each window of `period` closes it takes the range of the mean-adjusted cumulative sum, divides by the window's standard deviation, and reports `log(R/S) / log(period)`.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.period` (default `20`, integer of at least 2) sets the window and the log base.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key. The warm-up is `period - 1` bars, so with the default `ready_at` is 19; `value` is additionally null on any window whose cumulative-deviation range or standard deviation is zero, which is what a perfectly flat stretch gives."
        },
        "warmup": {
          "count": "period - 1 bars (19 by default)",
          "value": "null",
          "note": "The window spans indices i-period+1 through i inclusive, so index `period - 1` is the first with a full window."
        },
        "errors": [
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `close` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n × period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "hurstExponent({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A09",
          "title": "Hurst Exponent",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 0.6970566842387678
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a09/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a09/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a09/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a09/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Hurst Exponent calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Hurst Exponent convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Hurst Exponent readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/hurst-exponent/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/hurst-exponent/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A10",
      "name": "Efficiency Ratio",
      "headline": null,
      "slug": "efficiency-ratio",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/efficiency-ratio",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/efficiency-ratio",
        "entry": "efficiencyRatio",
        "params": [
          "input"
        ],
        "exports": [
          "efficiencyRatio"
        ],
        "archetype": "record-transform",
        "signature": "efficiencyRatio(input)"
      },
      "api": {
        "summary": "Kaufman's ratio of net displacement to gross travel: the absolute change in close over `period` bars divided by the sum of the absolute bar-to-bar changes across the same span. Near 1 the market went somewhere; near 0 it churned.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.period` (default `20`, integer of at least 2) sets the lookback.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key, unscaled and between 0 and 1. The warm-up is `period` bars, so with the default `ready_at` is 20; `value` is also null on any window whose absolute changes sum to zero."
        },
        "warmup": {
          "count": "period bars (20 by default)",
          "value": "null",
          "note": "The numerator needs a close `period` bars back and the denominator's rolling sum rejects the null at index 0, so both align on index `period`."
        },
        "errors": [
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `close` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n × period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "efficiencyRatio({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A10",
          "title": "Efficiency Ratio",
          "state": "calculated",
          "ready": true,
          "ready_at": 20,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 0.08092573520497529
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a10/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a10/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a10/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a10/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Efficiency Ratio calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Efficiency Ratio convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Efficiency Ratio readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/efficiency-ratio/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/efficiency-ratio/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A11",
      "name": "Market Meanness Index",
      "headline": null,
      "slug": "market-meanness-index",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/market-meanness-index",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/market-meanness-index",
        "entry": "marketMeannessIndex",
        "params": [
          "input"
        ],
        "exports": [
          "marketMeannessIndex"
        ],
        "archetype": "record-transform",
        "signature": "marketMeannessIndex(input)"
      },
      "api": {
        "summary": "Counts how often close crosses the median of its own `period`-bar window and reports that as a percentage of the `period - 1` opportunities. High readings mean the series keeps returning to its centre.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.period` (default `20`, integer of at least 2) sets the window whose median is the reference line.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key, between 0 and 100. The warm-up is `period - 1` bars, so with the default `ready_at` is 19; once the window is full the value is never null."
        },
        "warmup": {
          "count": "period - 1 bars (19 by default)",
          "value": "null",
          "note": "The window spans indices i-period+1 through i inclusive, so index `period - 1` is the first with a full window."
        },
        "errors": [
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `close` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n × period log period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "marketMeannessIndex({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A11",
          "title": "Market Meanness Index",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 10.526315789473685
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a11/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a11/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a11/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a11/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Market Meanness Index calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Market Meanness Index convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Market Meanness Index readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/market-meanness-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/market-meanness-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A12",
      "name": "Trend/Range Regime Classifier",
      "headline": null,
      "slug": "trend-range-regime-classifier",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/trend-range-regime-classifier",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/trend-range-regime-classifier",
        "entry": "trendRangeRegimeClassifier",
        "params": [
          "input"
        ],
        "exports": [
          "trendRangeRegimeClassifier"
        ],
        "archetype": "record-transform",
        "signature": "trendRangeRegimeClassifier(input)"
      },
      "api": {
        "summary": "Labels each bar `trend`, `range` or `uncertain` by requiring two independent readings to agree: efficiency ratio at or above 0.55 with Choppiness at or below 45 gives `trend`, efficiency at or below 0.25 with Choppiness at or above 55 gives `range`, and anything else is `uncertain`.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.period` (default `20`, integer of at least 2) sets both inputs - it is forwarded verbatim to the Choppiness Index implementation, which reads no other key. The four thresholds are fixed in the implementation.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `efficiency`, `choppiness` and the string series `regime`. The warm-up is uneven: `choppiness` starts at `period - 1` and `efficiency` at `period`, so `ready_at` is 19 with the default while the `regime` label itself stays null until index 20."
        },
        "warmup": {
          "count": "period - 1 bars for choppiness, period bars for efficiency and regime",
          "value": "null",
          "note": "`ready_at` reports the earliest non-null across all series, which is `choppiness` at index `period - 1`. A caller reading `regime` should wait one bar longer, since the label is null whenever either input is."
        },
        "errors": [
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `high`, `low`, or `close` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n × period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "trendRangeRegimeClassifier({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A12",
          "title": "Trend/Range Regime Classifier",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "efficiency": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "choppiness": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "regime": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "efficiency": 0.08092573520497529,
            "choppiness": 58.89834097590164,
            "regime": "range"
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a12/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a12/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a12/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a12/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Trend/Range Regime Classifier calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Trend/Range Regime Classifier convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Trend/Range Regime Classifier readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/trend-range-regime-classifier/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/trend-range-regime-classifier/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A13",
      "name": "Volatility Regime Classifier",
      "headline": null,
      "slug": "volatility-regime-classifier",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/volatility-regime-classifier",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/volatility-regime-classifier",
        "entry": "volatilityRegimeClassifier",
        "params": [
          "input"
        ],
        "exports": [
          "volatilityRegimeClassifier"
        ],
        "archetype": "record-transform",
        "signature": "volatilityRegimeClassifier(input)"
      },
      "api": {
        "summary": "Computes realized volatility as the standard deviation of simple close returns over `period` bars, then ranks each reading against the last `rank_period` of them: bottom quartile is `low`, top quartile is `high`, everything between is `normal`.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.period` (default `20`, integer of at least 2) sets the volatility window; `parameters.rank_period` (default `40`) sets the ranking history and must be an integer of at least `period`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `volatility` and the string series `regime`. The warm-up is uneven: `volatility` needs `period` bars, so `ready_at` is 20 with the defaults, but `regime` needs a full `rank_period` of non-null volatilities behind it and so first appears at index `period + rank_period - 1`, which is 59 by default."
        },
        "warmup": {
          "count": "period bars for volatility, period + rank_period - 1 for regime",
          "value": "null",
          "note": "The return series is null at index 0, so the standard deviation window first completes at index `period`. The rank window then needs `rank_period` consecutive non-null volatilities, pushing the first label much later than `ready_at` suggests."
        },
        "errors": [
          {
            "when": "`rank_period` is supplied as a non-integer or as a value below `period`",
            "behaviour": "throws Error"
          },
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n × (period + rank_period))",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "volatilityRegimeClassifier({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A13",
          "title": "Volatility Regime Classifier",
          "state": "calculated",
          "ready": true,
          "ready_at": 20,
          "series": {
            "volatility": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "regime": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "volatility": 0.008703709337001016,
            "regime": "normal"
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a13/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a13/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a13/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a13/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Volatility Regime Classifier calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Volatility Regime Classifier convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Volatility Regime Classifier readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/volatility-regime-classifier/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/volatility-regime-classifier/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A14",
      "name": "Directional Persistence",
      "headline": null,
      "slug": "directional-persistence",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/directional-persistence",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/directional-persistence",
        "entry": "directionalPersistence",
        "params": [
          "input"
        ],
        "exports": [
          "directionalPersistence"
        ],
        "archetype": "record-transform",
        "signature": "directionalPersistence(input)"
      },
      "api": {
        "summary": "Maps each bar to +1, -1 or 0 by the sign of its close-to-close change, sums those signs over `period` bars, and reports the absolute total divided by `period`. It measures one-sidedness without caring which side.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.period` (default `20`, integer of at least 2) sets the summation window.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key, between 0 and 1. The warm-up is `period` bars, because the sign at index 0 is undefined and the rolling sum rejects windows containing it, so with the default `ready_at` is 20."
        },
        "warmup": {
          "count": "period bars (20 by default)",
          "value": "null",
          "note": "The sign series is null at index 0, so the first complete window of `period` signs ends at index `period`."
        },
        "errors": [
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `close` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n × period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "directionalPersistence({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A14",
          "title": "Directional Persistence",
          "state": "calculated",
          "ready": true,
          "ready_at": 20,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 0.1
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a14/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a14/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a14/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a14/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Directional Persistence calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Directional Persistence convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Directional Persistence readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/directional-persistence/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/directional-persistence/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A15",
      "name": "Swing Structure Detector",
      "headline": null,
      "slug": "swing-structure-detector",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/swing-structure-detector",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/swing-structure-detector",
        "entry": "swingStructureDetector",
        "params": [
          "input"
        ],
        "exports": [
          "swingStructureDetector"
        ],
        "archetype": "record-transform",
        "signature": "swingStructureDetector(input)"
      },
      "api": {
        "summary": "Confirms five-bar swing highs and lows and labels each one against the previous swing of the same kind - `HH`, `LH`, `HL`, `LL`, or `swing-high`/`swing-low` for the first of each. The confirmation is causal: a swing at bar p is only reported at bar p+2.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. The five-bar swing window is fixed and no `parameters` key changes it; `period` (default `20`, integer of at least 2) is validated by the family but unused here.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `swing_high`, `swing_low` and the string series `structure`. The warm-up is four bars: from index 4 `structure` reads `none` on bars with no confirmation, so `ready_at` is 4, while `swing_high` and `swing_low` stay null except on the bars that confirm one."
        },
        "warmup": {
          "count": "4 bars",
          "value": "null",
          "note": "A centred five-bar window is impossible before index 4. From there `structure` is never null, so `ready_at` is 4 regardless of the data. When a high and a low confirm on the same bar the low's label is the one that survives."
        },
        "errors": [
          {
            "when": "`bars` is empty or is not an array",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `high` or `low` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "swingStructureDetector({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A15",
          "title": "Swing Structure Detector",
          "state": "calculated",
          "ready": true,
          "ready_at": 4,
          "series": {
            "swing_high": [
              null,
              null,
              null,
              null,
              null,
              105.01857496
            ],
            "swing_low": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "structure": [
              null,
              null,
              null,
              null,
              "none",
              "swing-high"
            ]
          },
          "latest": {
            "swing_high": null,
            "swing_low": null,
            "structure": "none"
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a15/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a15/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a15/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a15/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Swing Structure Detector calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Swing Structure Detector convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Swing Structure Detector readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/swing-structure-detector/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/swing-structure-detector/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A16",
      "name": "Higher-High/Lower-Low Structure",
      "headline": null,
      "slug": "higher-high-lower-low-structure",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/higher-high-lower-low-structure",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/higher-high-lower-low-structure",
        "entry": "higherHighLowerLowStructure",
        "params": [
          "input"
        ],
        "exports": [
          "higherHighLowerLowStructure"
        ],
        "archetype": "record-transform",
        "signature": "higherHighLowerLowStructure(input)"
      },
      "api": {
        "summary": "Reduces price to the higher-high / lower-low sequence traders read structure from, labelling each confirmed five-bar swing `HH`, `LH`, `HL` or `LL` against the previous swing of its kind. It shares a byte-identical state transition with the swing structure detector.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. The five-bar swing window is fixed and no `parameters` key changes it; `period` (default `20`, integer of at least 2) is validated by the family but unused here.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry `swing_high`, `swing_low` and the string series `structure`, whose values are `none`, `swing-high`, `swing-low`, `HH`, `LH`, `HL` or `LL`. The warm-up is four bars, so `ready_at` is 4."
        },
        "warmup": {
          "count": "4 bars",
          "value": "null",
          "note": "A centred five-bar window is impossible before index 4. From there `structure` is never null; `swing_high` and `swing_low` remain null on every bar that does not confirm a swing."
        },
        "errors": [
          {
            "when": "`bars` is empty or is not an array",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `high` or `low` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "higherHighLowerLowStructure({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A16",
          "title": "Higher-High/Lower-Low Structure",
          "state": "calculated",
          "ready": true,
          "ready_at": 4,
          "series": {
            "swing_high": [
              null,
              null,
              null,
              null,
              null,
              105.01857496
            ],
            "swing_low": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "structure": [
              null,
              null,
              null,
              null,
              "none",
              "swing-high"
            ]
          },
          "latest": {
            "swing_high": null,
            "swing_low": null,
            "structure": "none"
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a16/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a16/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a16/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a16/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Higher-High/Lower-Low Structure calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Higher-High/Lower-Low Structure convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Higher-High/Lower-Low Structure readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/higher-high-lower-low-structure/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/higher-high-lower-low-structure/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A17",
      "name": "Inside/Outside Bar Structure",
      "headline": null,
      "slug": "inside-outside-bar-structure",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/inside-outside-bar-structure",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/inside-outside-bar-structure",
        "entry": "insideOutsideBarStructure",
        "params": [
          "input"
        ],
        "exports": [
          "insideOutsideBarStructure"
        ],
        "archetype": "record-transform",
        "signature": "insideOutsideBarStructure(input)"
      },
      "api": {
        "summary": "Classifies each bar against its immediate predecessor as `inside` (high not above and low not below), `outside` (high not below and low not above), or `neither`. A bar that exactly repeats the previous range is classified `inside`, because that test is evaluated first.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. This topic reads no keys from `parameters`; `period` (default `20`, integer of at least 2) is validated by the family but unused here.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single string series, `structure`. The warm-up is one bar, since index 0 has no predecessor to compare against, so `ready_at` is 1."
        },
        "warmup": {
          "count": "1 bar",
          "value": "null",
          "note": "Index 0 is null; every index from 1 onward carries one of `inside`, `outside` or `neither` and is never null."
        },
        "errors": [
          {
            "when": "a bar's `high` is below its own `open`, `close`, or `low` (or `low` is above them)",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty or is not an array",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "insideOutsideBarStructure({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A17",
          "title": "Inside/Outside Bar Structure",
          "state": "calculated",
          "ready": true,
          "ready_at": 1,
          "series": {
            "structure": [
              null,
              "neither",
              "neither",
              "neither",
              "neither",
              "neither"
            ]
          },
          "latest": {
            "structure": "neither"
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a17/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a17/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a17/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a17/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Inside/Outside Bar Structure calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Inside/Outside Bar Structure convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Inside/Outside Bar Structure readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/inside-outside-bar-structure/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/inside-outside-bar-structure/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F07-A18",
      "name": "Market Entropy",
      "headline": null,
      "slug": "market-entropy",
      "path": "geometric-chart-patterns/market-structure-breakouts-and-regimes/market-entropy",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F07",
        "family": "Market Structure, Breakouts, and Regimes",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/market-structure-breakouts-and-regimes/market-entropy",
        "entry": "marketEntropy",
        "params": [
          "input"
        ],
        "exports": [
          "marketEntropy"
        ],
        "archetype": "record-transform",
        "signature": "marketEntropy(input)"
      },
      "api": {
        "summary": "Treats each bar as one of three states by the sign of its close change, then reports the Shannon entropy of the state distribution over a `period`-bar window, normalised by `log(3)` so a perfectly balanced mix scores 1.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is the required OHLCV history, strictly ordered by `timestamp` and on a single adjustment basis. `parameters.period` (default `20`, integer of at least 2) sets the counting window and the probability denominator.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series` and `latest` carry a single `value` key, between 0 and 1. The warm-up is `period` bars, because the sign at index 0 is undefined, so with the default `ready_at` is 20."
        },
        "warmup": {
          "count": "period bars (20 by default)",
          "value": "null",
          "note": "Emission starts at index `period`, the first bar whose `period`-long window of signs excludes the undefined sign at index 0."
        },
        "errors": [
          {
            "when": "`period` is supplied as a non-integer or as a value below 2",
            "behaviour": "throws Error"
          },
          {
            "when": "a bar's `close` is not a finite number",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n × period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "marketEntropy({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F07-A18",
          "title": "Market Entropy",
          "state": "calculated",
          "ready": true,
          "ready_at": 20,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 0.6263709416065661
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a18/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a18/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a18/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d08-f07-a18/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Market Entropy calculation flow",
            "source": "flowchart LR\n    A[\"ordered OHLC observations, explicit lookbacks and threshol\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Market Entropy convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Market Entropy readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)",
          "author": "Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation",
          "url": null
        },
        {
          "key": "S2",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S3",
          "title": "Long-Term Storage Capacity of Reservoirs",
          "author": "H. E. Hurst",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/market-structure-breakouts-and-regimes/market-entropy/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/market-structure-breakouts-and-regimes/market-entropy/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": [
          {
            "file": "decision-flow.md",
            "caption": "ACF decision flow",
            "source": "flowchart TD\n  A[\"Ordered finite series\"] --> B{\"Contract valid?\"}\n  B -- \"No\" --> X[\"Stop: explicit invalid state\"]\n  B -- \"Yes\" --> C[\"Center once\"]\n  C --> D[\"Align lag-k pairs\"]\n  D --> E[\"Divide by common sum of squares\"]\n  E --> F[\"Inspect coefficient and heuristic band\"]\n  F --> G{\"Declared strict decision rule\"}\n  G --> H[\"Report machine state, null, and limitation\"]\n  H --> I[\"Compare with PACF\"]"
          }
        ]
      },
      "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": [
          {
            "file": "decision-flow.md",
            "caption": "PACF decision flow",
            "source": "flowchart TD\n  A[\"Ordered finite series\"] --> B{\"Contract valid?\"}\n  B -- \"No\" --> X[\"Stop: explicit invalid state\"]\n  B -- \"Yes\" --> C[\"Compute biased ACF\"]\n  C --> D[\"Seed reflection and variance\"]\n  D --> E[\"Run Levinson-Durbin recursion\"]\n  E --> F[\"Inspect incremental lag coefficient\"]\n  F --> G{\"Declared strict decision rule\"}\n  G --> H[\"Report machine state, null, and limitation\"]\n  H --> I[\"Compare with Augmented Dickey-Fuller\"]"
          }
        ]
      },
      "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": [
          {
            "file": "decision-flow.md",
            "caption": "Augmented Dickey-Fuller decision flow",
            "source": "flowchart TD\n  A[\"Ordered finite series\"] --> B{\"Contract valid?\"}\n  B -- \"No\" --> X[\"Stop: explicit invalid state\"]\n  B -- \"Yes\" --> C[\"Difference after warm-up\"]\n  C --> D[\"Build fixed-lag constant-only OLS rows\"]\n  D --> E[\"Compute gamma t-ratio\"]\n  E --> F[\"Compare with nonstandard boundary\"]\n  F --> G{\"Declared strict decision rule\"}\n  G --> H[\"Report machine state, null, and limitation\"]\n  H --> I[\"Compare with KPSS\"]"
          }
        ]
      },
      "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": [
          {
            "file": "decision-flow.md",
            "caption": "KPSS decision flow",
            "source": "flowchart TD\n  A[\"Ordered finite series\"] --> B{\"Contract valid?\"}\n  B -- \"No\" --> X[\"Stop: explicit invalid state\"]\n  B -- \"Yes\" --> C[\"Demean for level null\"]\n  C --> D[\"Accumulate residual partial sums\"]\n  D --> E[\"Estimate Bartlett long-run variance\"]\n  E --> F[\"Compare KPSS statistic with boundary\"]\n  F --> G{\"Declared strict decision rule\"}\n  G --> H[\"Report machine state, null, and limitation\"]\n  H --> I[\"Compare with Ljung-Box\"]"
          }
        ]
      },
      "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": [
          {
            "file": "decision-flow.md",
            "caption": "Ljung-Box decision flow",
            "source": "flowchart TD\n  A[\"Ordered finite series\"] --> B{\"Contract valid?\"}\n  B -- \"No\" --> X[\"Stop: explicit invalid state\"]\n  B -- \"Yes\" --> C[\"Compute residual ACF through h\"]\n  C --> D[\"Scale and sum squared lag terms\"]\n  D --> E[\"Set df = h - model_df\"]\n  E --> F[\"Compare chi-square tail with alpha\"]\n  F --> G{\"Declared strict decision rule\"}\n  G --> H[\"Report machine state, null, and limitation\"]\n  H --> I[\"Compare with Zivot-Andrews Break Test\"]"
          }
        ]
      },
      "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": [
          {
            "file": "decision-flow.md",
            "caption": "Zivot-Andrews Break Test decision flow",
            "source": "flowchart TD\n  A[\"Ordered finite series\"] --> B{\"Contract valid?\"}\n  B -- \"No\" --> X[\"Stop: explicit invalid state\"]\n  B -- \"Yes\" --> C[\"Apply trim and enumerate break dates\"]\n  C --> D[\"Fit fixed-lag intercept-break OLS at each date\"]\n  D --> E[\"Select minimum lagged-level t-ratio\"]\n  E --> F[\"Compare selected statistic with boundary\"]\n  F --> G{\"Declared strict decision rule\"}\n  G --> H[\"Report machine state, null, and limitation\"]\n  H --> I[\"Compare with AutoReg\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "AutoReg Calculation Flow",
            "source": "flowchart LR\n    A[\"Finalized equally spaced training series\"] --> B[\"Validate cutoff and frozen parameters\"]\n    B --> C[\"Build selected state or transformed series\"]\n    C --> D[\"Calculate horizon h conditional mean\"]\n    D --> E{\"More horizons?\"}\n    E -- \"yes\" --> F[\"Append forecast and zero future innovation\"]\n    F --> D\n    E -- \"no\" --> G[\"Publish path and state trace\"]\n    G --> H[\"Reveal holdout only for evaluation\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "ARMA Calculation Flow",
            "source": "flowchart LR\n    A[\"Finalized equally spaced training series\"] --> B[\"Validate cutoff and frozen parameters\"]\n    B --> C[\"Build selected state or transformed series\"]\n    C --> D[\"Calculate horizon h conditional mean\"]\n    D --> E{\"More horizons?\"}\n    E -- \"yes\" --> F[\"Append forecast and zero future innovation\"]\n    F --> D\n    E -- \"no\" --> G[\"Publish path and state trace\"]\n    G --> H[\"Reveal holdout only for evaluation\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "ARIMA Calculation Flow",
            "source": "flowchart LR\n    A[\"Finalized equally spaced training series\"] --> B[\"Validate cutoff and frozen parameters\"]\n    B --> C[\"Build selected state or transformed series\"]\n    C --> D[\"Calculate horizon h conditional mean\"]\n    D --> E{\"More horizons?\"}\n    E -- \"yes\" --> F[\"Append forecast and zero future innovation\"]\n    F --> D\n    E -- \"no\" --> G[\"Publish path and state trace\"]\n    G --> H[\"Reveal holdout only for evaluation\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "SARIMA/SARIMAX Calculation Flow",
            "source": "flowchart LR\n    A[\"Finalized equally spaced training series\"] --> B[\"Validate cutoff and frozen parameters\"]\n    B --> C[\"Build selected state or transformed series\"]\n    C --> D[\"Calculate horizon h conditional mean\"]\n    D --> E{\"More horizons?\"}\n    E -- \"yes\" --> F[\"Append forecast and zero future innovation\"]\n    F --> D\n    E -- \"no\" --> G[\"Publish path and state trace\"]\n    G --> H[\"Reveal holdout only for evaluation\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Holt-Winters Calculation Flow",
            "source": "flowchart LR\n    A[\"Finalized equally spaced training series\"] --> B[\"Validate cutoff and frozen parameters\"]\n    B --> C[\"Build selected state or transformed series\"]\n    C --> D[\"Calculate horizon h conditional mean\"]\n    D --> E{\"More horizons?\"}\n    E -- \"yes\" --> F[\"Append forecast and zero future innovation\"]\n    F --> D\n    E -- \"no\" --> G[\"Publish path and state trace\"]\n    G --> H[\"Reveal holdout only for evaluation\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Theta Forecast Calculation Flow",
            "source": "flowchart LR\n    A[\"Finalized equally spaced training series\"] --> B[\"Validate cutoff and frozen parameters\"]\n    B --> C[\"Build selected state or transformed series\"]\n    C --> D[\"Calculate horizon h conditional mean\"]\n    D --> E{\"More horizons?\"}\n    E -- \"yes\" --> F[\"Append forecast and zero future innovation\"]\n    F --> D\n    E -- \"no\" --> G[\"Publish path and state trace\"]\n    G --> H[\"Reveal holdout only for evaluation\"]"
          }
        ]
      },
      "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": [
          {
            "file": "system-flow.md",
            "caption": "VAR system flow",
            "source": "flowchart LR\n    A[\"Aligned stationary rows\"] --> B[\"Lagged design matrix\"]\n    B --> C[\"Equation-wise OLS\"]\n    C --> D[\"A matrices and residual covariance\"]\n    D --> E[\"Forecast plus diagnostics\"]"
          }
        ]
      },
      "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": [
          {
            "file": "system-flow.md",
            "caption": "Structural VAR system flow",
            "source": "flowchart LR\n    A[\"Reduced-form residuals\"] --> B[\"Declared variable ordering\"]\n    B --> C[\"Cholesky impact matrix\"]\n    C --> D[\"Orthogonal structural shocks\"]\n    D --> E[\"Ordering sensitivity record\"]"
          }
        ]
      },
      "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": [
          {
            "file": "system-flow.md",
            "caption": "VECM system flow",
            "source": "flowchart LR\n    A[\"Aligned integrated levels\"] --> B[\"Supplied rank and normalized beta\"]\n    B --> C[\"Lagged equilibrium error\"]\n    C --> D[\"Alpha and short-run Gamma\"]\n    D --> E[\"Adjustment diagnostics\"]"
          }
        ]
      },
      "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",
          "impactMatrix"
        ],
        "exports": [
          "companionMatrix",
          "companionSpectralRadius",
          "fitVAR",
          "choleskyLower",
          "fitRecursiveSVAR",
          "fitVECMFixedBeta",
          "movingAverageMatrices",
          "impulseResponses",
          "forecastErrorVarianceDecomposition"
        ],
        "archetype": "record-transform",
        "signature": "impulseResponses(coefficients, horizon, impactMatrix)"
      },
      "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
          },
          {
            "name": "impactMatrix",
            "type": "Matrix",
            "required": false,
            "description": "Contemporaneous impact matrix. Defaults to the identity, so the responses are to unit shocks in each variable rather than to structurally identified ones.",
            "constraints": null,
            "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": [
          {
            "file": "system-flow.md",
            "caption": "Impulse-Response Analysis system flow",
            "source": "flowchart LR\n    A[\"VAR coefficient matrices\"] --> B[\"Phi zero equals identity\"]\n    B --> C[\"Moving-average recursion\"]\n    C --> D[\"Multiply by impact matrix\"]\n    D --> E[\"Response and cumulative paths\"]"
          }
        ]
      },
      "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",
          "impactMatrix"
        ],
        "exports": [
          "companionMatrix",
          "companionSpectralRadius",
          "fitVAR",
          "choleskyLower",
          "fitRecursiveSVAR",
          "fitVECMFixedBeta",
          "movingAverageMatrices",
          "impulseResponses",
          "forecastErrorVarianceDecomposition"
        ],
        "archetype": "record-transform",
        "signature": "forecastErrorVarianceDecomposition(coefficients, sigmaU, horizon, impactMatrix)"
      },
      "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
          },
          {
            "name": "impactMatrix",
            "type": "Matrix",
            "required": false,
            "description": "Contemporaneous impact matrix. Defaults to the lower Cholesky factor of `sigmaU`, which is the recursive identification implied by variable order.",
            "constraints": null,
            "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": [
          {
            "file": "system-flow.md",
            "caption": "Forecast-Error Variance Decomposition system flow",
            "source": "flowchart LR\n    A[\"Identified response matrices\"] --> B[\"Square each contribution\"]\n    B --> C[\"Accumulate through horizon\"]\n    C --> D[\"Normalize within response row\"]\n    D --> E[\"Shares sum to one\"]"
          }
        ]
      },
      "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": "observations is empty or holds a non-finite value",
            "behaviour": "throws"
          },
          {
            "when": "config omits any of a, b, c, q, r, initial_mean, initial_variance",
            "behaviour": "throws"
          },
          {
            "when": "any config value is non-finite",
            "behaviour": "throws"
          },
          {
            "when": "q or initial_variance is negative, or 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": "observations is empty or holds a non-finite value",
            "behaviour": "throws"
          },
          {
            "when": "config omits a required key or holds a non-finite value",
            "behaviour": "throws"
          },
          {
            "when": "q or initial_variance is negative, r or alpha is not positive, or n + lambda is not positive",
            "behaviour": "throws"
          },
          {
            "when": "the sigma-point parameters produce a non-positive-definite covariance",
            "behaviour": "throws",
            "note": "Checked on the predicted, innovation and posterior covariance at every step. Values within 1e-12 of zero are treated as floating-point noise; anything more negative is refused rather than clipped."
          }
        ],
        "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": "observations is empty or holds a non-finite value",
            "behaviour": "throws"
          },
          {
            "when": "config omits transition, intercepts, phis, stds or initial",
            "behaviour": "throws"
          },
          {
            "when": "the parameter arrays differ in length from the number of regimes",
            "behaviour": "throws"
          },
          {
            "when": "any coefficient, standard deviation or probability is non-finite",
            "behaviour": "throws"
          },
          {
            "when": "a transition row or the initial vector holds a value outside [0, 1] or does not sum to 1",
            "behaviour": "throws",
            "note": "Checked per entry, not only on the row sum, so a row such as [-0.5, 1.5] is refused rather than clipped."
          },
          {
            "when": "a standard deviation is not positive",
            "behaviour": "throws"
          },
          {
            "when": "a phi equals 1, leaving the row-0 start c/(1-phi) undefined",
            "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": [
          {
            "file": "decomposition-flow.md",
            "caption": "STL Decomposition — Audit Flow",
            "source": "flowchart LR\n    A[\"Finite evenly sampled values\"] --> B[\"Freeze transformation and profile\"]\n    B --> C[\"Seasonal-position LOESS ↔ trend LOESS\"]\n    C --> D[\"Component or power output\"]\n    D --> E[\"Reconstruction / accounting check\"]\n    E --> F[\"Endpoint and revision audit\"]\n    F --> G[\"Profile sensitivity\"]\n    G --> H[\"White-noise control\"]\n    H --> I{\"Decision use justified?\"}\n    I -->|No| J[\"Keep as descriptive diagnostic\"]\n    I -->|Yes| K[\"Rebuild causally and test out of sample\"]"
          }
        ]
      },
      "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": [
          {
            "file": "decomposition-flow.md",
            "caption": "Hodrick-Prescott Filter — Audit Flow",
            "source": "flowchart LR\n    A[\"Finite evenly sampled values\"] --> B[\"Freeze transformation and profile\"]\n    B --> C[\"Solve penalized trend system\"]\n    C --> D[\"Component or power output\"]\n    D --> E[\"Reconstruction / accounting check\"]\n    E --> F[\"Endpoint and revision audit\"]\n    F --> G[\"Profile sensitivity\"]\n    G --> H[\"White-noise control\"]\n    H --> I{\"Decision use justified?\"}\n    I -->|No| J[\"Keep as descriptive diagnostic\"]\n    I -->|Yes| K[\"Rebuild causally and test out of sample\"]"
          }
        ]
      },
      "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": [
          {
            "file": "decomposition-flow.md",
            "caption": "Baxter-King Filter — Audit Flow",
            "source": "flowchart LR\n    A[\"Finite evenly sampled values\"] --> B[\"Freeze transformation and profile\"]\n    B --> C[\"Apply centered finite band-pass weights\"]\n    C --> D[\"Component or power output\"]\n    D --> E[\"Reconstruction / accounting check\"]\n    E --> F[\"Endpoint and revision audit\"]\n    F --> G[\"Profile sensitivity\"]\n    G --> H[\"White-noise control\"]\n    H --> I{\"Decision use justified?\"}\n    I -->|No| J[\"Keep as descriptive diagnostic\"]\n    I -->|Yes| K[\"Rebuild causally and test out of sample\"]"
          }
        ]
      },
      "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": [
          {
            "file": "decomposition-flow.md",
            "caption": "Christiano-Fitzgerald Filter — Audit Flow",
            "source": "flowchart LR\n    A[\"Finite evenly sampled values\"] --> B[\"Freeze transformation and profile\"]\n    B --> C[\"Apply date-varying full-sample weights\"]\n    C --> D[\"Component or power output\"]\n    D --> E[\"Reconstruction / accounting check\"]\n    E --> F[\"Endpoint and revision audit\"]\n    F --> G[\"Profile sensitivity\"]\n    G --> H[\"White-noise control\"]\n    H --> I{\"Decision use justified?\"}\n    I -->|No| J[\"Keep as descriptive diagnostic\"]\n    I -->|Yes| K[\"Rebuild causally and test out of sample\"]"
          }
        ]
      },
      "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": [
          {
            "file": "decomposition-flow.md",
            "caption": "Fast Fourier Transform Periodogram — Audit Flow",
            "source": "flowchart LR\n    A[\"Finite evenly sampled values\"] --> B[\"Freeze transformation and profile\"]\n    B --> C[\"Detrend → window → FFT → power\"]\n    C --> D[\"Component or power output\"]\n    D --> E[\"Reconstruction / accounting check\"]\n    E --> F[\"Endpoint and revision audit\"]\n    F --> G[\"Profile sensitivity\"]\n    G --> H[\"White-noise control\"]\n    H --> I{\"Decision use justified?\"}\n    I -->|No| J[\"Keep as descriptive diagnostic\"]\n    I -->|Yes| K[\"Rebuild causally and test out of sample\"]"
          }
        ]
      },
      "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": [
          {
            "file": "decomposition-flow.md",
            "caption": "Wavelet Decomposition — Audit Flow",
            "source": "flowchart LR\n    A[\"Finite evenly sampled values\"] --> B[\"Freeze transformation and profile\"]\n    B --> C[\"Pair averages/differences across levels\"]\n    C --> D[\"Component or power output\"]\n    D --> E[\"Reconstruction / accounting check\"]\n    E --> F[\"Endpoint and revision audit\"]\n    F --> G[\"Profile sensitivity\"]\n    G --> H[\"White-noise control\"]\n    H --> I{\"Decision use justified?\"}\n    I -->|No| J[\"Keep as descriptive diagnostic\"]\n    I -->|Yes| K[\"Rebuild causally and test out of sample\"]"
          }
        ]
      },
      "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": "D09-F06-A01",
      "name": "Hilbert Transform Dominant Cycle Period",
      "headline": null,
      "slug": "hilbert-transform-dominant-cycle-period",
      "path": "statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-dominant-cycle-period",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F06",
        "family": "Hilbert and Ehlers Cycle Analytics",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-dominant-cycle-period",
        "entry": "hilbertTransformDominantCyclePeriod",
        "params": [
          "input"
        ],
        "exports": [
          "hilbertTransformDominantCyclePeriod"
        ],
        "archetype": "record-transform",
        "signature": "hilbertTransformDominantCyclePeriod(input)"
      },
      "api": {
        "summary": "Estimates the dominant cycle length in bars from the bar-to-bar change in the Hilbert phase angle, clamping each raw estimate into the 6-to-50 bar range and smoothing it with a 0.2 / 0.8 exponential update. Any contract failure is rethrown as an `Error` whose message begins `topic calculation failed: `.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of rows with `timestamp`, `open`, `high`, `low`, `close` and `volume`, strictly ordered by timestamp. The cycles family reads one key from `parameters`, `period`, defaulting to 20 and required to be an integer of at least 4; it is validated for this topic but its arithmetic never uses it.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "`series.value` and `latest.value` carry the smoothed dominant-cycle period measured in bars, always between 6 and 50. `parameters` echoes the supplied parameters and `diagnostics` reports `causal` and `input_count`. Warm-up is seven leading nulls, so `ready_at` is 7."
        },
        "warmup": {
          "count": 7,
          "value": null,
          "note": "The 4-bar EMA of `close` first resolves at index 3, the four-tap quadrature filter needs three further bars so phase begins at index 6, and the period step differences two consecutive phases, which puts the first estimate and `ready_at` at index 7."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 4",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, a `timestamp` is missing or not strictly increasing, an OHLCV field is not finite, `volume` is negative, or `high` and `low` do not bracket `open` and `close`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "hilbertTransformDominantCyclePeriod({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D09-F06-A01",
          "title": "Hilbert Transform Dominant Cycle Period",
          "state": "calculated",
          "ready": true,
          "ready_at": 7,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": 24.86605208112273
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a01/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a01/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a01/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Hilbert Transform Dominant Cycle Period calculation flow",
            "source": "flowchart LR\n    A[\"uniformly sampled finite prices with declared prefilter, c\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Hilbert Transform Dominant Cycle Period convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Hilbert Transform Dominant Cycle Period readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib cycle indicator group",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "SciPy analytic-signal documentation",
          "author": "The SciPy community",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-dominant-cycle-period/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-dominant-cycle-period/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F06-A02",
      "name": "Hilbert Transform Dominant Cycle Phase",
      "headline": null,
      "slug": "hilbert-transform-dominant-cycle-phase",
      "path": "statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-dominant-cycle-phase",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F06",
        "family": "Hilbert and Ehlers Cycle Analytics",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-dominant-cycle-phase",
        "entry": "hilbertTransformDominantCyclePhase",
        "params": [
          "input"
        ],
        "exports": [
          "hilbertTransformDominantCyclePhase"
        ],
        "archetype": "record-transform",
        "signature": "hilbertTransformDominantCyclePhase(input)"
      },
      "api": {
        "summary": "Returns the instantaneous Hilbert phase angle in radians as `atan2(quadrature, in_phase)`, where both components come from a four-tap filter over the residual of `close` against its 4-bar EMA. Any contract failure is rethrown as an `Error` whose message begins `topic calculation failed: `.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of rows with `timestamp`, `open`, `high`, `low`, `close` and `volume`, strictly ordered by timestamp. The cycles family reads one key from `parameters`, `period`, defaulting to 20 and required to be an integer of at least 4; it is validated for this topic but its arithmetic never uses it.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "One series, `phase`, mirrored as `latest.phase`, holding the angle in radians on the `atan2` range. `parameters` echoes the supplied parameters and `diagnostics` reports `causal` and `input_count`. Warm-up is six leading nulls, so `ready_at` is 6."
        },
        "warmup": {
          "count": 6,
          "value": null,
          "note": "The 4-bar EMA of `close` first resolves at index 3, and the quadrature filter reads the detrended value at the current bar plus the three before it, so the first defined phase and `ready_at` are at index 6."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 4",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, a `timestamp` is missing or not strictly increasing, an OHLCV field is not finite, `volume` is negative, or `high` and `low` do not bracket `open` and `close`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "hilbertTransformDominantCyclePhase({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D09-F06-A02",
          "title": "Hilbert Transform Dominant Cycle Phase",
          "state": "calculated",
          "ready": true,
          "ready_at": 6,
          "series": {
            "phase": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "phase": 2.9490866862859964
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a02/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a02/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a02/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Hilbert Transform Dominant Cycle Phase calculation flow",
            "source": "flowchart LR\n    A[\"uniformly sampled finite prices with declared prefilter, c\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Hilbert Transform Dominant Cycle Phase convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Hilbert Transform Dominant Cycle Phase readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib cycle indicator group",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "SciPy analytic-signal documentation",
          "author": "The SciPy community",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-dominant-cycle-phase/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-dominant-cycle-phase/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F06-A03",
      "name": "Hilbert Transform Phasor Components",
      "headline": null,
      "slug": "hilbert-transform-phasor-components",
      "path": "statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-phasor-components",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F06",
        "family": "Hilbert and Ehlers Cycle Analytics",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-phasor-components",
        "entry": "hilbertTransformPhasorComponents",
        "params": [
          "input"
        ],
        "exports": [
          "hilbertTransformPhasorComponents"
        ],
        "archetype": "record-transform",
        "signature": "hilbertTransformPhasorComponents(input)"
      },
      "api": {
        "summary": "Exposes the raw phasor behind the Hilbert cycle family: the in-phase component, its quadrature partner from the four-tap filter, and the amplitude and angle they form. Any contract failure is rethrown as an `Error` whose message begins `topic calculation failed: `.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of rows with `timestamp`, `open`, `high`, `low`, `close` and `volume`, strictly ordered by timestamp. The cycles family reads one key from `parameters`, `period`, defaulting to 20 and required to be an integer of at least 4; it is validated for this topic but its arithmetic never uses it.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Four series, each mirrored in `latest`: `in_phase` is the detrended value lagged two bars, `quadrature` is the four-tap combination of the last four detrended values, `amplitude` is the Euclidean length of the two, and `phase` is their `atan2` angle in radians. `parameters` echoes the supplied parameters and `diagnostics` reports `causal` and `input_count`. All four share the same warm-up of six leading nulls, so `ready_at` is 6."
        },
        "warmup": {
          "count": 6,
          "value": null,
          "note": "The 4-bar EMA of `close` first resolves at index 3, and the quadrature filter reads the detrended value at the current bar plus the three before it, so all four series begin together at index 6."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 4",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, a `timestamp` is missing or not strictly increasing, an OHLCV field is not finite, `volume` is negative, or `high` and `low` do not bracket `open` and `close`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "hilbertTransformPhasorComponents({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D09-F06-A03",
          "title": "Hilbert Transform Phasor Components",
          "state": "calculated",
          "ready": true,
          "ready_at": 6,
          "series": {
            "in_phase": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "quadrature": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "amplitude": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "phase": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "in_phase": -0.8607335347476948,
            "quadrature": 0.16777396655856047,
            "amplitude": 0.8769323358697945,
            "phase": 2.9490866862859964
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a03/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a03/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a03/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Hilbert Transform Phasor Components calculation flow",
            "source": "flowchart LR\n    A[\"uniformly sampled finite prices with declared prefilter, c\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Hilbert Transform Phasor Components convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Hilbert Transform Phasor Components readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib cycle indicator group",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "SciPy analytic-signal documentation",
          "author": "The SciPy community",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-phasor-components/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-phasor-components/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F06-A04",
      "name": "Hilbert Transform SineWave",
      "headline": null,
      "slug": "hilbert-transform-sinewave",
      "path": "statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-sinewave",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F06",
        "family": "Hilbert and Ehlers Cycle Analytics",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-sinewave",
        "entry": "hilbertTransformSinewave",
        "params": [
          "input"
        ],
        "exports": [
          "hilbertTransformSinewave"
        ],
        "archetype": "record-transform",
        "signature": "hilbertTransformSinewave(input)"
      },
      "api": {
        "summary": "Turns the Hilbert phase angle into the classic sinewave pair, the sine of the phase and a lead sine shifted a quarter turn ahead, whose crossings are the usual cycle-turn signal. Any contract failure is rethrown as an `Error` whose message begins `topic calculation failed: `.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of rows with `timestamp`, `open`, `high`, `low`, `close` and `volume`, strictly ordered by timestamp. The cycles family reads one key from `parameters`, `period`, defaulting to 20 and required to be an integer of at least 4; it is validated for this topic but its arithmetic never uses it.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Two series, `sine` and `lead_sine`, mirrored as `latest.sine` and `latest.lead_sine`. `sine` is the sine of the phase and `lead_sine` is the sine of the phase advanced by a quarter turn, so both stay within -1 to 1. `parameters` echoes the supplied parameters and `diagnostics` reports `causal` and `input_count`. Warm-up is six leading nulls in both series, so `ready_at` is 6."
        },
        "warmup": {
          "count": 6,
          "value": null,
          "note": "Both series are functions of the phase, which needs the 4-bar EMA of `close` to resolve at index 3 and three further bars for the quadrature filter, so they begin at index 6."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 4",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, a `timestamp` is missing or not strictly increasing, an OHLCV field is not finite, `volume` is negative, or `high` and `low` do not bracket `open` and `close`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "hilbertTransformSinewave({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D09-F06-A04",
          "title": "Hilbert Transform SineWave",
          "state": "calculated",
          "ready": true,
          "ready_at": 6,
          "series": {
            "sine": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "lead_sine": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "sine": 0.19131916990169168,
            "lead_sine": -0.5587619360262619
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a04/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a04/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a04/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Hilbert Transform SineWave calculation flow",
            "source": "flowchart LR\n    A[\"uniformly sampled finite prices with declared prefilter, c\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Hilbert Transform SineWave convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Hilbert Transform SineWave readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib cycle indicator group",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "SciPy analytic-signal documentation",
          "author": "The SciPy community",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-sinewave/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-sinewave/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F06-A05",
      "name": "Hilbert Transform Trend/Cycle Mode",
      "headline": null,
      "slug": "hilbert-transform-trend-cycle-mode",
      "path": "statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-trend-cycle-mode",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F06",
        "family": "Hilbert and Ehlers Cycle Analytics",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-trend-cycle-mode",
        "entry": "hilbertTransformTrendCycleMode",
        "params": [
          "input"
        ],
        "exports": [
          "hilbertTransformTrendCycleMode"
        ],
        "archetype": "record-transform",
        "signature": "hilbertTransformTrendCycleMode(input)"
      },
      "api": {
        "summary": "Labels each bar `trend` or `cycle` by asking whether the distance from `close` to its exponential trend exceeds 1.5 times the current Hilbert phasor amplitude. Any contract failure is rethrown as an `Error` whose message begins `topic calculation failed: `.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of rows with `timestamp`, `open`, `high`, `low`, `close` and `volume`, strictly ordered by timestamp. This topic genuinely uses `parameters.period`, which defaults to 20 and must be an integer of at least 4; it is the span of the `close` EMA that supplies the `trend` series.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Three series, each mirrored in `latest`: `mode` is the text `trend` or `cycle`, `trend` is the EMA of `close` over `period`, and `amplitude` is the Hilbert phasor magnitude. `parameters` echoes the supplied parameters and `diagnostics` reports `causal` and `input_count`. The series have different warm-ups and `ready_at` follows the earliest of them, 6."
        },
        "warmup": {
          "count": "6 nulls for `amplitude`, and `period - 1` nulls for `trend` and `mode` (19 at the default period of 20)",
          "value": null,
          "note": "`amplitude` needs the 4-bar EMA of `close` plus three bars of the quadrature filter, so it starts at index 6 and sets `ready_at` to 6. `trend` is an EMA seeded from the first full window of `period` closes, so it starts at index `period - 1`, and `mode` needs both, so it starts with `trend`."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 4",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, a `timestamp` is missing or not strictly increasing, an OHLCV field is not finite, `volume` is negative, or `high` and `low` do not bracket `open` and `close`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "hilbertTransformTrendCycleMode({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D09-F06-A05",
          "title": "Hilbert Transform Trend/Cycle Mode",
          "state": "calculated",
          "ready": true,
          "ready_at": 6,
          "series": {
            "mode": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "trend": [
              null,
              null,
              null,
              null,
              null,
              null
            ],
            "amplitude": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "mode": "trend",
            "trend": 103.9546773984291,
            "amplitude": 0.8769323358697945
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a05/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a05/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a05/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Hilbert Transform Trend/Cycle Mode calculation flow",
            "source": "flowchart LR\n    A[\"uniformly sampled finite prices with declared prefilter, c\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Hilbert Transform Trend/Cycle Mode convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Hilbert Transform Trend/Cycle Mode readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib cycle indicator group",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "SciPy analytic-signal documentation",
          "author": "The SciPy community",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-trend-cycle-mode/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/hilbert-and-ehlers-cycle-analytics/hilbert-transform-trend-cycle-mode/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F06-A06",
      "name": "Ehlers Cyber Cycle",
      "headline": null,
      "slug": "ehlers-cyber-cycle",
      "path": "statistical-time-series/hilbert-and-ehlers-cycle-analytics/ehlers-cyber-cycle",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F06",
        "family": "Hilbert and Ehlers Cycle Analytics",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/hilbert-and-ehlers-cycle-analytics/ehlers-cyber-cycle",
        "entry": "ehlersCyberCycle",
        "params": [
          "input"
        ],
        "exports": [
          "ehlersCyberCycle"
        ],
        "archetype": "record-transform",
        "signature": "ehlersCyberCycle(input)"
      },
      "api": {
        "summary": "Runs `close` through a two-pole high-pass filter tuned to `period`, then smooths the residual with an EMA of the same span, leaving an oscillator centred on zero that tracks the shorter-than-`period` swings. Any contract failure is rethrown as an `Error` whose message begins `topic calculation failed: `.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of rows with `timestamp`, `open`, `high`, `low`, `close` and `volume`, strictly ordered by timestamp. This topic genuinely uses `parameters.period`, which defaults to 20 and must be an integer of at least 4; it sets both the high-pass cutoff coefficient and the span of the EMA applied afterwards.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "One series, `value`, mirrored as `latest.value`, holding the smoothed high-pass residual in price units and oscillating about zero. `parameters` echoes the supplied parameters and `diagnostics` reports `causal` and `input_count`. Warm-up is `period - 1` leading nulls, which is 19 at the default period, and `ready_at` matches it."
        },
        "warmup": {
          "count": "`period - 1` (19 at the default period of 20)",
          "value": null,
          "note": "The high-pass recursion itself emits a number from the first bar, seeding the first two bars at zero, but the EMA laid over it is seeded from the first full window of `period` values, so `value` and `ready_at` begin at index `period - 1`."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 4",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, a `timestamp` is missing or not strictly increasing, an OHLCV field is not finite, `volume` is negative, or `high` and `low` do not bracket `open` and `close`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "ehlersCyberCycle({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D09-F06-A06",
          "title": "Ehlers Cyber Cycle",
          "state": "calculated",
          "ready": true,
          "ready_at": 19,
          "series": {
            "value": [
              null,
              null,
              null,
              null,
              null,
              null
            ]
          },
          "latest": {
            "value": -0.5033672802018834
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a06/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a06/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a06/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a06/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Ehlers Cyber Cycle calculation flow",
            "source": "flowchart LR\n    A[\"uniformly sampled finite prices with declared prefilter, c\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Ehlers Cyber Cycle convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Ehlers Cyber Cycle readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib cycle indicator group",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "SciPy analytic-signal documentation",
          "author": "The SciPy community",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/hilbert-and-ehlers-cycle-analytics/ehlers-cyber-cycle/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/hilbert-and-ehlers-cycle-analytics/ehlers-cyber-cycle/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F06-A07",
      "name": "Ehlers Roofing Filter",
      "headline": null,
      "slug": "ehlers-roofing-filter",
      "path": "statistical-time-series/hilbert-and-ehlers-cycle-analytics/ehlers-roofing-filter",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F06",
        "family": "Hilbert and Ehlers Cycle Analytics",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/hilbert-and-ehlers-cycle-analytics/ehlers-roofing-filter",
        "entry": "ehlersRoofingFilter",
        "params": [
          "input"
        ],
        "exports": [
          "ehlersRoofingFilter"
        ],
        "archetype": "record-transform",
        "signature": "ehlersRoofingFilter(input)"
      },
      "api": {
        "summary": "Stacks the two halves of a roof: a two-pole high-pass filter tuned to `period` removes the slow drift, and an Ehlers Super Smoother run at half that span removes the fast noise, leaving the band in between. Any contract failure is rethrown as an `Error` whose message begins `topic calculation failed: `.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of rows with `timestamp`, `open`, `high`, `low`, `close` and `volume`, strictly ordered by timestamp. This topic genuinely uses `parameters.period`, which defaults to 20 and must be an integer of at least 4; it sets the high-pass cutoff, and the smoother stage runs at `max(4, floor(period / 2))`, which is 10 by default.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Two series, both mirrored in `latest`: `high_pass` is the intermediate high-pass residual and `value` is that residual after the Super Smoother pass. `parameters` echoes the supplied parameters and `diagnostics` reports `causal` and `input_count`. There is no null prefix at all, so the warm-up is zero bars and `ready_at` is 0."
        },
        "warmup": {
          "count": 0,
          "value": "no nulls are emitted",
          "note": "Both stages are seeded rather than gated. The high-pass recursion holds its first two outputs at zero, and the Super Smoother copies its input for its first two bars, so every index carries a number and `ready_at` is 0. The opening bars are seed values, not converged filter output."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 4",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, a `timestamp` is missing or not strictly increasing, an OHLCV field is not finite, `volume` is negative, or `high` and `low` do not bracket `open` and `close`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "ehlersRoofingFilter({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D09-F06-A07",
          "title": "Ehlers Roofing Filter",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "high_pass": [
              0,
              0,
              -0.46270692883549364,
              -1.335377436005075,
              -2.201684726094235,
              -2.614761522250397
            ],
            "value": [
              0,
              0,
              -0.058577494525456325,
              -0.29546823437612796,
              -0.7658592036228475,
              -1.375141122806132
            ]
          },
          "latest": {
            "high_pass": -1.4080590702156108,
            "value": -1.0173197105824179
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a07/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a07/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a07/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a07/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Ehlers Roofing Filter calculation flow",
            "source": "flowchart LR\n    A[\"uniformly sampled finite prices with declared prefilter, c\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Ehlers Roofing Filter convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Ehlers Roofing Filter readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib cycle indicator group",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "SciPy analytic-signal documentation",
          "author": "The SciPy community",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/hilbert-and-ehlers-cycle-analytics/ehlers-roofing-filter/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/hilbert-and-ehlers-cycle-analytics/ehlers-roofing-filter/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F06-A08",
      "name": "Ehlers Decycler",
      "headline": null,
      "slug": "ehlers-decycler",
      "path": "statistical-time-series/hilbert-and-ehlers-cycle-analytics/ehlers-decycler",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F06",
        "family": "Hilbert and Ehlers Cycle Analytics",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/hilbert-and-ehlers-cycle-analytics/ehlers-decycler",
        "entry": "ehlersDecycler",
        "params": [
          "input"
        ],
        "exports": [
          "ehlersDecycler"
        ],
        "archetype": "record-transform",
        "signature": "ehlersDecycler(input)"
      },
      "api": {
        "summary": "Subtracts a two-pole high-pass residual from `close`, leaving a trend line with the sub-`period` wiggle removed and far less lag than a moving average of the same span. Any contract failure is rethrown as an `Error` whose message begins `topic calculation failed: `.",
        "params": [
          {
            "name": "input",
            "type": "TopicInput",
            "required": true,
            "description": "`bars` is a non-empty array of rows with `timestamp`, `open`, `high`, `low`, `close` and `volume`, strictly ordered by timestamp. This topic genuinely uses `parameters.period`, which defaults to 20 and must be an integer of at least 4; it sets the high-pass cutoff coefficient and so decides which cycles are removed.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Two series, both mirrored in `latest`: `high_pass` is the removed high-frequency residual and `value` is `close` minus that residual, in price units. `parameters` echoes the supplied parameters and `diagnostics` reports `causal` and `input_count`. There is no null prefix at all, so the warm-up is zero bars and `ready_at` is 0."
        },
        "warmup": {
          "count": 0,
          "value": "no nulls are emitted",
          "note": "The high-pass recursion holds its first two outputs at zero rather than leaving them null, so `high_pass` is defined from index 0 and `value` simply equals `close` there. `ready_at` is 0, but the opening bars are seed values rather than converged filter output."
        },
        "errors": [
          {
            "when": "`parameters.period` is present but is not an integer of at least 4",
            "behaviour": "throws Error"
          },
          {
            "when": "`bars` is empty, a `timestamp` is missing or not strictly increasing, an OHLCV field is not finite, `volume` is negative, or `high` and `low` do not bracket `open` and `close`",
            "behaviour": "throws Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "ehlersDecycler({\"bars\":[{\"timestamp\":\"2024-01-02\",\"basis\":\"synthetic-unadjusted\",\"open\":100,\"high\":101.45,\"low\":98.695,\"close\":100,\"volume\":750000,\"benchmark\":200},{\"timestamp\":\"2024-01-03\",\"basis\":\"synthetic-unadjusted\",\"open\":101.49111452,\"high\":103.38381693,\"low\":100.05480022,\"close\":101.78791214,\"volume\":795117,\"benchmark\":200.56326135},{\"timestamp\":\"2024-01-04\",\"basis\":\"synthetic-unadjusted\",\"open\":102.45519048,\"high\":104.6701838,\"low\":100.91147007,\"close\":102.9549389,\"volume\":840234,\"benchmark\":201.11020913}],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2024-01-02",
                  "basis": "synthetic-unadjusted",
                  "open": 100,
                  "high": 101.45,
                  "low": 98.695,
                  "close": 100,
                  "volume": 750000,
                  "benchmark": 200
                },
                {
                  "timestamp": "2024-01-03",
                  "basis": "synthetic-unadjusted",
                  "open": 101.49111452,
                  "high": 103.38381693,
                  "low": 100.05480022,
                  "close": 101.78791214,
                  "volume": 795117,
                  "benchmark": 200.56326135
                },
                {
                  "timestamp": "2024-01-04",
                  "basis": "synthetic-unadjusted",
                  "open": 102.45519048,
                  "high": 104.6701838,
                  "low": 100.91147007,
                  "close": 102.9549389,
                  "volume": 840234,
                  "benchmark": 201.11020913
                }
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D09-F06-A08",
          "title": "Ehlers Decycler",
          "state": "calculated",
          "ready": true,
          "ready_at": 0,
          "series": {
            "high_pass": [
              0,
              0,
              -0.46270692883549364,
              -1.335377436005075,
              -2.201684726094235,
              -2.614761522250397
            ],
            "value": [
              100,
              101.78791214,
              103.41764582883549,
              104.56766012600508,
              105.03298485609423,
              104.8834874922504
            ]
          },
          "latest": {
            "high_pass": -1.4080590702156108,
            "value": 101.39887354021562
          },
          "parameters": {},
          "diagnostics": {
            "causal": true,
            "input_count": 96
          }
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: topic_id, title, state, ready, ready_at, series, latest, parameters, …"
      },
      "verification": {
        "tier": "verified",
        "via": "E"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a08/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a08/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a08/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d09-f06-a08/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Ehlers Decycler calculation flow",
            "source": "flowchart LR\n    A[\"uniformly sampled finite prices with declared prefilter, c\"] --> B[\"Validate order, basis, and finite values\"]\n    B --> C[\"Apply the selected Ehlers Decycler convention\"]\n    C --> D[\"Emit value, readiness, and diagnostics\"]\n    D --> E[\"Interpret descriptively; test outcomes separately\"]\n    B -->|invalid or insufficient| X[\"Withhold output with a reason\"]"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Ehlers Decycler readiness and evidence states",
            "source": "stateDiagram-v2\n    [*] --> Waiting\n    Waiting --> Ready: enough valid causal observations\n    Waiting --> Rejected: malformed or unsupported input\n    Ready --> Calculated: selected formula applied\n    Calculated --> Interpreted: diagnostic and limitation retained\n    Interpreted --> Ready: next observation arrives\n    Rejected --> Waiting: corrected input and deterministic reset"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "TA-Lib cycle indicator group",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "S2",
          "title": "SciPy analytic-signal documentation",
          "author": "The SciPy community",
          "url": null
        },
        {
          "key": "S3",
          "title": "TA-Lib maintained source",
          "author": "TA-Lib project contributors",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        },
        {
          "key": "Level 1 evidence map",
          "title": "Level 1 evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/hilbert-and-ehlers-cycle-analytics/ehlers-decycler/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/hilbert-and-ehlers-cycle-analytics/ehlers-decycler/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F01-A01",
      "name": "Close-to-Close Volatility",
      "headline": null,
      "slug": "close-to-close-volatility",
      "path": "volatility-and-covariance/historical-estimators/close-to-close-volatility",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F01",
        "family": "Historical Estimators",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/historical-estimators/close-to-close-volatility",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Observe a close shock enter and leave centered return dispersion. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(nw)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"bars\":[{\"timestamp\":\"2026-01-01T09:00:00Z\",\"open\":99.50124791926824,\"close\":100,\"high\":101.00501670841679,\"low\":98.51119396030626},{\"timestamp\":\"2026-01-02T09:00:00Z\",\"open\":100.5012520859401,\"close\":101.00501670841679,\"high\":102.02013400267558,\"low\":99.50124791926824},{\"timestamp\":\"2026-01-03T09:00:00Z\",\"open\":98.51119396030626,\"close\":99.0049833749168,\"high\":100,\"low\":97.53099120283326}],\"parameters\":{\"window\":2,\"annualization_factor\":1}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2026-01-01T09:00:00Z",
                  "open": 99.50124791926824,
                  "close": 100,
                  "high": 101.00501670841679,
                  "low": 98.51119396030626
                },
                {
                  "timestamp": "2026-01-02T09:00:00Z",
                  "open": 100.5012520859401,
                  "close": 101.00501670841679,
                  "high": 102.02013400267558,
                  "low": 99.50124791926824
                },
                {
                  "timestamp": "2026-01-03T09:00:00Z",
                  "open": 98.51119396030626,
                  "close": 99.0049833749168,
                  "high": 100,
                  "low": 97.53099120283326
                }
              ],
              "parameters": {
                "window": 2,
                "annualization_factor": 1
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F01-A01",
          "title": "Close-to-Close Volatility",
          "parameters": {
            "window": 2,
            "annualization_factor": 1
          },
          "series": [
            null,
            null,
            {
              "timestamp": "2026-01-03T09:00:00Z",
              "variance": 0.0004499999999999914,
              "volatility": 0.021213203435596222,
              "contributions": [
                0.009999999999999893,
                -0.019999999999999823
              ],
              "components": {},
              "window_start": 1,
              "window_end": 2
            }
          ],
          "latest": {
            "timestamp": "2026-01-03T09:00:00Z",
            "variance": 0.0004499999999999914,
            "volatility": 0.021213203435596222,
            "contributions": [
              0.009999999999999893,
              -0.019999999999999823
            ],
            "components": {},
            "window_start": 1,
            "window_end": 2
          },
          "ready": true,
          "ready_at": 2,
          "diagnostics": {
            "input_count": 3,
            "annualization_factor": 1,
            "causal": true
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, series, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a01/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a01/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a01/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Close-to-Close Volatility — calculation-flow",
            "source": "flowchart TD\n    N0[\"Closes → log returns\"]\n    N1[\"Center the active returns\"]\n    N2[\"Divide squared deviations by w−1\"]\n    N3[\"Scale variance; take square root\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Close-to-Close Volatility — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"Close-to-Close Volatility calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/historical-estimators/close-to-close-volatility/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/historical-estimators/close-to-close-volatility/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F01-A02",
      "name": "Parkinson Volatility",
      "headline": null,
      "slug": "parkinson-volatility",
      "path": "volatility-and-covariance/historical-estimators/parkinson-volatility",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F01",
        "family": "Historical Estimators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/historical-estimators/parkinson-volatility",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Change intraday range while keeping endpoint prices fixed. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(nw)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"bars\":[{\"timestamp\":\"2026-01-01T09:00:00Z\",\"open\":99.50124791926824,\"close\":100,\"high\":101.00501670841679,\"low\":98.51119396030626},{\"timestamp\":\"2026-01-02T09:00:00Z\",\"open\":100.5012520859401,\"close\":101.00501670841679,\"high\":102.02013400267558,\"low\":99.50124791926824},{\"timestamp\":\"2026-01-03T09:00:00Z\",\"open\":98.51119396030626,\"close\":99.0049833749168,\"high\":100,\"low\":97.53099120283326}],\"parameters\":{\"window\":2,\"annualization_factor\":1}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2026-01-01T09:00:00Z",
                  "open": 99.50124791926824,
                  "close": 100,
                  "high": 101.00501670841679,
                  "low": 98.51119396030626
                },
                {
                  "timestamp": "2026-01-02T09:00:00Z",
                  "open": 100.5012520859401,
                  "close": 101.00501670841679,
                  "high": 102.02013400267558,
                  "low": 99.50124791926824
                },
                {
                  "timestamp": "2026-01-03T09:00:00Z",
                  "open": 98.51119396030626,
                  "close": 99.0049833749168,
                  "high": 100,
                  "low": 97.53099120283326
                }
              ],
              "parameters": {
                "window": 2,
                "annualization_factor": 1
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F01-A02",
          "title": "Parkinson Volatility",
          "parameters": {
            "window": 2,
            "annualization_factor": 1
          },
          "series": [
            null,
            {
              "timestamp": "2026-01-02T09:00:00Z",
              "variance": 0.00022542110013889886,
              "volatility": 0.015014030109830568,
              "contributions": [
                0.00022542110013890082,
                0.00022542110013889694
              ],
              "components": {},
              "window_start": 0,
              "window_end": 1
            },
            {
              "timestamp": "2026-01-03T09:00:00Z",
              "variance": 0.00022542110013889886,
              "volatility": 0.015014030109830568,
              "contributions": [
                0.00022542110013889694,
                0.00022542110013890082
              ],
              "components": {},
              "window_start": 1,
              "window_end": 2
            }
          ],
          "latest": {
            "timestamp": "2026-01-03T09:00:00Z",
            "variance": 0.00022542110013889886,
            "volatility": 0.015014030109830568,
            "contributions": [
              0.00022542110013889694,
              0.00022542110013890082
            ],
            "components": {},
            "window_start": 1,
            "window_end": 2
          },
          "ready": true,
          "ready_at": 1,
          "diagnostics": {
            "input_count": 3,
            "annualization_factor": 1,
            "causal": true
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, series, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a02/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a02/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a02/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Parkinson Volatility — calculation-flow",
            "source": "flowchart TD\n    N0[\"Validate bracketed prices\"]\n    N1[\"Log high/low range\"]\n    N2[\"Square and divide by 4 ln 2\"]\n    N3[\"Average same-session contributions\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Parkinson Volatility — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"Parkinson Volatility calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/historical-estimators/parkinson-volatility/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/historical-estimators/parkinson-volatility/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F01-A03",
      "name": "Garman-Klass Volatility",
      "headline": null,
      "slug": "garman-klass-volatility",
      "path": "volatility-and-covariance/historical-estimators/garman-klass-volatility",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F01",
        "family": "Historical Estimators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/historical-estimators/garman-klass-volatility",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "See the range term and body correction under valid OHLC geometry. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(nw)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"bars\":[{\"timestamp\":\"2026-01-01T09:00:00Z\",\"open\":99.50124791926824,\"close\":100,\"high\":101.00501670841679,\"low\":98.51119396030626},{\"timestamp\":\"2026-01-02T09:00:00Z\",\"open\":100.5012520859401,\"close\":101.00501670841679,\"high\":102.02013400267558,\"low\":99.50124791926824},{\"timestamp\":\"2026-01-03T09:00:00Z\",\"open\":98.51119396030626,\"close\":99.0049833749168,\"high\":100,\"low\":97.53099120283326}],\"parameters\":{\"window\":2,\"annualization_factor\":1}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2026-01-01T09:00:00Z",
                  "open": 99.50124791926824,
                  "close": 100,
                  "high": 101.00501670841679,
                  "low": 98.51119396030626
                },
                {
                  "timestamp": "2026-01-02T09:00:00Z",
                  "open": 100.5012520859401,
                  "close": 101.00501670841679,
                  "high": 102.02013400267558,
                  "low": 99.50124791926824
                },
                {
                  "timestamp": "2026-01-03T09:00:00Z",
                  "open": 98.51119396030626,
                  "close": 99.0049833749168,
                  "high": 100,
                  "low": 97.53099120283326
                }
              ],
              "parameters": {
                "window": 2,
                "annualization_factor": 1
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F01-A03",
          "title": "Garman-Klass Volatility",
          "parameters": {
            "window": 2,
            "annualization_factor": 1
          },
          "series": [
            null,
            {
              "timestamp": "2026-01-02T09:00:00Z",
              "variance": 0.00030284264097200084,
              "volatility": 0.01740237457854533,
              "contributions": [
                0.0003028426409720035,
                0.00030284264097199813
              ],
              "components": {},
              "window_start": 0,
              "window_end": 1
            },
            {
              "timestamp": "2026-01-03T09:00:00Z",
              "variance": 0.0003028426409720004,
              "volatility": 0.01740237457854532,
              "contributions": [
                0.00030284264097199813,
                0.0003028426409720027
              ],
              "components": {},
              "window_start": 1,
              "window_end": 2
            }
          ],
          "latest": {
            "timestamp": "2026-01-03T09:00:00Z",
            "variance": 0.0003028426409720004,
            "volatility": 0.01740237457854532,
            "contributions": [
              0.00030284264097199813,
              0.0003028426409720027
            ],
            "components": {},
            "window_start": 1,
            "window_end": 2
          },
          "ready": true,
          "ready_at": 1,
          "diagnostics": {
            "input_count": 3,
            "annualization_factor": 1,
            "causal": true
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, series, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a03/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a03/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a03/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Garman-Klass Volatility — calculation-flow",
            "source": "flowchart TD\n    N0[\"Measure log range and body\"]\n    N1[\"Half of squared log range\"]\n    N2[\"Subtract weighted squared body\"]\n    N3[\"Check nonnegative contribution\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Garman-Klass Volatility — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"Garman-Klass Volatility calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/historical-estimators/garman-klass-volatility/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/historical-estimators/garman-klass-volatility/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F01-A04",
      "name": "Rogers-Satchell Volatility",
      "headline": null,
      "slug": "rogers-satchell-volatility",
      "path": "volatility-and-covariance/historical-estimators/rogers-satchell-volatility",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F01",
        "family": "Historical Estimators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/historical-estimators/rogers-satchell-volatility",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Track the upper and lower log-distance products. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(nw)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"bars\":[{\"timestamp\":\"2026-01-01T09:00:00Z\",\"open\":99.50124791926824,\"close\":100,\"high\":101.00501670841679,\"low\":98.51119396030626},{\"timestamp\":\"2026-01-02T09:00:00Z\",\"open\":100.5012520859401,\"close\":101.00501670841679,\"high\":102.02013400267558,\"low\":99.50124791926824},{\"timestamp\":\"2026-01-03T09:00:00Z\",\"open\":98.51119396030626,\"close\":99.0049833749168,\"high\":100,\"low\":97.53099120283326}],\"parameters\":{\"window\":2,\"annualization_factor\":1}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2026-01-01T09:00:00Z",
                  "open": 99.50124791926824,
                  "close": 100,
                  "high": 101.00501670841679,
                  "low": 98.51119396030626
                },
                {
                  "timestamp": "2026-01-02T09:00:00Z",
                  "open": 100.5012520859401,
                  "close": 101.00501670841679,
                  "high": 102.02013400267558,
                  "low": 99.50124791926824
                },
                {
                  "timestamp": "2026-01-03T09:00:00Z",
                  "open": 98.51119396030626,
                  "close": 99.0049833749168,
                  "high": 100,
                  "low": 97.53099120283326
                }
              ],
              "parameters": {
                "window": 2,
                "annualization_factor": 1
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F01-A04",
          "title": "Rogers-Satchell Volatility",
          "parameters": {
            "window": 2,
            "annualization_factor": 1
          },
          "series": [
            null,
            {
              "timestamp": "2026-01-02T09:00:00Z",
              "variance": 0.00029999999999999916,
              "volatility": 0.01732050807568875,
              "contributions": [
                0.00029999999999999954,
                0.00029999999999999884
              ],
              "components": {},
              "window_start": 0,
              "window_end": 1
            },
            {
              "timestamp": "2026-01-03T09:00:00Z",
              "variance": 0.0003000000000000008,
              "volatility": 0.017320508075688797,
              "contributions": [
                0.00029999999999999884,
                0.00030000000000000274
              ],
              "components": {},
              "window_start": 1,
              "window_end": 2
            }
          ],
          "latest": {
            "timestamp": "2026-01-03T09:00:00Z",
            "variance": 0.0003000000000000008,
            "volatility": 0.017320508075688797,
            "contributions": [
              0.00029999999999999884,
              0.00030000000000000274
            ],
            "components": {},
            "window_start": 1,
            "window_end": 2
          },
          "ready": true,
          "ready_at": 1,
          "diagnostics": {
            "input_count": 3,
            "annualization_factor": 1,
            "causal": true
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, series, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a04/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a04/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a04/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Rogers-Satchell Volatility — calculation-flow",
            "source": "flowchart TD\n    N0[\"High relative to open and close\"]\n    N1[\"Low relative to open and close\"]\n    N2[\"Add the two nonnegative products\"]\n    N3[\"Average inside the chosen window\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Rogers-Satchell Volatility — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"Rogers-Satchell Volatility calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/historical-estimators/rogers-satchell-volatility/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/historical-estimators/rogers-satchell-volatility/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F01-A05",
      "name": "Yang-Zhang Volatility",
      "headline": null,
      "slug": "yang-zhang-volatility",
      "path": "volatility-and-covariance/historical-estimators/yang-zhang-volatility",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F01",
        "family": "Historical Estimators",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/historical-estimators/yang-zhang-volatility",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Separate overnight, weighted body and weighted range contributions. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(nw)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"bars\":[{\"timestamp\":\"2026-01-01T09:00:00Z\",\"open\":99.50124791926824,\"close\":100,\"high\":101.00501670841679,\"low\":98.51119396030626},{\"timestamp\":\"2026-01-02T09:00:00Z\",\"open\":100.5012520859401,\"close\":101.00501670841679,\"high\":102.02013400267558,\"low\":99.50124791926824},{\"timestamp\":\"2026-01-03T09:00:00Z\",\"open\":98.51119396030626,\"close\":99.0049833749168,\"high\":100,\"low\":97.53099120283326}],\"parameters\":{\"window\":2,\"annualization_factor\":1}})",
        "args": [
          {
            "value": {
              "bars": [
                {
                  "timestamp": "2026-01-01T09:00:00Z",
                  "open": 99.50124791926824,
                  "close": 100,
                  "high": 101.00501670841679,
                  "low": 98.51119396030626
                },
                {
                  "timestamp": "2026-01-02T09:00:00Z",
                  "open": 100.5012520859401,
                  "close": 101.00501670841679,
                  "high": 102.02013400267558,
                  "low": 99.50124791926824
                },
                {
                  "timestamp": "2026-01-03T09:00:00Z",
                  "open": 98.51119396030626,
                  "close": 99.0049833749168,
                  "high": 100,
                  "low": 97.53099120283326
                }
              ],
              "parameters": {
                "window": 2,
                "annualization_factor": 1
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F01-A05",
          "title": "Yang-Zhang Volatility",
          "parameters": {
            "window": 2,
            "annualization_factor": 1
          },
          "series": [
            null,
            null,
            {
              "timestamp": "2026-01-03T09:00:00Z",
              "variance": 0.0007264976958525304,
              "volatility": 0.026953621201102652,
              "contributions": [
                [
                  0.004999999999999897,
                  0.004999999999999897,
                  0.00029999999999999884
                ],
                [
                  -0.024999999999999942,
                  0.005000000000000118,
                  0.00030000000000000274
                ]
              ],
              "components": {
                "overnight": 0.00044999999999999516,
                "open_close": 1.9162261030955815e-33,
                "range": 0.00027649769585253527,
                "k": 0.0783410138248848
              },
              "window_start": 1,
              "window_end": 2
            }
          ],
          "latest": {
            "timestamp": "2026-01-03T09:00:00Z",
            "variance": 0.0007264976958525304,
            "volatility": 0.026953621201102652,
            "contributions": [
              [
                0.004999999999999897,
                0.004999999999999897,
                0.00029999999999999884
              ],
              [
                -0.024999999999999942,
                0.005000000000000118,
                0.00030000000000000274
              ]
            ],
            "components": {
              "overnight": 0.00044999999999999516,
              "open_close": 1.9162261030955815e-33,
              "range": 0.00027649769585253527,
              "k": 0.0783410138248848
            },
            "window_start": 1,
            "window_end": 2
          },
          "ready": true,
          "ready_at": 2,
          "diagnostics": {
            "input_count": 3,
            "annualization_factor": 1,
            "causal": true
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, series, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a05/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a05/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a05/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f01-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Yang-Zhang Volatility — calculation-flow",
            "source": "flowchart TD\n    N0[\"Previous close → opening return\"]\n    N1[\"Sample overnight/body variances\"]\n    N2[\"Compute w-dependent k and RS mean\"]\n    N3[\"Add weighted variance components\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Yang-Zhang Volatility — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"Yang-Zhang Volatility calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/historical-estimators/yang-zhang-volatility/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/historical-estimators/yang-zhang-volatility/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F02-A01",
      "name": "Realized Variance",
      "headline": null,
      "slug": "realized-variance",
      "path": "volatility-and-covariance/realized-measures/realized-variance",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F02",
        "family": "Realized Measures",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/realized-measures/realized-variance",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Identify which squared return dominates the measured variation. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(nw)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"returns\":[0.01,-0.02,0.03,-0.01],\"parameters\":{\"window\":4,\"annualization_factor\":1}})",
        "args": [
          {
            "value": {
              "returns": [
                0.01,
                -0.02,
                0.03,
                -0.01
              ],
              "parameters": {
                "window": 4,
                "annualization_factor": 1
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F02-A01",
          "title": "Realized Variance",
          "parameters": {
            "window": 4,
            "annualization_factor": 1
          },
          "series": [
            null,
            null,
            null,
            {
              "variance": 0.0015,
              "volatility": 0.03872983346207417,
              "contributions": [
                0.0001,
                0.0004,
                0.0009,
                0.0001
              ],
              "window_start": 0,
              "window_end": 3
            }
          ],
          "latest": {
            "variance": 0.0015,
            "volatility": 0.03872983346207417,
            "contributions": [
              0.0001,
              0.0004,
              0.0009,
              0.0001
            ],
            "window_start": 0,
            "window_end": 3
          },
          "ready": true,
          "ready_at": 3,
          "diagnostics": {
            "causal": true,
            "input_count": 4,
            "annualization_factor": 1
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, series, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a01/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a01/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a01/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Realized Variance — calculation-flow",
            "source": "flowchart TD\n    N0[\"Choose regular return grid\"]\n    N1[\"Square every retained return\"]\n    N2[\"Sum without demeaning or n divisor\"]\n    N3[\"Distinguish window scale from annual scale\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Realized Variance — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"Realized Variance calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/realized-measures/realized-variance/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/realized-measures/realized-variance/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F02-A02",
      "name": "Realized Covariance",
      "headline": null,
      "slug": "realized-covariance",
      "path": "volatility-and-covariance/realized-measures/realized-covariance",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F02",
        "family": "Realized Measures",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/realized-measures/realized-covariance",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Pair exact intervals, then inspect positive and negative products. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(nw)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"returns_x\":[0.01,-0.02,0.03,-0.01],\"returns_y\":[0.02,0.01,-0.01,-0.02],\"timestamps_x\":[\"2026-01-01T09:00:00Z\",\"2026-01-01T09:05:00Z\",\"2026-01-01T09:10:00Z\",\"2026-01-01T09:15:00Z\"],\"timestamps_y\":[\"2026-01-01T09:00:00Z\",\"2026-01-01T09:05:00Z\",\"2026-01-01T09:10:00Z\",\"2026-01-01T09:15:00Z\"],\"parameters\":{\"window\":4,\"annualization_factor\":1}})",
        "args": [
          {
            "value": {
              "returns_x": [
                0.01,
                -0.02,
                0.03,
                -0.01
              ],
              "returns_y": [
                0.02,
                0.01,
                -0.01,
                -0.02
              ],
              "timestamps_x": [
                "2026-01-01T09:00:00Z",
                "2026-01-01T09:05:00Z",
                "2026-01-01T09:10:00Z",
                "2026-01-01T09:15:00Z"
              ],
              "timestamps_y": [
                "2026-01-01T09:00:00Z",
                "2026-01-01T09:05:00Z",
                "2026-01-01T09:10:00Z",
                "2026-01-01T09:15:00Z"
              ],
              "parameters": {
                "window": 4,
                "annualization_factor": 1
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F02-A02",
          "title": "Realized Covariance",
          "parameters": {
            "window": 4,
            "annualization_factor": 1
          },
          "series": [
            null,
            null,
            null,
            {
              "covariance": -0.00009999999999999996,
              "contributions": [
                0.0002,
                -0.0002,
                -0.0003,
                0.0002
              ],
              "window_start": 0,
              "window_end": 3
            }
          ],
          "latest": {
            "covariance": -0.00009999999999999996,
            "contributions": [
              0.0002,
              -0.0002,
              -0.0003,
              0.0002
            ],
            "window_start": 0,
            "window_end": 3
          },
          "ready": true,
          "ready_at": 3,
          "diagnostics": {
            "causal": true,
            "input_count": 4,
            "annualization_factor": 1
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, series, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a02/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a02/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a02/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Realized Covariance — calculation-flow",
            "source": "flowchart TD\n    N0[\"Validate identical regular clocks\"]\n    N1[\"Pair x and y on each interval\"]\n    N2[\"Retain signed products\"]\n    N3[\"Sum co-movement, not correlation\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Realized Covariance — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"Realized Covariance calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/realized-measures/realized-covariance/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/realized-measures/realized-covariance/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F02-A03",
      "name": "Bipower Variation",
      "headline": null,
      "slug": "bipower-variation",
      "path": "volatility-and-covariance/realized-measures/bipower-variation",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F02",
        "family": "Realized Measures",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/realized-measures/bipower-variation",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "See how a shock affects its two adjacent absolute products. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(nw)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"returns\":[0.01,-0.02,0.03,-0.01],\"parameters\":{\"window\":4,\"annualization_factor\":1}})",
        "args": [
          {
            "value": {
              "returns": [
                0.01,
                -0.02,
                0.03,
                -0.01
              ],
              "parameters": {
                "window": 4,
                "annualization_factor": 1
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F02-A03",
          "title": "Bipower Variation",
          "parameters": {
            "window": 4,
            "annualization_factor": 1
          },
          "series": [
            null,
            null,
            null,
            {
              "realized_variance": 0.0015,
              "bipower_variation": 0.001727875959474386,
              "signed_difference": -0.000227875959474386,
              "jump_variation": 0,
              "contributions": [
                0.0003141592653589793,
                0.0009424777960769378,
                0.0004712388980384689
              ],
              "window_start": 0,
              "window_end": 3
            }
          ],
          "latest": {
            "realized_variance": 0.0015,
            "bipower_variation": 0.001727875959474386,
            "signed_difference": -0.000227875959474386,
            "jump_variation": 0,
            "contributions": [
              0.0003141592653589793,
              0.0009424777960769378,
              0.0004712388980384689
            ],
            "window_start": 0,
            "window_end": 3
          },
          "ready": true,
          "ready_at": 3,
          "diagnostics": {
            "causal": true,
            "input_count": 4,
            "annualization_factor": 1
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, series, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a03/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a03/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a03/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Bipower Variation — calculation-flow",
            "source": "flowchart TD\n    N0[\"Absolute neighboring magnitudes\"]\n    N1[\"Multiply adjacent pairs\"]\n    N2[\"Scale sum by π/2\"]\n    N3[\"Keep signed RV minus BV visible\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Bipower Variation — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"Bipower Variation calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/realized-measures/bipower-variation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/realized-measures/bipower-variation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F02-A04",
      "name": "Jump-Variation Detector",
      "headline": null,
      "slug": "jump-variation-detector",
      "path": "volatility-and-covariance/realized-measures/jump-variation-detector",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F02",
        "family": "Realized Measures",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/realized-measures/jump-variation-detector",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Separate the observed variation difference from its uncertainty and threshold. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(nw)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"returns\":[0.01,-0.02,0.03,-0.01],\"parameters\":{\"window\":4,\"annualization_factor\":1,\"alpha\":0.05}})",
        "args": [
          {
            "value": {
              "returns": [
                0.01,
                -0.02,
                0.03,
                -0.01
              ],
              "parameters": {
                "window": 4,
                "annualization_factor": 1,
                "alpha": 0.05
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F02-A04",
          "title": "Jump-Variation Detector",
          "parameters": {
            "window": 4,
            "annualization_factor": 1,
            "alpha": 0.05
          },
          "series": [
            null,
            null,
            null,
            {
              "realized_variance": 0.0015,
              "bipower_variation": 0.001727875959474386,
              "tripower_quarticity": 0.000003041375049273447,
              "standard_error": 0.0006804738070197237,
              "statistic": -0.33487837022326555,
              "critical_value": 1.644853625133699,
              "jump_detected": false,
              "decision_status": "asymptotic",
              "signed_difference": -0.000227875959474386,
              "window_start": 0,
              "window_end": 3
            }
          ],
          "latest": {
            "realized_variance": 0.0015,
            "bipower_variation": 0.001727875959474386,
            "tripower_quarticity": 0.000003041375049273447,
            "standard_error": 0.0006804738070197237,
            "statistic": -0.33487837022326555,
            "critical_value": 1.644853625133699,
            "jump_detected": false,
            "decision_status": "asymptotic",
            "signed_difference": -0.000227875959474386,
            "window_start": 0,
            "window_end": 3
          },
          "ready": true,
          "ready_at": 3,
          "diagnostics": {
            "causal": true,
            "input_count": 4,
            "annualization_factor": 1
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, series, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a04/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a04/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a04/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Jump-Variation Detector — calculation-flow",
            "source": "flowchart TD\n    N0[\"Compute RV and unadjusted BV\"]\n    N1[\"Compute tripower quarticity\"]\n    N2[\"Standardize signed RV minus BV\"]\n    N3[\"Compare Z with upper-tail quantile\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Jump-Variation Detector — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"Jump-Variation Detector calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/realized-measures/jump-variation-detector/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/realized-measures/jump-variation-detector/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F02-A05",
      "name": "Realized Kernel",
      "headline": null,
      "slug": "realized-kernel",
      "path": "volatility-and-covariance/realized-measures/realized-kernel",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F02",
        "family": "Realized Measures",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/realized-measures/realized-kernel",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Explain each weighted lag correction to realized variance. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(nwH)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"returns\":[0.01,-0.02,0.03,-0.01],\"parameters\":{\"window\":4,\"annualization_factor\":1,\"bandwidth\":1}})",
        "args": [
          {
            "value": {
              "returns": [
                0.01,
                -0.02,
                0.03,
                -0.01
              ],
              "parameters": {
                "window": 4,
                "annualization_factor": 1,
                "bandwidth": 1
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F02-A05",
          "title": "Realized Kernel",
          "parameters": {
            "window": 4,
            "annualization_factor": 1,
            "bandwidth": 1
          },
          "series": [
            null,
            null,
            null,
            {
              "realized_kernel": 0.0004000000000000002,
              "volatility": 0.020000000000000004,
              "bandwidth": 1,
              "lags": [
                {
                  "lag": 0,
                  "weight": 1,
                  "gamma": 0.0015,
                  "contribution": 0.0015
                },
                {
                  "lag": 1,
                  "weight": 0.5,
                  "gamma": -0.0010999999999999998,
                  "contribution": -0.0010999999999999998
                }
              ],
              "window_start": 0,
              "window_end": 3
            }
          ],
          "latest": {
            "realized_kernel": 0.0004000000000000002,
            "volatility": 0.020000000000000004,
            "bandwidth": 1,
            "lags": [
              {
                "lag": 0,
                "weight": 1,
                "gamma": 0.0015,
                "contribution": 0.0015
              },
              {
                "lag": 1,
                "weight": 0.5,
                "gamma": -0.0010999999999999998,
                "contribution": -0.0010999999999999998
              }
            ],
            "window_start": 0,
            "window_end": 3
          },
          "ready": true,
          "ready_at": 3,
          "diagnostics": {
            "causal": true,
            "input_count": 4,
            "annualization_factor": 1
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, series, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a05/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a05/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a05/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f02-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Realized Kernel — calculation-flow",
            "source": "flowchart TD\n    N0[\"Lag zero = realized variance\"]\n    N1[\"Compute signed lag products\"]\n    N2[\"Apply Bartlett weights and factor two\"]\n    N3[\"Sum the quadratic-form contributions\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Realized Kernel — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"Realized Kernel calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/realized-measures/realized-kernel/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/realized-measures/realized-kernel/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F03-A01",
      "name": "ARCH",
      "headline": null,
      "slug": "arch",
      "path": "volatility-and-covariance/conditional-volatility/arch",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F03",
        "family": "Conditional Volatility",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/conditional-volatility/arch",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Follow a squared shock through a finite coefficient queue. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(nq)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"returns\":[-0.02,0.01,0],\"parameters\":{\"omega\":0.000002,\"initial_variance\":0.0001,\"alphas\":[0.2,0.1]}})",
        "args": [
          {
            "value": {
              "returns": [
                -0.02,
                0.01,
                0
              ],
              "parameters": {
                "omega": 0.000002,
                "initial_variance": 0.0001,
                "alphas": [
                  0.2,
                  0.1
                ]
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F03-A01",
          "title": "ARCH",
          "parameters": {
            "omega": 0.000002,
            "initial_variance": 0.0001,
            "alphas": [
              0.2,
              0.1
            ]
          },
          "series": [
            null,
            null,
            {
              "index": 2,
              "variance": 0.000062,
              "intercept": 0.000002,
              "lag_contributions": [
                0.00002,
                0.00004
              ]
            }
          ],
          "latest": {
            "index": 2,
            "variance": 0.000062,
            "intercept": 0.000002,
            "lag_contributions": [
              0.00002,
              0.00004
            ]
          },
          "ready": true,
          "ready_at": 2,
          "diagnostics": {
            "causal": true,
            "input_count": 3,
            "fitted_parameters": false,
            "model": "arch"
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, series, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a01/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a01/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a01/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "ARCH — calculation-flow",
            "source": "flowchart TD\n    N0[\"Read only past residuals\"]\n    N1[\"Square each retained lag\"]\n    N2[\"Multiply by its own coefficient\"]\n    N3[\"Add intercept; current shock waits\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "ARCH — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"ARCH calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/conditional-volatility/arch/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/conditional-volatility/arch/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F03-A02",
      "name": "GARCH",
      "headline": null,
      "slug": "garch",
      "path": "volatility-and-covariance/conditional-volatility/garch",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F03",
        "family": "Conditional Volatility",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/conditional-volatility/garch",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Separate new shock information from carried variance. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"returns\":[-0.02,0.01,0],\"parameters\":{\"omega\":0.000002,\"initial_variance\":0.0001,\"alpha\":0.1,\"beta\":0.8}})",
        "args": [
          {
            "value": {
              "returns": [
                -0.02,
                0.01,
                0
              ],
              "parameters": {
                "omega": 0.000002,
                "initial_variance": 0.0001,
                "alpha": 0.1,
                "beta": 0.8
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F03-A02",
          "title": "GARCH",
          "parameters": {
            "omega": 0.000002,
            "initial_variance": 0.0001,
            "alpha": 0.1,
            "beta": 0.8
          },
          "series": [
            {
              "index": 0,
              "variance": 0.0001,
              "initialization": true
            },
            {
              "index": 1,
              "variance": 0.00012200000000000001,
              "intercept": 0.000002,
              "shock_contribution": 0.00004,
              "threshold_contribution": 0,
              "carry": 0.00008
            },
            {
              "index": 2,
              "variance": 0.00010960000000000001,
              "intercept": 0.000002,
              "shock_contribution": 0.00001,
              "threshold_contribution": 0,
              "carry": 0.00009760000000000001
            }
          ],
          "latest": {
            "index": 2,
            "variance": 0.00010960000000000001,
            "intercept": 0.000002,
            "shock_contribution": 0.00001,
            "threshold_contribution": 0,
            "carry": 0.00009760000000000001
          },
          "ready": true,
          "ready_at": 0,
          "diagnostics": {
            "causal": true,
            "input_count": 3,
            "fitted_parameters": false,
            "model": "garch"
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, series, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a02/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a02/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a02/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "GARCH — calculation-flow",
            "source": "flowchart TD\n    N0[\"Read explicit initial variance\"]\n    N1[\"Square previous residual\"]\n    N2[\"Add intercept and α shock term\"]\n    N3[\"Carry β times previous variance\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "GARCH — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"GARCH calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/conditional-volatility/garch/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/conditional-volatility/garch/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F03-A03",
      "name": "EGARCH",
      "headline": null,
      "slug": "egarch",
      "path": "volatility-and-covariance/conditional-volatility/egarch",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F03",
        "family": "Conditional Volatility",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/conditional-volatility/egarch",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Compare signed standardized shocks on the log-variance scale. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"returns\":[-0.02,0],\"parameters\":{\"omega\":-0.5,\"initial_variance\":0.0001,\"alpha\":0.1,\"beta\":0.9,\"gamma\":-0.2}})",
        "args": [
          {
            "value": {
              "returns": [
                -0.02,
                0
              ],
              "parameters": {
                "omega": -0.5,
                "initial_variance": 0.0001,
                "alpha": 0.1,
                "beta": 0.9,
                "gamma": -0.2
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F03-A03",
          "title": "EGARCH",
          "parameters": {
            "omega": -0.5,
            "initial_variance": 0.0001,
            "alpha": 0.1,
            "beta": 0.9,
            "gamma": -0.2
          },
          "series": [
            {
              "index": 0,
              "variance": 0.0001,
              "initialization": true
            },
            {
              "index": 1,
              "variance": 0.00025631720695395993,
              "log_variance": -8.26909479085885,
              "standardized_shock": -2,
              "intercept": -0.5,
              "carry": -8.289306334778564,
              "magnitude_contribution": 0.12021154391971348,
              "sign_contribution": 0.4
            }
          ],
          "latest": {
            "index": 1,
            "variance": 0.00025631720695395993,
            "log_variance": -8.26909479085885,
            "standardized_shock": -2,
            "intercept": -0.5,
            "carry": -8.289306334778564,
            "magnitude_contribution": 0.12021154391971348,
            "sign_contribution": 0.4
          },
          "ready": true,
          "ready_at": 0,
          "diagnostics": {
            "causal": true,
            "input_count": 2,
            "fitted_parameters": false,
            "model": "egarch"
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, series, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a03/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a03/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a03/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "EGARCH — calculation-flow",
            "source": "flowchart TD\n    N0[\"Standardize using previous variance\"]\n    N1[\"Center the shock magnitude\"]\n    N2[\"Add signed shock and carried log state\"]\n    N3[\"Exponentiate or reject numerical overflow\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "EGARCH — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"EGARCH calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/conditional-volatility/egarch/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/conditional-volatility/egarch/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F03-A04",
      "name": "GJR-GARCH",
      "headline": null,
      "slug": "gjr-garch",
      "path": "volatility-and-covariance/conditional-volatility/gjr-garch",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F03",
        "family": "Conditional Volatility",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/conditional-volatility/gjr-garch",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Isolate the extra term activated by a negative lagged residual. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"returns\":[-0.02,0.01,0],\"parameters\":{\"omega\":0.000002,\"initial_variance\":0.0001,\"alpha\":0.1,\"beta\":0.8,\"gamma\":0.1}})",
        "args": [
          {
            "value": {
              "returns": [
                -0.02,
                0.01,
                0
              ],
              "parameters": {
                "omega": 0.000002,
                "initial_variance": 0.0001,
                "alpha": 0.1,
                "beta": 0.8,
                "gamma": 0.1
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F03-A04",
          "title": "GJR-GARCH",
          "parameters": {
            "omega": 0.000002,
            "initial_variance": 0.0001,
            "alpha": 0.1,
            "beta": 0.8,
            "gamma": 0.1
          },
          "series": [
            {
              "index": 0,
              "variance": 0.0001,
              "initialization": true
            },
            {
              "index": 1,
              "variance": 0.00016200000000000003,
              "intercept": 0.000002,
              "shock_contribution": 0.00004,
              "threshold_contribution": 0.00004,
              "carry": 0.00008
            },
            {
              "index": 2,
              "variance": 0.00014160000000000003,
              "intercept": 0.000002,
              "shock_contribution": 0.00001,
              "threshold_contribution": 0,
              "carry": 0.00012960000000000003
            }
          ],
          "latest": {
            "index": 2,
            "variance": 0.00014160000000000003,
            "intercept": 0.000002,
            "shock_contribution": 0.00001,
            "threshold_contribution": 0,
            "carry": 0.00012960000000000003
          },
          "ready": true,
          "ready_at": 0,
          "diagnostics": {
            "causal": true,
            "input_count": 3,
            "fitted_parameters": false,
            "model": "gjr_garch"
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, series, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a04/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a04/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a04/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "GJR-GARCH — calculation-flow",
            "source": "flowchart TD\n    N0[\"Read previous residual sign\"]\n    N1[\"Compute ordinary squared-shock term\"]\n    N2[\"Activate γ term only below zero\"]\n    N3[\"Add intercept and carried variance\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "GJR-GARCH — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"GJR-GARCH calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/conditional-volatility/gjr-garch/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/conditional-volatility/gjr-garch/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F03-A05",
      "name": "FIGARCH",
      "headline": null,
      "slug": "figarch",
      "path": "volatility-and-covariance/conditional-volatility/figarch",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F03",
        "family": "Conditional Volatility",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/conditional-volatility/figarch",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Keep retained fractional weights and omitted backcast mass separate. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(nm)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"returns\":[-0.02,0.01,0],\"parameters\":{\"omega\":0.000002,\"initial_variance\":0.0001,\"d\":0.4,\"truncation\":2,\"backcast_variance\":0.0001}})",
        "args": [
          {
            "value": {
              "returns": [
                -0.02,
                0.01,
                0
              ],
              "parameters": {
                "omega": 0.000002,
                "initial_variance": 0.0001,
                "d": 0.4,
                "truncation": 2,
                "backcast_variance": 0.0001
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F03-A05",
          "title": "FIGARCH",
          "parameters": {
            "omega": 0.000002,
            "initial_variance": 0.0001,
            "d": 0.4,
            "truncation": 2,
            "backcast_variance": 0.0001
          },
          "series": [
            {
              "index": 0,
              "variance": 0.000102,
              "intercept": 0.000002,
              "weights": [
                0.4,
                0.12
              ],
              "lag_contributions": [],
              "backcast_contribution": 0.0001,
              "memory_mass": 0
            },
            {
              "index": 1,
              "variance": 0.000222,
              "intercept": 0.000002,
              "weights": [
                0.4,
                0.12
              ],
              "lag_contributions": [
                0.00016
              ],
              "backcast_contribution": 0.00006,
              "memory_mass": 0.4
            },
            {
              "index": 2,
              "variance": 0.000138,
              "intercept": 0.000002,
              "weights": [
                0.4,
                0.12
              ],
              "lag_contributions": [
                0.00004,
                0.000048
              ],
              "backcast_contribution": 0.000048,
              "memory_mass": 0.52
            }
          ],
          "latest": {
            "index": 2,
            "variance": 0.000138,
            "intercept": 0.000002,
            "weights": [
              0.4,
              0.12
            ],
            "lag_contributions": [
              0.00004,
              0.000048
            ],
            "backcast_contribution": 0.000048,
            "memory_mass": 0.52
          },
          "ready": true,
          "ready_at": 0,
          "diagnostics": {
            "causal": true,
            "input_count": 3,
            "fitted_parameters": false,
            "model": "figarch"
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, series, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a05/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a05/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a05/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "FIGARCH — calculation-flow",
            "source": "flowchart TD\n    N0[\"δ1 = d\"]\n    N1[\"Recur unnormalized fractional weights\"]\n    N2[\"Weight newest through oldest shocks\"]\n    N3[\"Assign unused mass to backcast\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "FIGARCH — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"FIGARCH calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/conditional-volatility/figarch/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/conditional-volatility/figarch/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F03-A06",
      "name": "HAR-RV",
      "headline": null,
      "slug": "har-rv",
      "path": "volatility-and-covariance/conditional-volatility/har-rv",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F03",
        "family": "Conditional Volatility",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/conditional-volatility/har-rv",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Watch one elevated session enter and leave three overlapping horizons. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"realized_variance\":[0.0001,0.0001,0.0001,0.0001,0.0001,0.0001],\"parameters\":{\"beta0\":0,\"beta_daily\":0.5,\"beta_weekly\":0.3,\"beta_monthly\":0.2}})",
        "args": [
          {
            "value": {
              "realized_variance": [
                0.0001,
                0.0001,
                0.0001,
                0.0001,
                0.0001,
                0.0001
              ],
              "parameters": {
                "beta0": 0,
                "beta_daily": 0.5,
                "beta_weekly": 0.3,
                "beta_monthly": 0.2
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F03-A06",
          "title": "HAR-RV",
          "parameters": {
            "beta0": 0,
            "beta_daily": 0.5,
            "beta_weekly": 0.3,
            "beta_monthly": 0.2
          },
          "series": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "latest": {
            "index": 21,
            "forecast_index": 22,
            "forecast_raw": 0.00027072727272727274,
            "forecast": 0.00027072727272727274,
            "valid": true,
            "daily": 0.0004,
            "weekly": 0.00016,
            "monthly": 0.00011363636363636366,
            "contributions": [
              0,
              0.0002,
              0.000048,
              0.000022727272727272733
            ],
            "baseline": 0.0004
          },
          "ready": true,
          "ready_at": 21,
          "diagnostics": {
            "causal": true,
            "input_count": 22,
            "fitted_parameters": false
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, series, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a06/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a06/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a06/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f03-a06/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "HAR-RV — calculation-flow",
            "source": "flowchart TD\n    N0[\"Observe RV through current session\"]\n    N1[\"Build 1 / 5 / 22 session features\"]\n    N2[\"Multiply by supplied coefficients\"]\n    N3[\"Forecast next session; flag negative raw value\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "HAR-RV — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"HAR-RV calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/conditional-volatility/har-rv/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/conditional-volatility/har-rv/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F04-A01",
      "name": "Sample Covariance",
      "headline": null,
      "slug": "sample-covariance",
      "path": "volatility-and-covariance/covariance-estimation/sample-covariance",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F04",
        "family": "Covariance Estimation",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/covariance-estimation/sample-covariance",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Add complete rows and audit sample means, denominator and cells. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(np²)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"returns\":[[1,1.3660254037844386],[1,-0.3660254037844386],[-1,0.3660254037844386]],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "returns": [
                [
                  1,
                  1.3660254037844386
                ],
                [
                  1,
                  -0.3660254037844386
                ],
                [
                  -1,
                  0.3660254037844386
                ]
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F04-A01",
          "title": "Sample Covariance",
          "parameters": {},
          "matrix": [
            [
              1.3333333333333333,
              0.6666666666666666
            ],
            [
              0.6666666666666666,
              1.3333333333333333
            ]
          ],
          "latest": [
            [
              1.3333333333333333,
              0.6666666666666666
            ],
            [
              0.6666666666666666,
              1.3333333333333333
            ]
          ],
          "ready": true,
          "ready_at": 0,
          "diagnostics": {
            "observations": 4,
            "assets": 2,
            "means": [
              0,
              0
            ],
            "causal": true,
            "ml_covariance": [
              [
                1,
                0.5
              ],
              [
                0.5,
                1
              ]
            ],
            "denominator": 3
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, matrix, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a01/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a01/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a01/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Sample Covariance — calculation-flow",
            "source": "flowchart TD\n    N0[\"Align complete asset vectors\"]\n    N1[\"Estimate endpoint column means\"]\n    N2[\"Sum centered outer products\"]\n    N3[\"Divide by n−1; singular PSD allowed\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Sample Covariance — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"Sample Covariance calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/covariance-estimation/sample-covariance/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/covariance-estimation/sample-covariance/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F04-A02",
      "name": "EWMA Covariance",
      "headline": null,
      "slug": "ewma-covariance",
      "path": "volatility-and-covariance/covariance-estimation/ewma-covariance",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F04",
        "family": "Covariance Estimation",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/covariance-estimation/ewma-covariance",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Watch the same new vector compete with the existing matrix. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(np²)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"returns\":[[0.01,0.02],[-0.02,0.01]],\"parameters\":{\"decay\":0.5}})",
        "args": [
          {
            "value": {
              "returns": [
                [
                  0.01,
                  0.02
                ],
                [
                  -0.02,
                  0.01
                ]
              ],
              "parameters": {
                "decay": 0.5
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F04-A02",
          "title": "EWMA Covariance",
          "parameters": {
            "decay": 0.5
          },
          "matrix": [
            [
              0.00022500000000000002,
              -0.00005
            ],
            [
              -0.00005,
              0.00015000000000000001
            ]
          ],
          "latest": [
            [
              0.00022500000000000002,
              -0.00005
            ],
            [
              -0.00005,
              0.00015000000000000001
            ]
          ],
          "ready": true,
          "ready_at": 0,
          "diagnostics": {
            "observations": 2,
            "assets": 2,
            "means": [
              -0.005,
              0.015
            ],
            "causal": true,
            "ml_covariance": [
              [
                0.000225,
                0.000075
              ],
              [
                0.000075,
                0.000025
              ]
            ],
            "states": [
              [
                [
                  0.00005,
                  0.0001
                ],
                [
                  0.0001,
                  0.0002
                ]
              ],
              [
                [
                  0.00022500000000000002,
                  -0.00005
                ],
                [
                  -0.00005,
                  0.00015000000000000001
                ]
              ]
            ],
            "mean_convention": "supplied zero-mean residuals",
            "weight_mass": 0.75,
            "seed_weight": 0.25
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, matrix, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a02/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a02/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a02/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "EWMA Covariance — calculation-flow",
            "source": "flowchart TD\n    N0[\"Declare zero-mean residuals and seed\"]\n    N1[\"Compute current outer product\"]\n    N2[\"Blend λ old + (1−λ) new\"]\n    N3[\"Report remaining seed weight\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "EWMA Covariance — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"EWMA Covariance calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/covariance-estimation/ewma-covariance/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/covariance-estimation/ewma-covariance/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F04-A03",
      "name": "Ledoit-Wolf Shrinkage",
      "headline": null,
      "slug": "ledoit-wolf-shrinkage",
      "path": "volatility-and-covariance/covariance-estimation/ledoit-wolf-shrinkage",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F04",
        "family": "Covariance Estimation",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/covariance-estimation/ledoit-wolf-shrinkage",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Compare estimated outer-product noise with target distance. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(np²)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"returns\":[[1,1.3660254037844386],[1,-0.3660254037844386],[-1,0.3660254037844386]],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "returns": [
                [
                  1,
                  1.3660254037844386
                ],
                [
                  1,
                  -0.3660254037844386
                ],
                [
                  -1,
                  0.3660254037844386
                ]
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F04-A03",
          "title": "Ledoit-Wolf Shrinkage",
          "parameters": {},
          "matrix": [
            [
              1,
              0
            ],
            [
              0,
              1
            ]
          ],
          "latest": [
            [
              1,
              0
            ],
            [
              0,
              1
            ]
          ],
          "ready": true,
          "ready_at": 0,
          "diagnostics": {
            "observations": 4,
            "assets": 2,
            "means": [
              0,
              0
            ],
            "causal": true,
            "ml_covariance": [
              [
                1,
                0.5
              ],
              [
                0.5,
                1
              ]
            ],
            "noise_estimate": 0.5625,
            "target_distance": 0.5,
            "shrinkage": 1,
            "target": 1
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, matrix, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a03/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a03/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a03/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Ledoit-Wolf Shrinkage — calculation-flow",
            "source": "flowchart TD\n    N0[\"Center data and divide by n\"]\n    N1[\"Build average-variance identity target\"]\n    N2[\"Estimate noise / target distance\"]\n    N3[\"Clip intensity and blend matrices\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Ledoit-Wolf Shrinkage — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"Ledoit-Wolf Shrinkage calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/covariance-estimation/ledoit-wolf-shrinkage/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/covariance-estimation/ledoit-wolf-shrinkage/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F04-A04",
      "name": "Oracle Approximating Shrinkage",
      "headline": null,
      "slug": "oracle-approximating-shrinkage",
      "path": "volatility-and-covariance/covariance-estimation/oracle-approximating-shrinkage",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F04",
        "family": "Covariance Estimation",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/covariance-estimation/oracle-approximating-shrinkage",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Trace the finite-dimensional coefficient rather than assuming library equivalence. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(np²)",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"returns\":[[1,1.3660254037844386],[1,-0.3660254037844386],[-1,0.3660254037844386]],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "returns": [
                [
                  1,
                  1.3660254037844386
                ],
                [
                  1,
                  -0.3660254037844386
                ],
                [
                  -1,
                  0.3660254037844386
                ]
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F04-A04",
          "title": "Oracle Approximating Shrinkage",
          "parameters": {},
          "matrix": [
            [
              1,
              0
            ],
            [
              0,
              1
            ]
          ],
          "latest": [
            [
              1,
              0
            ],
            [
              0,
              1
            ]
          ],
          "ready": true,
          "ready_at": 0,
          "diagnostics": {
            "observations": 4,
            "assets": 2,
            "means": [
              0,
              0
            ],
            "causal": true,
            "ml_covariance": [
              [
                1,
                0.5
              ],
              [
                0.5,
                1
              ]
            ],
            "numerator": 4,
            "denominator": 2,
            "variant": "original finite-p OAS",
            "shrinkage": 1,
            "target": 1
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, matrix, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a04/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a04/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a04/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Oracle Approximating Shrinkage — calculation-flow",
            "source": "flowchart TD\n    N0[\"Compute ML empirical covariance\"]\n    N1[\"Trace C and trace C²\"]\n    N2[\"Retain original 2/p coefficient terms\"]\n    N3[\"Handle isotropy and blend target\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Oracle Approximating Shrinkage — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"Oracle Approximating Shrinkage calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/covariance-estimation/oracle-approximating-shrinkage/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/covariance-estimation/oracle-approximating-shrinkage/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F04-A05",
      "name": "Factor-Model Covariance",
      "headline": null,
      "slug": "factor-model-covariance",
      "path": "volatility-and-covariance/covariance-estimation/factor-model-covariance",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F04",
        "family": "Covariance Estimation",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/covariance-estimation/factor-model-covariance",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Change loadings, common-factor risk and specific risk independently. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(p²k²) transparent direct multiplication",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"loadings\":[[1],[2]],\"factor_covariance\":[[0.04]],\"specific_variances\":[0.01,0.02],\"parameters\":{}})",
        "args": [
          {
            "value": {
              "loadings": [
                [
                  1
                ],
                [
                  2
                ]
              ],
              "factor_covariance": [
                [
                  0.04
                ]
              ],
              "specific_variances": [
                0.01,
                0.02
              ],
              "parameters": {}
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F04-A05",
          "title": "Factor-Model Covariance",
          "parameters": {},
          "matrix": [
            [
              0.05,
              0.08
            ],
            [
              0.08,
              0.18
            ]
          ],
          "latest": [
            [
              0.05,
              0.08
            ],
            [
              0.08,
              0.18
            ]
          ],
          "ready": true,
          "ready_at": 0,
          "diagnostics": {
            "common": [
              [
                0.04,
                0.08
              ],
              [
                0.08,
                0.16
              ]
            ],
            "specific_variances": [
              0.01,
              0.02
            ],
            "assets": 2,
            "factors": 1,
            "causal": true
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, matrix, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a05/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a05/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a05/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Factor-Model Covariance — calculation-flow",
            "source": "flowchart TD\n    N0[\"Validate B, PSD F and nonnegative D\"]\n    N1[\"Compute each common-risk cell BFBᵀ\"]\n    N2[\"Add specific variances only on diagonal\"]\n    N3[\"Check portfolio variance two ways\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Factor-Model Covariance — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"Factor-Model Covariance calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/covariance-estimation/factor-model-covariance/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/covariance-estimation/factor-model-covariance/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D10-F04-A06",
      "name": "Graphical-Lasso Covariance",
      "headline": null,
      "slug": "graphical-lasso-covariance",
      "path": "volatility-and-covariance/covariance-estimation/graphical-lasso-covariance",
      "taxonomy": {
        "domainId": "D10",
        "domain": "Volatility and Covariance",
        "familyId": "D10-F04",
        "family": "Covariance Estimation",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/volatility-and-covariance/covariance-estimation/graphical-lasso-covariance",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Vary penalty independently from sample count and inspect precision edges. Supplied-parameter educational reference; no fitted performance claim.",
        "params": [
          {
            "name": "data",
            "type": "TopicInput",
            "required": true,
            "description": "See data-contract/CONTRACT.md.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "TopicResult",
          "description": "Structured result with readiness, values, parameters, and diagnostics."
        },
        "warmup": {
          "count": "depends on window or model order",
          "value": "null prefix until minimum history exists"
        },
        "errors": [
          {
            "when": "required data is missing, non-finite, malformed, or out of range",
            "behaviour": "raises ContractError / Error"
          }
        ],
        "complexity": {
          "time": "O(np²) empirical covariance plus bounded iterative block optimization; iteration-dependent",
          "space": "Full diagnostic trace retained for teaching; see implementation for observation/window/matrix dimensions"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"returns\":[[1,1.3660254037844386],[1,-0.3660254037844386],[-1,0.3660254037844386]],\"parameters\":{\"alpha\":0.1}})",
        "args": [
          {
            "value": {
              "returns": [
                [
                  1,
                  1.3660254037844386
                ],
                [
                  1,
                  -0.3660254037844386
                ],
                [
                  -1,
                  0.3660254037844386
                ]
              ],
              "parameters": {
                "alpha": 0.1
              }
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D10-F04-A06",
          "title": "Graphical-Lasso Covariance",
          "parameters": {
            "alpha": 0.1
          },
          "matrix": [
            [
              1,
              0.4
            ],
            [
              0.4,
              1
            ]
          ],
          "latest": [
            [
              1,
              0.4
            ],
            [
              0.4,
              1
            ]
          ],
          "ready": true,
          "ready_at": 0,
          "diagnostics": {
            "observations": 4,
            "assets": 2,
            "means": [
              0,
              0
            ],
            "causal": true,
            "ml_covariance": [
              [
                1,
                0.5
              ],
              [
                0.5,
                1
              ]
            ],
            "graphical_lasso": {
              "iterations": 1,
              "converged": true,
              "alpha": 0.1,
              "precision": [
                [
                  1.1904761904761905,
                  -0.4761904761904762
                ],
                [
                  -0.4761904761904762,
                  1.1904761904761905
                ]
              ],
              "kkt_residual": 5.551115123125783e-17,
              "dual_gap": -9.71445146547012e-17,
              "history": [
                {
                  "iteration": 1,
                  "kkt_residual": 5.551115123125783e-17,
                  "dual_gap": -9.71445146547012e-17,
                  "objective": 1.8256466128552222
                }
              ]
            }
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: topic_id, title, parameters, matrix, latest, ready, ready_at, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "F"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a06/static/article-hero.svg"
          },
          {
            "file": "concept-map.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a06/static/concept-map.svg"
          },
          {
            "file": "decision-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a06/static/decision-comparison.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d10-f04-a06/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Graphical-Lasso Covariance — calculation-flow",
            "source": "flowchart TD\n    N0[\"Center observations into ML C\"]\n    N1[\"Solve block lasso with fixed diagonal\"]\n    N2[\"Check SPD, KKT residual and dual gap\"]\n    N3[\"Invert to precision; interpret conditional edges\"]\n    N0 --> N1 --> N2 --> N3"
          },
          {
            "file": "decision-boundary.md",
            "caption": "Graphical-Lasso Covariance — decision-boundary",
            "source": "flowchart TD\n    A[\"Supplied observations and parameters\"] --> B{\"Contract valid?\"}\n    B -->|No| E[\"Reject with explicit error\"]\n    B -->|Yes| C{\"Required history available?\"}\n    C -->|No| W[\"Withhold; never insert zero\"]\n    C -->|Yes| D[\"Graphical-Lasso Covariance calculation\"]\n    D --> F[\"Inspect diagnostics and stated limits\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Scope of evidence",
          "title": "Scope of evidence",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/volatility-and-covariance/covariance-estimation/graphical-lasso-covariance/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/volatility-and-covariance/covariance-estimation/graphical-lasso-covariance/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": [
          {
            "file": "calculation-flow.md",
            "caption": "Tick Test Calculation Flow",
            "source": "flowchart LR\n    A[\"Final synthetic records\"] --> B[\"Order by event time and sequence\"]\n    B --> C[\"Apply status and condition filters\"]\n    C --> D[\"Enforce availability and causal reference\"]\n    D --> E[\"Run Tick Test\"]\n    E --> F[\"Sign or fractional volume\"]\n    F --> G[\"Reason code and trace\"]\n    G --> H[\"Coverage and imbalance\"]\n    H --> I[\"Sensitivity comparison\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Quote Test Calculation Flow",
            "source": "flowchart LR\n    A[\"Final synthetic records\"] --> B[\"Order by event time and sequence\"]\n    B --> C[\"Apply status and condition filters\"]\n    C --> D[\"Enforce availability and causal reference\"]\n    D --> E[\"Run Quote Test\"]\n    E --> F[\"Sign or fractional volume\"]\n    F --> G[\"Reason code and trace\"]\n    G --> H[\"Coverage and imbalance\"]\n    H --> I[\"Sensitivity comparison\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Lee-Ready Trade Signing Calculation Flow",
            "source": "flowchart LR\n    A[\"Final synthetic records\"] --> B[\"Order by event time and sequence\"]\n    B --> C[\"Apply status and condition filters\"]\n    C --> D[\"Enforce availability and causal reference\"]\n    D --> E[\"Run Lee-Ready Trade Signing\"]\n    E --> F[\"Sign or fractional volume\"]\n    F --> G[\"Reason code and trace\"]\n    G --> H[\"Coverage and imbalance\"]\n    H --> I[\"Sensitivity comparison\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Bulk Volume Classification Calculation Flow",
            "source": "flowchart LR\n    A[\"Final synthetic records\"] --> B[\"Order by event time and sequence\"]\n    B --> C[\"Apply status and condition filters\"]\n    C --> D[\"Enforce availability and causal reference\"]\n    D --> E[\"Run Bulk Volume Classification\"]\n    E --> F[\"Sign or fractional volume\"]\n    F --> G[\"Reason code and trace\"]\n    G --> H[\"Coverage and imbalance\"]\n    H --> I[\"Sensitivity comparison\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "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": [
          {
            "file": "system-flow.md",
            "caption": "Quoted Spread validation flow",
            "source": "flowchart LR\n    A[\"Question: How far apart are the best displayed prices available to an immediate seller and buyer?\"] --> B[\"Freeze instrument, scope, clock, units, and variant\"]\n    B --> C[\"Validate Quoted Spread inputs\"]\n    C --> D{\"Eligible and synchronized?\"}\n    D -- \"No\" --> E[\"Reject with topic-specific reason\"]\n    D -- \"Yes\" --> F[\"Apply the frozen Quoted spread formula\"]\n    F --> G[\"Expose intermediate value and decision state\"]\n    G --> H{\"Direct measure or model-based proxy?\"}\n    H --> I[\"Report result with its unit and limitation\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "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": [
          {
            "file": "system-flow.md",
            "caption": "Effective Spread validation flow",
            "source": "flowchart LR\n    A[\"Question: How far did a signed execution occur from the contemporaneous quote midpoint?\"] --> B[\"Freeze instrument, scope, clock, units, and variant\"]\n    B --> C[\"Validate Effective Spread inputs\"]\n    C --> D{\"Eligible and synchronized?\"}\n    D -- \"No\" --> E[\"Reject with topic-specific reason\"]\n    D -- \"Yes\" --> F[\"Apply the frozen Effective spread formula\"]\n    F --> G[\"Expose intermediate value and decision state\"]\n    G --> H{\"Direct measure or model-based proxy?\"}\n    H --> I[\"Report result with its unit and limitation\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "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": [
          {
            "file": "system-flow.md",
            "caption": "Realized Spread validation flow",
            "source": "flowchart LR\n    A[\"Question: How much of the execution concession remains after the midpoint moves over a declared horizon?\"] --> B[\"Freeze instrument, scope, clock, units, and variant\"]\n    B --> C[\"Validate Realized Spread inputs\"]\n    C --> D{\"Eligible and synchronized?\"}\n    D -- \"No\" --> E[\"Reject with topic-specific reason\"]\n    D -- \"Yes\" --> F[\"Apply the frozen Realized spread formula\"]\n    F --> G[\"Expose intermediate value and decision state\"]\n    G --> H{\"Direct measure or model-based proxy?\"}\n    H --> I[\"Report result with its unit and limitation\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "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": [
          {
            "file": "system-flow.md",
            "caption": "Roll Spread Estimator validation flow",
            "source": "flowchart LR\n    A[\"Question: Can bid–ask bounce reveal an implicit spread when quote data are unavailable?\"] --> B[\"Freeze instrument, scope, clock, units, and variant\"]\n    B --> C[\"Validate Roll Spread Estimator inputs\"]\n    C --> D{\"Eligible and synchronized?\"}\n    D -- \"No\" --> E[\"Reject with topic-specific reason\"]\n    D -- \"Yes\" --> F[\"Apply the frozen Roll spread formula\"]\n    F --> G[\"Expose intermediate value and decision state\"]\n    G --> H{\"Direct measure or model-based proxy?\"}\n    H --> I[\"Report result with its unit and limitation\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "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": [
          {
            "file": "system-flow.md",
            "caption": "Amihud Illiquidity Ratio validation flow",
            "source": "flowchart LR\n    A[\"Question: How much absolute return accompanies one unit of traded dollar volume?\"] --> B[\"Freeze instrument, scope, clock, units, and variant\"]\n    B --> C[\"Validate Amihud Illiquidity Ratio inputs\"]\n    C --> D{\"Eligible and synchronized?\"}\n    D -- \"No\" --> E[\"Reject with topic-specific reason\"]\n    D -- \"Yes\" --> F[\"Apply the frozen Amihud ratio formula\"]\n    F --> G[\"Expose intermediate value and decision state\"]\n    G --> H{\"Direct measure or model-based proxy?\"}\n    H --> I[\"Report result with its unit and limitation\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "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": [
          {
            "file": "system-flow.md",
            "caption": "Corwin-Schultz Spread Estimator validation flow",
            "source": "flowchart LR\n    A[\"Question: Can two consecutive daily high–low ranges separate spread from fundamental volatility?\"] --> B[\"Freeze instrument, scope, clock, units, and variant\"]\n    B --> C[\"Validate Corwin-Schultz Spread Estimator inputs\"]\n    C --> D{\"Eligible and synchronized?\"}\n    D -- \"No\" --> E[\"Reject with topic-specific reason\"]\n    D -- \"Yes\" --> F[\"Apply the frozen High–low spread formula\"]\n    F --> G[\"Expose intermediate value and decision state\"]\n    G --> H{\"Direct measure or model-based proxy?\"}\n    H --> I[\"Report result with its unit and limitation\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Order Flow Imbalance Calculation Flow",
            "source": "flowchart LR\n    A[\"Point-in-time source records\"] --> B[\"Validate clocks, sequence, and finality\"]\n    B --> C[\"Apply Order Flow Imbalance profile\"]\n    C --> D[\"Preserve trace and diagnostics\"]\n    D --> E[\"Report bounded output\"]\n    E --> F[\"Compare profiles\"]\n    F --> G[\"Reject unsupported inference\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Queue Imbalance Calculation Flow",
            "source": "flowchart LR\n    A[\"Point-in-time source records\"] --> B[\"Validate clocks, sequence, and finality\"]\n    B --> C[\"Apply Queue Imbalance profile\"]\n    C --> D[\"Preserve trace and diagnostics\"]\n    D --> E[\"Report bounded output\"]\n    E --> F[\"Compare profiles\"]\n    F --> G[\"Reject unsupported inference\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Kyle Lambda Calculation Flow",
            "source": "flowchart LR\n    A[\"Point-in-time source records\"] --> B[\"Validate clocks, sequence, and finality\"]\n    B --> C[\"Apply Kyle Lambda profile\"]\n    C --> D[\"Preserve trace and diagnostics\"]\n    D --> E[\"Report bounded output\"]\n    E --> F[\"Compare profiles\"]\n    F --> G[\"Reject unsupported inference\"]"
          }
        ]
      },
      "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": "Estimates a bivariate VAR(1) in signed flow and midpoint return, identifies a one-unit flow innovation recursively with flow ordered first, and sums the return responses through a declared horizon. The result is the cumulative midpoint response that follows a flow innovation after dynamic feedback; it is not a permanent/transient decomposition and it does not identify informed trades.",
        "params": [
          {
            "name": "inputRows",
            "type": "Row[]",
            "required": true,
            "description": "At least eight ordered interval records, each carrying a finite `signed_flow` and a finite `mid_change_bps`. There is no midpoint path per trade; one return observation per interval is used.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "horizon",
            "type": "number",
            "required": false,
            "description": "Number of response steps after the contemporaneous step. The trace holds `horizon + 1` rows, indexed 0 through `horizon`.",
            "constraints": {
              "min": 0,
              "max": 100,
              "integer": true
            },
            "nulls": null,
            "default": 10
          }
        ],
        "returns": {
          "type": "{ model, state, observation_count, horizon, flow_equation, return_equation, flow_innovation_variance, return_flow_innovation_covariance, contemporaneous_return_response_bps, cumulative_price_impact_bps, trace }",
          "description": "Both fitted equations with their intercept and lag coefficients, the flow innovation variance and return/flow innovation covariance used for the recursive identification, the contemporaneous and cumulative response in basis points, and a per-step trace of `flow_response`, `return_response_bps` and `cumulative_impact_bps`. All numbers are rounded to ten decimal places."
        },
        "warmup": null,
        "errors": [
          {
            "when": "fewer than eight rows are supplied, or a row is not an object",
            "behaviour": "throws"
          },
          {
            "when": "horizon is not an integer from 0 through 100",
            "behaviour": "throws"
          },
          {
            "when": "a row omits signed_flow or mid_change_bps, or the value is not finite",
            "behaviour": "throws"
          },
          {
            "when": "the regression design is singular",
            "behaviour": "throws"
          },
          {
            "when": "the residual degrees of freedom are not positive",
            "behaviour": "throws"
          },
          {
            "when": "the flow innovation variance is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n + horizon)",
          "space": "O(n + horizon)"
        }
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "Hasbrouck Price Impact Calculation Flow",
            "source": "flowchart LR\n    A[\"Point-in-time source records\"] --> B[\"Validate clocks, sequence, and finality\"]\n    B --> C[\"Apply Hasbrouck Price Impact profile\"]\n    C --> D[\"Preserve trace and diagnostics\"]\n    D --> E[\"Report bounded output\"]\n    E --> F[\"Compare profiles\"]\n    F --> G[\"Reject unsupported inference\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "PIN Calculation Flow",
            "source": "flowchart LR\n    A[\"Point-in-time source records\"] --> B[\"Validate clocks, sequence, and finality\"]\n    B --> C[\"Apply PIN profile\"]\n    C --> D[\"Preserve trace and diagnostics\"]\n    D --> E[\"Report bounded output\"]\n    E --> F[\"Compare profiles\"]\n    F --> G[\"Reject unsupported inference\"]"
          }
        ]
      },
      "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": [
          {
            "file": "calculation-flow.md",
            "caption": "VPIN Calculation Flow",
            "source": "flowchart LR\n    A[\"Point-in-time source records\"] --> B[\"Validate clocks, sequence, and finality\"]\n    B --> C[\"Apply VPIN profile\"]\n    C --> D[\"Preserve trace and diagnostics\"]\n    D --> E[\"Report bounded output\"]\n    E --> F[\"Compare profiles\"]\n    F --> G[\"Reject unsupported inference\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f04-a01/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Order-Book Slope validation flow",
            "source": "flowchart LR\n    A[\"Question: How quickly does cumulative displayed depth grow as prices move away from the midpoint?\"] --> B[\"Reconstruct one causal book or event state\"]\n    B --> C[\"Freeze scope, window, sequence, session, units, and variant\"]\n    C --> D{\"Eligible input?\"}\n    D -- \"No\" --> E[\"Reject with topic-specific reason\"]\n    D -- \"Yes\" --> F[\"Apply the frozen Order-Book Slope relationship\"]\n    F --> G[\"Expose intermediate diagnostics and state\"]\n    G --> H{\"Static identity, fitted proxy, or conditional model?\"}\n    H --> I[\"Report output with convention and evidence boundary\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f04-a02/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Depth-Weighted Midprice validation flow",
            "source": "flowchart LR\n    A[\"Question: Where is the center of the selected book after each side is summarized with its own displayed depth?\"] --> B[\"Reconstruct one causal book or event state\"]\n    B --> C[\"Freeze scope, window, sequence, session, units, and variant\"]\n    C --> D{\"Eligible input?\"}\n    D -- \"No\" --> E[\"Reject with topic-specific reason\"]\n    D -- \"Yes\" --> F[\"Apply the frozen Depth-Weighted Midprice relationship\"]\n    F --> G[\"Expose intermediate diagnostics and state\"]\n    G --> H{\"Static identity, fitted proxy, or conditional model?\"}\n    H --> I[\"Report output with convention and evidence boundary\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f04-a03/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Microprice validation flow",
            "source": "flowchart LR\n    A[\"Question: How does top-of-book queue imbalance shift a quote-based reference price inside the spread?\"] --> B[\"Reconstruct one causal book or event state\"]\n    B --> C[\"Freeze scope, window, sequence, session, units, and variant\"]\n    C --> D{\"Eligible input?\"}\n    D -- \"No\" --> E[\"Reject with topic-specific reason\"]\n    D -- \"Yes\" --> F[\"Apply the frozen Microprice relationship\"]\n    F --> G[\"Expose intermediate diagnostics and state\"]\n    G --> H{\"Static identity, fitted proxy, or conditional model?\"}\n    H --> I[\"Report output with convention and evidence boundary\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f04-a04/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Order-Book Resiliency validation flow",
            "source": "flowchart LR\n    A[\"Question: How quickly does a liquidity displacement decay after a declared shock?\"] --> B[\"Reconstruct one causal book or event state\"]\n    B --> C[\"Freeze scope, window, sequence, session, units, and variant\"]\n    C --> D{\"Eligible input?\"}\n    D -- \"No\" --> E[\"Reject with topic-specific reason\"]\n    D -- \"Yes\" --> F[\"Apply the frozen Order-Book Resiliency relationship\"]\n    F --> G[\"Expose intermediate diagnostics and state\"]\n    G --> H{\"Static identity, fitted proxy, or conditional model?\"}\n    H --> I[\"Report output with convention and evidence boundary\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f04-a05/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Hawkes Order-Arrival Model validation flow",
            "source": "flowchart LR\n    A[\"Question: How does each order arrival temporarily increase the conditional rate of later arrivals?\"] --> B[\"Reconstruct one causal book or event state\"]\n    B --> C[\"Freeze scope, window, sequence, session, units, and variant\"]\n    C --> D{\"Eligible input?\"}\n    D -- \"No\" --> E[\"Reject with topic-specific reason\"]\n    D -- \"Yes\" --> F[\"Apply the frozen Hawkes Order-Arrival Model relationship\"]\n    F --> G[\"Expose intermediate diagnostics and state\"]\n    G --> H{\"Static identity, fitted proxy, or conditional model?\"}\n    H --> I[\"Report output with convention and evidence boundary\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f05-a01/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Cumulative Bid/Ask Depth calculation flow",
            "source": "flowchart LR\n    S1[\"Validate and preserve besttoworse price order\"]\n    S2[\"Set each sides running quantity to zero\"]\n    S3[\"Add each level and emit its cumulative quantity\"]\n    S4[\"Compare final included totals\"]\n    S5[\"Return curves totals tick distances and state\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"the included level window and visibleonly scope\"}\n    D --> O[\"total_bid_depth + diagnostics\"]\n    O --> A[\"Audit: Cumulative quantities are nondecreasing\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f05-a02/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Top-N Depth Imbalance calculation flow",
            "source": "flowchart LR\n    S1[\"Validate at least N levels on both sides\"]\n    S2[\"Sum the first N bid quantities\"]\n    S3[\"Sum the first N ask quantities\"]\n    S4[\"Normalize the signed difference by total depth\"]\n    S5[\"Classify against the symmetric threshold\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"threshold and the completewindow requirement\"}\n    D --> O[\"imbalance + diagnostics\"]\n    O --> A[\"Audit: Imbalance is in 11\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f05-a03/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Depth-at-Distance Profile calculation flow",
            "source": "flowchart LR\n    S1[\"Validate tick alignment\"]\n    S2[\"Anchor each side at its own best quote\"]\n    S3[\"Map every level to an integer distance\"]\n    S4[\"Emit zero for unpopulated distances\"]\n    S5[\"Calculate quantity shares and cumulative depth\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"tick alignment and inclusive maximum distance\"}\n    D --> O[\"included_bid_depth + diagnostics\"]\n    O --> A[\"Audit: Distance zero is populated on each nonempty side\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f05-a04/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Expected Market-Order Fill Price calculation flow",
            "source": "flowchart LR\n    S1[\"Select asks for a buy or bids for a sell\"]\n    S2[\"Apply the optional limitprice eligibility boundary\"]\n    S3[\"Fill from best price outward\"]\n    S4[\"Accumulate quantity and notional\"]\n    S5[\"Return fullfill price only if residual quantity is zer\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"eligible visible depth versus requested quantity\"}\n    D --> O[\"expected_fill_price + diagnostics\"]\n    O --> A[\"Audit: Filled plus unfilled quantity equals requested quantity\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f05-a05/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Multi-Level Sweep Cost and Slippage calculation flow",
            "source": "flowchart LR\n    S1[\"Calculate eligible perlevel fills\"]\n    S2[\"Select and validate the benchmark\"]\n    S3[\"Compute fill VWAP\"]\n    S4[\"Apply buysell direction to price difference\"]\n    S5[\"Scale to basis points and filled monetary cost\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"full versus partial sweep and benchmark choice\"}\n    D --> O[\"signed_slippage_bps + diagnostics\"]\n    O --> A[\"Audit: Benchmark choice is returned with its numeric value\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f05-a06/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Liquidity-Wall and Concentration Detection calculation flow",
            "source": "flowchart LR\n    S1[\"Validate one ordered book side\"]\n    S2[\"Normalize level quantities into shares\"]\n    S3[\"Sum squared shares\"]\n    S4[\"Calculate median multiples\"]\n    S5[\"Flag only levels passing both thresholds and classify \"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"both wall thresholds and the separate HHI state threshold\"}\n    D --> O[\"hhi_fraction + diagnostics\"]\n    O --> A[\"Audit: Fractional HHI is in 1L1 for L positive levels\"]"
          }
        ]
      },
      "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": "Splits the snapshot-to-snapshot changes in one visible-depth quantity series into gross depletion and gross replenishment, so that turnover hidden behind a small start-to-end difference becomes visible. A snapshot change cannot separate executions from cancellations, adds or replaces, so no cause is assigned to either total.",
        "params": [
          {
            "name": "seriesRaw",
            "type": "{ timestamp_seconds: number; quantity: number }[]",
            "required": true,
            "description": "At least two snapshots of one selected price level or distance bucket, with strictly increasing nonnegative `timestamp_seconds` and nonnegative `quantity`. This is a single aggregate series, not a per-side or per-level book.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ model, snapshot_count, start_quantity, end_quantity, gross_depletion, gross_replenishment, net_depth_change, replenishment_to_depletion, changes, state }",
          "description": "Gross depletion and gross replenishment in quantity units, their difference as `net_depth_change`, their ratio as `replenishment_to_depletion` (null when there is no depletion), a `net-replenishing` / `net-depleting` / `net-flat` state label, and a `changes` audit of every consecutive pair with its `delta_quantity` and `depletion` / `replenishment` / `unchanged` classification."
        },
        "warmup": null,
        "errors": [
          {
            "when": "fewer than two snapshots are supplied",
            "behaviour": "throws"
          },
          {
            "when": "a snapshot is not an object, or omits timestamp_seconds or quantity",
            "behaviour": "throws"
          },
          {
            "when": "a timestamp or quantity is non-finite or negative",
            "behaviour": "throws"
          },
          {
            "when": "timestamps are not strictly increasing",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(snapshots)",
          "space": "O(snapshots)"
        }
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f05-a07/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Depth Depletion and Replenishment calculation flow",
            "source": "flowchart LR\n    S1[\"Validate chronological snapshots\"]\n    S2[\"Subtract each prior visible quantity\"]\n    S3[\"Accumulate negative magnitudes as depletion\"]\n    S4[\"Accumulate positive changes as replenishment\"]\n    S5[\"Return gross net ratio and event audit\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"zerodepletion null ratio and stable bucket identity\"}\n    D --> O[\"replenishment_to_depletion + diagnostics\"]\n    O --> A[\"Audit: Net change equals end quantity minus start quantity\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f05-a08/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Market-Depth Heatmap Aggregation calculation flow",
            "source": "flowchart LR\n    S1[\"Validate regular chronological snapshots\"]\n    S2[\"Reconstruct each uncrossed visible book\"]\n    S3[\"Map bids to negative and asks to positive inside coord\"]\n    S4[\"Zerofill absent included distances\"]\n    S5[\"Aggregate mean max count and peak by time bin\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"regular sampling and the unused zero coordinate\"}\n    D --> O[\"time_bin_count + diagnostics\"]\n    O --> A[\"Audit: Coordinate zero is never used\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f01-a01/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Price-Time Priority calculation flow",
            "source": "flowchart LR\n    S1[\"Validate identity side price quantity and sequence\"]\n    S2[\"Sort opposite interest best price first\"]\n    S3[\"Break equalprice ties by ascending arrival sequence\"]\n    S4[\"Fill until the aggressor is complete or price no longe\"]\n    S5[\"Return fills residual average price and final book\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"the incoming limit and equalprice FIFO order\"}\n    D --> O[\"filled_quantity + diagnostics\"]\n    O --> A[\"Audit: Worse price never executes before a better executable pric\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f01-a02/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Pro-Rata Matching calculation flow",
            "source": "flowchart LR\n    S1[\"Validate oneprice and wholelot inputs\"]\n    S2[\"Compute executable quantity\"]\n    S3[\"Calculate each raw proportional share\"]\n    S4[\"Floor shares to lots\"]\n    S5[\"Award residual lots by fractional remainder size then \"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"wholelot rounding and capacity caps\"}\n    D --> O[\"allocated_quantity + diagnostics\"]\n    O --> A[\"Audit: Allocation is proportional before lot rounding\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f01-a03/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Size-Time Priority calculation flow",
            "source": "flowchart LR\n    S1[\"Validate oneprice and wholelot inputs\"]\n    S2[\"Sort open quantity descending\"]\n    S3[\"Break equalsize ties by oldest sequence\"]\n    S4[\"Sequentially fill the ranked queue\"]\n    S5[\"Return rank and quantity conservation trace\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"equalsize time priority and postpartialfill reranking\"}\n    D --> O[\"allocated_quantity + diagnostics\"]\n    O --> A[\"Audit: A smaller open order never ranks ahead of a larger one\"]"
          }
        ]
      },
      "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": "hybridProRataTime",
        "params": [
          "incomingRaw",
          "priceRaw",
          "lotRaw",
          "fractionRaw",
          "restingRaw"
        ],
        "exports": [
          "priceTimePriority",
          "proRataMatching",
          "sizeTimePriority",
          "hybridProRataTime",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "hybridProRataTime(incomingRaw, priceRaw, lotRaw, fractionRaw, restingRaw)"
      },
      "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": "incomingRaw",
            "type": "number",
            "required": true,
            "description": "Quantity of the aggressing order. Only the part the resting book can fill is allocated; the rest comes back as `unfilled_quantity`.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "priceRaw",
            "type": "number",
            "required": true,
            "description": "The single price this match happens at. Echoed back as `price`.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "lotRaw",
            "type": "number",
            "required": true,
            "description": "Lot size. Allocation is computed in whole lots, so both portions are shared out in units of this rather than in raw quantity.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "fractionRaw",
            "type": "number",
            "required": true,
            "description": "Share of the executable quantity allocated by arrival order before the remainder goes pro rata. Zero is pure pro-rata; one is pure time priority.",
            "constraints": {
              "min": 0,
              "max": 1
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "restingRaw",
            "type": "RestingOrder[]",
            "required": true,
            "description": "The resting book at this price, each order carrying `order_id`, `remaining_quantity` and `arrival_sequence`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ model, price, lot_size, fifo_fraction, incoming_quantity, executable_quantity, fifo_target_quantity, pro_rata_target_quantity, allocated_quantity, unfilled_quantity, allocations, state }",
          "description": "Both target quantities, and `allocations` ordered by arrival with each order's fill split into `fifo_quantity` and `pro_rata_quantity`. `state` is `fully-allocated` or `partially-allocated`."
        },
        "warmup": null,
        "errors": [
          {
            "when": "`fractionRaw` is below zero or above one",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(resting log resting)",
          "space": "O(resting)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "hybridProRataTime(600, 100, 1, 0.4, [{\"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": 600,
            "elided": null
          },
          {
            "value": 100,
            "elided": null
          },
          {
            "value": 1,
            "elided": null
          },
          {
            "value": 0.4,
            "elided": null
          },
          {
            "value": [
              {
                "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f01-a04/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Hybrid Pro-Rata/Time Matching calculation flow",
            "source": "flowchart LR\n    S1[\"Validate the oneprice book and fraction\"]\n    S2[\"Compute executable whole lots\"]\n    S3[\"Floor the FIFO target and allocate oldest orders first\"]\n    S4[\"Recompute residual resting capacity\"]\n    S5[\"Allocate the remaining target pro rata and reconcile\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"zeroone split endpoints and capacity doublecount preventio\"}\n    D --> O[\"allocated_quantity + diagnostics\"]\n    O --> A[\"Audit: FIFO and prorata targets sum to executable quantity\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f02-a01/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Maximum-Executable-Volume Auction calculation flow",
            "source": "flowchart LR\n    S1[\"Validate orders ticks identity and reference\"]\n    S2[\"Build the candidate price set\"]\n    S3[\"Compute cumulative buy and sell quantity\"]\n    S4[\"Calculate executable quantity and imbalance\"]\n    S5[\"Return every maximumvolume candidate\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"a tie in the first objective and the zerovolume nocross st\"}\n    D --> O[\"maximum_executable_quantity + diagnostics\"]\n    O --> A[\"Audit: Market orders participate at every candidate price\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f02-a02/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Minimum-Imbalance Tie-Break calculation flow",
            "source": "flowchart LR\n    S1[\"Evaluate every candidate\"]\n    S2[\"Retain maximum executable volume\"]\n    S3[\"Calculate absolute imbalance for survivors\"]\n    S4[\"Retain minimumimbalance survivors\"]\n    S5[\"Return one price or an explicit remaining tie\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"an unresolved tie after both objectives\"}\n    D --> O[\"selected_price + diagnostics\"]\n    O --> A[\"Audit: A nonmaximumvolume price can never win on imbalance\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f02-a03/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Opening-Cross Price calculation flow",
            "source": "flowchart LR\n    S1[\"Validate MOO LOO and DAY eligibility\"]\n    S2[\"Build tick candidates inside the opening collar\"]\n    S3[\"Maximize volume and minimize imbalance\"]\n    S4[\"Apply directional surplus or previousclose proximity\"]\n    S5[\"Publish price volume imbalance and trace\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"collar equality and the nocross session\"}\n    D --> O[\"selected_price + diagnostics\"]\n    O --> A[\"Audit: Every selected price is inside the inclusive collar\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f02-a04/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Closing-Cross Price calculation flow",
            "source": "flowchart LR\n    S1[\"Validate MOC LOC and DAY eligibility\"]\n    S2[\"Build candidates inside the closing collar\"]\n    S3[\"Maximize executable quantity\"]\n    S4[\"Minimize imbalance then apply surplusreference rules\"]\n    S5[\"Return closing price volume imbalance and trace\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"closingonly eligibility and a nocross officialprice gap\"}\n    D --> O[\"selected_price + diagnostics\"]\n    O --> A[\"Audit: Openingonly MOO and LOO orders are unsupported\"]"
          }
        ]
      },
      "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": "Decides, from an already-determined corridor state, whether continuous trading carries on, the auction has no executable quantity, the indicative price may reopen the book, or the auction must be extended. The dynamic and static corridors are both built from a reference and a band percentage, and the reopening test uses each corridor widened by the extension multiplier. The algorithm does not build a book or discover a price; the indicative price and executable quantity are supplied.",
        "params": [
          {
            "name": "inputs",
            "type": "{ reference_price, dynamic_reference, dynamic_band_pct, static_reference, static_band_pct, potential_continuous_price, indicative_auction_price, extended_band_multiplier, executable_quantity }",
            "required": true,
            "description": "Nine scalars. The first eight must be finite and positive; `extended_band_multiplier` must be at least one and `executable_quantity` must be finite and nonnegative. No order arrays are taken.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ model, reference_price, potential_continuous_price, dynamic_corridor, static_corridor, dynamic_breach, static_breach, triggered, indicative_auction_price, executable_quantity, expanded_dynamic_corridor, expanded_static_corridor, inside_reopening_corridor, reopened, reopen_price, reason, state }",
          "description": "Both active corridors and both expanded corridors as [low, high] pairs, the per-corridor breach flags and their disjunction, whether the indicative price sits inside both expanded corridors, and a `state` of `continuous`, `auction-no-cross`, `reopened` or `extended-volatility-auction` with the `reason` that produced it. `reopen_price` is the indicative price when the state is `reopened` and null otherwise."
        },
        "warmup": null,
        "errors": [
          {
            "when": "inputs is not an object",
            "behaviour": "throws"
          },
          {
            "when": "any scalar is missing, non-numeric or non-finite",
            "behaviour": "throws"
          },
          {
            "when": "a price, reference or band percentage is not positive",
            "behaviour": "throws"
          },
          {
            "when": "extended_band_multiplier is below one",
            "behaviour": "throws"
          },
          {
            "when": "executable_quantity 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": "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f02-a05/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Volatility-Auction Reopening calculation flow",
            "source": "flowchart LR\n    S1[\"Validate references percentages multiplier and quantit\"]\n    S2[\"Test potential price against both active corridors\"]\n    S3[\"Enter volatilityauction state on either strict breach\"]\n    S4[\"Test indicative price against both expanded corridors\"]\n    S5[\"Reopen remain nocross or extend with a reason\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"endpoint equality nocross and onecorridoronly failure\"}\n    D --> O[\"reopened + diagnostics\"]\n    O --> A[\"Audit: Equality at any corridor endpoint is inside\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f03-a01/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Tick-Size Validation calculation flow",
            "source": "flowchart LR\n    S1[\"Validate price tick scale and policy identity\"]\n    S2[\"Divide price by tick using integer arithmetic\"]\n    S3[\"Accept a zero remainder\"]\n    S4[\"Otherwise report lowerupper valid neighbors and reject\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"zero versus nonzero remainder\"}\n    D --> O[\"valid + diagnostics\"]\n    O --> A[\"Audit: A valid price has zero remainder\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f03-a02/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Price-Band Validation calculation flow",
            "source": "flowchart LR\n    S1[\"Validate the ordered band\"]\n    S2[\"Apply the declared inclusiveexclusive comparison\"]\n    S3[\"Classify below inside or above\"]\n    S4[\"Return distances and source time\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"inclusive equality at each band edge\"}\n    D --> O[\"valid + diagnostics\"]\n    O --> A[\"Audit: Lower band is strictly below upper band\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f03-a03/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Self-Trade Prevention calculation flow",
            "source": "flowchart LR\n    S1[\"Sort marketable contra orders by pricetime\"]\n    S2[\"Execute external interest normally\"]\n    S3[\"At a matching STP group apply the selected mode\"]\n    S4[\"Emit every cancellation decrement and execution\"]\n    S5[\"Return the residual book\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"first sameparticipant and samegroup encounter\"}\n    D --> O[\"prevented_self_quantity + diagnostics\"]\n    O --> A[\"Audit: Prevented self quantity is never reported as execution\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f03-a04/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Cancel-on-Disconnect calculation flow",
            "source": "flowchart LR\n    S1[\"Validate session trigger list policy and orders\"]\n    S2[\"Test whether the disconnect class triggers\"]\n    S3[\"Filter orders by owning session\"]\n    S4[\"Apply bookTIF retention policy\"]\n    S5[\"Return canceled IDs and retention reasons\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"configured trigger and session ownership\"}\n    D --> O[\"canceled_order_ids + diagnostics\"]\n    O --> A[\"Audit: Orders from another session are never canceled\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f03-a05/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Fat-Finger Limit calculation flow",
            "source": "flowchart LR\n    S1[\"Validate order and configured limits\"]\n    S2[\"Compute exact notional\"]\n    S3[\"Compute buyabove or sellbelow aggressive deviation\"]\n    S4[\"Evaluate quantity notional and price checks\"]\n    S5[\"Return all violations\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"equality at each configured maximum\"}\n    D --> O[\"violations + diagnostics\"]\n    O --> A[\"Audit: Notional equals integer price times quantity\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f03-a06/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Circuit-Breaker Trigger calculation flow",
            "source": "flowchart LR\n    S1[\"Validate reference observation thresholds and prior st\"]\n    S2[\"Compute nonnegative decline\"]\n    S3[\"Find the highest reached threshold\"]\n    S4[\"Compare reached level with prior triggered level\"]\n    S5[\"Return action and next threshold distance\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"exact equality and alreadytriggered suppression\"}\n    D --> O[\"newly_triggered_level + diagnostics\"]\n    O --> A[\"Audit: Thresholds are strictly increasing\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f04-a01/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Limit-Order Lifecycle State Machine calculation flow",
            "source": "flowchart LR\n    S1[\"Initialize pendingnew with full leaves\"]\n    S2[\"Accept or reject the entry\"]\n    S3[\"Apply each liveorder fill to cumulative and notional\"]\n    S4[\"Resolve cancel expire replace or complete fill\"]\n    S5[\"Emit an audit transition and block postterminal events\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"terminalstate finality and the overfill guard\"}\n    D --> O[\"status + diagnostics\"]\n    O --> A[\"Audit: Cumulative fill never exceeds original quantity\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f04-a02/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Cancel/Replace Priority Rule calculation flow",
            "source": "flowchart LR\n    S1[\"Validate original displayedlimit scope\"]\n    S2[\"Compare original and replacement price\"]\n    S3[\"Compare replacement quantity with current leaves\"]\n    S4[\"Preserve only when both canonical conditions pass\"]\n    S5[\"Return effective sequence and reason\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"venueordertype eligibility for the preserve exception\"}\n    D --> O[\"priority_preserved + diagnostics\"]\n    O --> A[\"Audit: A newpriority result uses the later replace sequence\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f04-a03/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Partial-Fill and Residual-Quantity Processing calculation flow",
            "source": "flowchart LR\n    S1[\"Freeze original quantity\"]\n    S2[\"Reject duplicate execution IDs\"]\n    S3[\"Validate the next fill against current leaves\"]\n    S4[\"Update cumulative notional and quantity\"]\n    S5[\"Emit residual state after every fill\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"duplicate executions and the overfill equality boundary\"}\n    D --> O[\"leaves_quantity + diagnostics\"]\n    O --> A[\"Audit: Cumulative plus leaves equals original quantity\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f04-a04/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Queue Position and Ahead-Volume Calculation calculation flow",
            "source": "flowchart LR\n    S1[\"Validate unique order IDs and sequences\"]\n    S2[\"Locate a displayed target\"]\n    S3[\"Filter exact side and price\"]\n    S4[\"Sort displayed orders by arrival sequence\"]\n    S5[\"Sum earlier residuals and report hidden excluded quant\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"displayedonly FIFO and exact price equality\"}\n    D --> O[\"ahead_volume + diagnostics\"]\n    O --> A[\"Audit: Displayed rank equals ahead order count plus one\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f04-a05/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Iceberg/Reserve-Order Replenishment calculation flow",
            "source": "flowchart LR\n    S1[\"Initialize displayed and reserve components\"]\n    S2[\"Consume the current displayed tranche\"]\n    S3[\"When it reaches zero expose the next bounded tranche\"]\n    S4[\"Increment displayed priority for every replenishment\"]\n    S5[\"Return fillreplenish audit and conserved residuals\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"zerodisplay trigger versus venuespecific replenishment rul\"}\n    D --> O[\"replenishment_count + diagnostics\"]\n    O --> A[\"Audit: Executed plus total remaining equals original total\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f04-a06/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Marketable-Order Multi-Level Sweep calculation flow",
            "source": "flowchart LR\n    S1[\"Validate incoming and resting IDs quantities and seque\"]\n    S2[\"Select oppositeside candidates\"]\n    S3[\"Sort by best price then FIFO sequence\"]\n    S4[\"Fill and decrement each marketable resting order\"]\n    S5[\"Post or cancel residual and return the mutated book\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"marketability FIFO sequence and residual postversuscancel \"}\n    D --> O[\"filled_quantity + diagnostics\"]\n    O --> A[\"Audit: Incoming filled plus residual equals requested quantity\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f01-a01/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "TWAP Execution calculation flow",
            "source": "flowchart LR\n    S1[\"Validate parent lot horizon and bucket count\"]\n    S2[\"Convert parent to lots\"]\n    S3[\"Assign equal base lots\"]\n    S4[\"Distribute residual lots by stable bucket order\"]\n    S5[\"Build exact time boundaries and cumulative targets\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"available lots versus bucket count\"}\n    D --> O[\"schedule + diagnostics\"]\n    O --> A[\"Audit: Every target is lotaligned\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f01-a02/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Historical VWAP Execution calculation flow",
            "source": "flowchart LR\n    S1[\"Validate parent lot profile ID and volume array\"]\n    S2[\"Sum historical volume\"]\n    S3[\"Compute each buckets ideal lot numerator\"]\n    S4[\"Allocate base lots and rank fractional remainders\"]\n    S5[\"Emit cumulative targets and profile lineage\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"zeroweight buckets and tied remainder allocation\"}\n    D --> O[\"schedule + diagnostics\"]\n    O --> A[\"Audit: Weights sum to one within displayed rounding\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f01-a03/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Adaptive VWAP Execution calculation flow",
            "source": "flowchart LR\n    S1[\"Validate parent realized data forecast executed quanti\"]\n    S2[\"Project total market volume\"]\n    S3[\"Calculate lotfloored target completed now\"]\n    S4[\"Classify aheadbehind and compute catchup\"]\n    S5[\"Allocate postcatchup lots by remaining forecast\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"executed quantity equal to the target completed quantity\"}\n    D --> O[\"pacing_state + diagnostics\"]\n    O --> A[\"Audit: Executed plus scheduled future quantity equals the parent\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f01-a04/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Percentage-of-Volume Execution calculation flow",
            "source": "flowchart LR\n    S1[\"Validate parent rate volume basis lot and child cap\"]\n    S2[\"Accumulate observed market volume\"]\n    S3[\"Compute lotfloored cumulative target\"]\n    S4[\"Release the smaller of deficit cap and parent residual\"]\n    S5[\"Report achieved participation and completion\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> S5\n    S5 --> D{\"target deficit equal to zero child cap and parent completi\"}\n    D --> O[\"released_quantity + diagnostics\"]\n    O --> A[\"Audit: Released quantity never exceeds the parent\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f02-a01/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Almgren-Chriss Optimal Execution calculation flow",
            "source": "flowchart LR\n    S1[\"Validate parent intervals lot and nonnegative weights\"]\n    S2[\"Compute kappa and continuous trade weights or equal we\"]\n    S3[\"Allocate every parent lot by largest remainder\"]\n    S4[\"Accumulate temporaryimpact and inventoryrisk score com\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"inventory risk exactly zero\"}\n    D --> O[\"schedule + diagnostics\"]\n    O --> A[\"Audit: Scheduled quantity equals the parent\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f02-a02/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Implementation-Shortfall Execution calculation flow",
            "source": "flowchart LR\n    S1[\"Validate side prices parent candidates lots and score \"]\n    S2[\"Compute sideaware move from decision price and retain \"]\n    S3[\"Score each declared child candidate\"]\n    S4[\"Choose the minimum score with deterministic smallerchi\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"current price exactly equal to the decision price\"}\n    D --> O[\"selected_child_quantity + diagnostics\"]\n    O --> A[\"Audit: Selected child belongs to the candidate set and does not e\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f02-a03/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Arrival-Price Execution calculation flow",
            "source": "flowchart LR\n    S1[\"Validate benchmark side rates deadline volume parent c\"]\n    S2[\"Compute the signed move from arrival price\"]\n    S3[\"Apply deadline favorable adverse then insideband prece\"]\n    S4[\"Floor the volume target to lots and cap by parent and \"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"signed move exactly plus or minus the tolerance\"}\n    D --> O[\"child_quantity + diagnostics\"]\n    O --> A[\"Audit: Child is lotaligned and cannot exceed the parent or max ch\"]"
          }
        ]
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f02-a04/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Liquidity-Seeking Execution calculation flow",
            "source": "flowchart LR\n    S1[\"Validate parent policy and event schema\"]\n    S2[\"Read events in callersupplied decision order\"]\n    S3[\"Reject stale lowconfidence outsidelimit or sublot even\"]\n    S4[\"Release capped quantity and update the residual parent\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"confidence exactly equal to the minimum and age exactly eq\"}\n    D --> O[\"accepted_quantity + diagnostics\"]\n    O --> A[\"Audit: Accepted quantity plus remaining quantity equals the paren\"]"
          }
        ]
      },
      "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": "Walks a list of dark opportunities in order and, for each one, either plans a lot-aligned exposure or records the first gate that refused it: the fallback window has arrived, firm probability is below the threshold, price improvement is below the threshold, the indicated size is under the minimum, or the dark cap is exhausted. Everything left over is reported as lit fallback quantity. The gating is deterministic arithmetic; no fill rate, adverse-selection cost or reversion is estimated, and no venue is chosen.",
        "params": [
          {
            "name": "input",
            "type": "{ total_quantity, lot_size, maximum_dark_fraction_bps, minimum_firm_probability_bps, minimum_price_improvement_atoms, minimum_execution_quantity, max_exposure_per_window, fallback_window, dark_opportunities }",
            "required": true,
            "description": "All scalars are integers. `maximum_dark_fraction_bps` and `minimum_firm_probability_bps` are basis points capped at 10000; `minimum_execution_quantity` and `max_exposure_per_window` must be multiples of `lot_size`. `dark_opportunities` is a nonempty array of `{ opportunity_id, window, indicated_quantity, firm_probability_bps, price_improvement_atoms }`. There is no venue list and no reference price.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ total_quantity, maximum_dark_fraction_bps, dark_quantity_cap, planned_dark_exposure_quantity, lit_fallback_quantity, dark_opportunity_count, accepted_dark_window_count, opportunities, state }",
          "description": "The lot-floored dark cap, the total planned dark exposure, the residual routed to lit fallback, and a per-opportunity audit carrying the planned exposure, the `expose-dark` / `fallback-active` / `firm-probability-below-threshold` / `price-improvement-below-threshold` / `minimum-size-not-met` / `dark-cap-reached` reason and the remaining dark cap. `state` is `dark-plan-complete` when nothing falls back to lit, and `lit-fallback-required` otherwise."
        },
        "warmup": null,
        "errors": [
          {
            "when": "inputs is not an object",
            "behaviour": "throws"
          },
          {
            "when": "total_quantity or lot_size is invalid, or total_quantity is not lot-aligned",
            "behaviour": "throws"
          },
          {
            "when": "a required scalar is missing, non-integer, or outside its positive/nonnegative range",
            "behaviour": "throws"
          },
          {
            "when": "maximum_dark_fraction_bps or minimum_firm_probability_bps exceeds 10000",
            "behaviour": "throws"
          },
          {
            "when": "minimum_execution_quantity or max_exposure_per_window is not lot-aligned",
            "behaviour": "throws"
          },
          {
            "when": "dark_opportunities is missing or empty",
            "behaviour": "throws"
          },
          {
            "when": "an opportunity is not an object, lacks a nonempty opportunity_id, or holds an invalid window, quantity, probability or improvement",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(opportunities)",
          "space": "O(opportunities)"
        }
      },
      "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": "verified",
        "via": "D"
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f02-a05/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Opportunistic Dark-Pool Execution calculation flow",
            "source": "flowchart LR\n    S1[\"Validate parent dark fraction thresholds lots fallback\"]\n    S2[\"Compute the total lotfloored dark cap\"]\n    S3[\"Before fallback accept only opportunities that pass pr\"]\n    S4[\"Cap each exposure and send the unexposed residual to t\"]\n    S1 --> S2\n    S2 --> S3\n    S3 --> S4\n    S4 --> D{\"opportunity window exactly equal to the fallback window\"}\n    D --> O[\"planned_dark_exposure_quantity + diagnostics\"]\n    O --> A[\"Audit: Planned dark exposure never exceeds its cap\"]"
          }
        ]
      },
      "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": "D14-F01-A01",
      "name": "Markowitz Mean-Variance",
      "headline": null,
      "slug": "markowitz-mean-variance",
      "path": "portfolio-construction/mean-risk-optimization/markowitz-mean-variance",
      "taxonomy": {
        "domainId": "D14",
        "domain": "Portfolio Construction",
        "familyId": "D14-F01",
        "family": "Mean-Risk Optimization",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/portfolio-construction/mean-risk-optimization/markowitz-mean-variance",
        "entry": "markowitzMeanVariance",
        "params": [
          "assetIdsInput",
          "muInput",
          "covarianceInput",
          "targetReturnInput",
          "options"
        ],
        "exports": [
          "markowitzMeanVariance"
        ],
        "archetype": "record-transform",
        "signature": "markowitzMeanVariance(assetIdsInput, muInput, covarianceInput, targetReturnInput, options)"
      },
      "api": {
        "summary": "Solves for the lowest-variance asset weights that still meet a declared return target, from expected returns and a covariance matrix.",
        "params": [
          {
            "name": "assetIdsInput",
            "type": "ordered string array",
            "required": true,
            "description": "One stable identifier per column/row",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "muInput",
            "type": "finite number array",
            "required": true,
            "description": "Expected return for one declared horizon",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "covarianceInput",
            "type": "finite number matrix",
            "required": true,
            "description": "Variance/covariance for that same horizon and return unit",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "targetReturnInput",
            "type": "finite number",
            "required": true,
            "description": "Same expected-return unit/horizon as `mu`",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "options",
            "type": "MarkowitzOptions",
            "required": false,
            "description": null,
            "constraints": null,
            "nulls": null,
            "default": "{}"
          }
        ],
        "returns": null,
        "warmup": null,
        "errors": [],
        "complexity": null
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "markowitzMeanVariance([\"A\",\"B\"], [0.06,0.14], [[0.04,0.01],[0.01,0.09]], 0.1, {\"maxIterations\":10000})",
        "args": [
          {
            "value": [
              "A",
              "B"
            ],
            "elided": null
          },
          {
            "value": [
              0.06,
              0.14
            ],
            "elided": null
          },
          {
            "value": [
              [
                0.04,
                0.01
              ],
              [
                0.01,
                0.09
              ]
            ],
            "elided": null
          },
          {
            "value": 0.1,
            "elided": null
          },
          {
            "value": {
              "maxIterations": 10000
            },
            "elided": null
          }
        ],
        "output": {
          "assetIds": [
            "A",
            "B"
          ],
          "mu": [
            0.06,
            0.14
          ],
          "targetReturn": 0.1,
          "weights": [
            0.4999999999999999,
            0.5000000000000001
          ],
          "expectedReturn": 0.1,
          "variance": 0.037500000000000006,
          "volatility": 0.19364916731037085,
          "budgetResidual": 0,
          "targetResidual": 0,
          "lowerBoundResidual": 0,
          "fwGapS": 0,
          "fwGap": 0,
          "matrixScale": 0.09,
          "status": "optimal"
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 21
        },
        "outputShape": "object with 21 fields: assetIds, mu, targetReturn, weights, expectedReturn, variance, volatility, budgetResidual, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d14-f01-a01/static/article-hero.svg"
          },
          {
            "file": "markowitz-frontier.svg",
            "url": "https://thefintechbuilder.com/content/d14-f01-a01/static/markowitz-frontier.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Primary technical sources",
          "title": "Primary technical sources",
          "author": null,
          "url": null
        },
        {
          "key": "Input-lineage sources",
          "title": "Input-lineage sources",
          "author": null,
          "url": null
        },
        {
          "key": "Contextual Google destinations inspected",
          "title": "Contextual Google destinations inspected",
          "author": null,
          "url": null
        },
        {
          "key": "Citation boundaries",
          "title": "Citation boundaries",
          "author": null,
          "url": null
        },
        {
          "key": "Independent recheck",
          "title": "2026-09-16",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/portfolio-construction/mean-risk-optimization/markowitz-mean-variance/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/portfolio-construction/mean-risk-optimization/markowitz-mean-variance/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D14-F01-A02",
      "name": "Global Minimum Variance",
      "headline": null,
      "slug": "global-minimum-variance",
      "path": "portfolio-construction/mean-risk-optimization/global-minimum-variance",
      "taxonomy": {
        "domainId": "D14",
        "domain": "Portfolio Construction",
        "familyId": "D14-F01",
        "family": "Mean-Risk Optimization",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/portfolio-construction/mean-risk-optimization/global-minimum-variance",
        "entry": "globalMinimumVariance",
        "params": [
          "assetIdsInput",
          "covarianceInput",
          "options"
        ],
        "exports": [
          "globalMinimumVariance"
        ],
        "archetype": "record-transform",
        "signature": "globalMinimumVariance(assetIdsInput, covarianceInput, options)"
      },
      "api": {
        "summary": "Computes the lowest-variance weights obtainable from a covariance matrix alone, with no expected-return input, and shows why clipping a short weight is not optimization.",
        "params": [
          {
            "name": "assetIdsInput",
            "type": "unknown",
            "required": true,
            "description": null,
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "covarianceInput",
            "type": "unknown",
            "required": true,
            "description": null,
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "options",
            "type": "GMVOptions",
            "required": false,
            "description": null,
            "constraints": null,
            "nulls": null,
            "default": "{}"
          }
        ],
        "returns": null,
        "warmup": null,
        "errors": [],
        "complexity": null
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "globalMinimumVariance([\"A\",\"B\"], [[0.04,0.01],[0.01,0.09]], {\"maxIterations\":10000})",
        "args": [
          {
            "value": [
              "A",
              "B"
            ],
            "elided": null
          },
          {
            "value": [
              [
                0.04,
                0.01
              ],
              [
                0.01,
                0.09
              ]
            ],
            "elided": null
          },
          {
            "value": {
              "maxIterations": 10000
            },
            "elided": null
          }
        ],
        "output": {
          "assetIds": [
            "A",
            "B"
          ],
          "mu": null,
          "matrixScale": 0.09,
          "variant": "gmv-long-only-fully-invested",
          "method": "projected-gradient-simplex-line-search",
          "maxIterations": 10000,
          "weights": [
            0.7272727272727273,
            0.27272727272727276
          ],
          "variance": 0.03181818181818182,
          "volatility": 0.17837651700316895,
          "expectedReturn": null,
          "budgetResidual": 0,
          "lowerBoundResidual": 0,
          "fwGapS": 0,
          "fwGap": 0
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 19
        },
        "outputShape": "object with 19 fields: assetIds, mu, matrixScale, variant, method, maxIterations, weights, variance, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d14-f01-a02/static/article-hero.svg"
          },
          {
            "file": "gmv-simplex-clipping.svg",
            "url": "https://thefintechbuilder.com/content/d14-f01-a02/static/gmv-simplex-clipping.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "R01",
          "title": "MOSEK Portfolio Optimization Cookbook — Markowitz portfolio",
          "author": null,
          "url": null
        },
        {
          "key": "R02",
          "title": "On the Estimation of the Global Minimum Variance Portfolio",
          "author": null,
          "url": null
        },
        {
          "key": "R03",
          "title": "Portfolio Optimization / Markowitz model",
          "author": null,
          "url": null
        },
        {
          "key": "R04",
          "title": "SEC: Stock Splits",
          "author": null,
          "url": null
        },
        {
          "key": "R05",
          "title": "Investor.gov: Ex-Dividend Dates",
          "author": null,
          "url": null
        },
        {
          "key": "R06",
          "title": "UW Markowitz project notes",
          "author": null,
          "url": null
        },
        {
          "key": "R07",
          "title": "Historical/case boundary",
          "author": null,
          "url": null
        },
        {
          "key": "Independent recheck",
          "title": "2026-09-16",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/portfolio-construction/mean-risk-optimization/global-minimum-variance/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/portfolio-construction/mean-risk-optimization/global-minimum-variance/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D14-F01-A03",
      "name": "Maximum Sharpe Ratio",
      "headline": null,
      "slug": "maximum-sharpe-ratio",
      "path": "portfolio-construction/mean-risk-optimization/maximum-sharpe-ratio",
      "taxonomy": {
        "domainId": "D14",
        "domain": "Portfolio Construction",
        "familyId": "D14-F01",
        "family": "Mean-Risk Optimization",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/portfolio-construction/mean-risk-optimization/maximum-sharpe-ratio",
        "entry": "maximumSharpe",
        "params": [
          "assetIdsInput",
          "muInput",
          "covarianceInput",
          "riskFreeReturnInput",
          "options"
        ],
        "exports": [
          "maximumSharpe"
        ],
        "archetype": "record-transform",
        "signature": "maximumSharpe(assetIdsInput, muInput, covarianceInput, riskFreeReturnInput, options)"
      },
      "api": {
        "summary": "Finds the weights that maximize the Sharpe ratio for a declared risk-free return, with the benchmark, horizon a