D08-F07-A15 / Released engineering topic

Swing Structure Detector: Formula, Worked Example, Visual Guide, and Failure Modes

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.

Swing Structure Detector contract flow from validated evidence to a bounded outputD08 / D08-F07
<!-- LEVEL-2-HERO:START -->

Swing Structure Detector contract overview

Hero takeaway: 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. Open the hero at full size.

<!-- LEVEL-2-HERO:END -->

If you have ever placed Swing Structure Detector on a chart and wondered why another platform showed a different answer, the problem probably was not arithmetic. The quiet differences usually live in the input source, lookback, seed, warm-up, equality rule, session reset, or a vendor-specific convention hidden behind the same label.

This guide gives you an audit trail instead of a magic line. You will see exactly what the topic measures, which formula this package selects, how to walk a synthetic example, what to test, and where interpretation must stop. The practical question is: Which highs and lows qualify as causal swings rather than provisional extrema?

The source lineage and maintained software context are recorded in Technical Analysis: Modern Perspectives (CFA Institute Research Foundation), TA-Lib maintained source, Long-Term Storage Capacity of Reservoirs. Those sources establish vocabulary and implementation history; they do not prove that the indicator predicts returns or that every product should share one default.

What you will be able to do

By the end, you can:

  • explain Swing Structure Detector in plain language before reaching for notation;
  • validate ordered OHLC observations, explicit lookbacks and thresholds, and pivots confirmed without future leakage;
  • reproduce the selected calculation or review someone else's implementation;
  • distinguish waiting, invalid, calculated, and interpreted states;
  • diagnose the most common cross-platform mismatches; and
  • compare Swing Structure Detector with range, trend, volatility, entropy, and breakout classifiers under the same causal clock without calling one universally better.

You need only basic arithmetic and ordered time-series intuition. When OHLC is used, O, H, L, and C mean open, high, low, and close for one completed observation. No trading-strategy knowledge is required.

Start with the useful intuition

Swing Structure Detector is a lens applied to already observed data. Its job is to make one feature of the path easier to inspect. The output may describe geometry, relative location, smoothed direction, realized range, volume-weighted state, statistical position, or phase. It does not add information that was absent from the inputs.

That distinction matters. A mathematically correct output answers what the selected transformation says now. It does not answer whether the next price will rise, whether an order should be placed, or whether a result will survive costs. Those are separate questions requiring point-in-time data and an outcome study.

Before looking at the formula, inspect the contract map. Notice that validation and timing come first; interpretation comes last.

Swing Structure Detector concept map

Open the concept map at full size.

Freeze the selected convention

The canonical variant is the formula printed below with oldest-to-newest inputs, finite values, declared parameters, no future observations, and rounding only after calculation.

Plain text
swing high at p iff H_p = max(H_(p-2..p+2)); swing low at p iff L_p = min(L_(p-2..p+2)); emitted at bar p+2

The window is fixed. There is no prominence threshold, no separate left-bar and right-bar count, and no minimum separation between consecutive swings; no parameters key changes any of that. The family validates period (default 20, integer of at least 2) alongside the other regime topics, but this topic never reads it.

Four consequences follow directly from the expression:

  • Equality qualifies. The test is =, not >. A bar whose high merely ties the largest high in its five-bar window is still confirmed as a swing high, and the same holds for lows.
  • Confirmation lags by exactly two bars. The window needs two bars to the right of the pivot, so a swing at bar p is published at bar p+2 and never earlier. The two most recent bars in any series can therefore never carry a confirmation.
  • A bar can confirm both. An outside bar can be both the highest high and the lowest low of its window. Both swing_high and swing_low are then populated, but structure is a single string and the low branch runs second, so the low's label is the one that survives.
  • Labels compare against the previous swing of the same kind. A confirmed high is HH when it is strictly above the previous confirmed high, LH otherwise (including an exact tie), and swing-high when it is the first one. Lows mirror this with HL, LL, and swing-low. Distance between the two swings is not considered.

From index 4 onward structure always carries a string, reading none on bars that confirm nothing, which is why ready_at is 4 for any input. swing_high and swing_low stay null except on the bars that confirm one.

Read every subscript as an observation index, not automatically a day. A window of n=14 can mean 14 daily bars, 14 five-minute bars, or 14 eligible events; those are different measurements. Calculate with full precision and round only for display.

Where a denominator can be zero, the correct output is an explicit undefined state unless the contract names another policy. Where recursion is present, publish the seed and warm-up. Where a pivot or session range must be confirmed, publish the first timestamp at which it was knowable. A later chart can look obvious while still being impossible to reproduce causally.

The data contract is part of the algorithm

Use ordered OHLC observations, explicit lookbacks and thresholds, and pivots confirmed without future leakage. The minimum production record should also preserve:

FieldWhy it mattersSafe policy
timestampOrders the evidence clocktimezone-aware, oldest to newest, unique after declared correction precedence
price fieldsSupply the mathematical inputfinite, same currency and adjustment basis
volume, when usedSupplies a weight or activity fieldname unit, venue coverage, session, and zero/missing policy
parametersFix the selected variantstore with every output or model version
availability timePrevents future leakagecompute only after required source fields are knowable
revision stateMakes replay deterministicidentify provisional, corrected, or final observations

Reject NaN, infinity, mixed split-adjustment bases, unexplained duplicate timestamps, and out-of-order observations. Do not silently forward-fill prices across a closed market or treat missing volume as zero. Those choices change the meaning of the result.

<!-- LEVEL-1-VERIFICATION:START -->

Level 1 verification contract

The short name is not the algorithm. For this package, the reproducible identity of Swing Structure Detector is the selected expression, the data basis, the clock, the parameter state, and the invalid-output policy taken together.

Contract itemFrozen rule for this topic
canonical questionWhich highs and lows qualify as causal swings rather than provisional extrema?
selected expressionswing high at p iff H_p = max(H_(p-2..p+2)); swing low at p iff L_p = min(L_(p-2..p+2)); emitted at bar p+2
required evidenceordered OHLC observations, explicit lookbacks and thresholds, and pivots confirmed without future leakage
output clockA state at t may use only observations available through t; confirmed swings retain their confirmation timestamp and are never relabeled as known at the pivot bar.
invalid statesnon-finite, misordered, future-dated, basis-mixed, unsupported parameters, insufficient warm-up, or undefined denominator/state
interpretation boundaryRegime labels compress a path; they are model outputs with uncertainty, not permanent market truths.

The displayed expression is the package's frozen publication convention. Names used by other platforms are not sufficient evidence of formula parity; compare coefficients, windows, equality rules, seeds, and output clocks.

This table separates four things that are often blurred together: cited lineage, the repository's explicit convention, synthetic example inputs, and the interpretation you draw from the result. Read the full definition contract, data contract, and verification fixture before implementing a variant.

<!-- LEVEL-1-VERIFICATION:END -->

Calculate it step by step

  1. Declare the measurement. Name the source price or OHLC fields, interval, session, adjustment basis, parameters, seed, and equality rules.
  2. Validate before calculating. Check order, finiteness, duplicates, eligibility, and minimum history. A clean error is more informative than a plausible zero.
  3. Build intermediates causally. Rolling extrema, averages, ranges, pivots, returns, phase states, and volume sums may use only information available now.
  4. Apply the formula without display rounding. Keep numerator, denominator, weights, state, and boundary comparisons available for audit.
  5. Emit a structured result. Return the value plus ready, state, window boundaries, parameters, and reason codes.
  6. Interpret the measurement—not a story. Explain what changed in the input and intermediate state before attaching a market narrative.

A worked numerical example

Use fourteen synthetic bars. Only high and low enter the calculation, so the table lists just those. The pivot column shows which bar p = t - 2 is being tested on each row.

thighlowpivot pswing_highswing_lowstructure
0104100—nullnullnull
1106102—nullnullnull
2110104—nullnullnull
3107103—nullnullnull
4105982110nullswing-high
5106993nullnullnone
61081014null98swing-low
7112965nullnullnone
81091036nullnullnone
9110104711296LL
101101058nullnullnone
111081069nullnullnone
1210710510110nullLH
1310610411nullnullnone

Row by row, the four confirmations are the whole lesson.

At t = 4 the pivot is bar 2, whose high of 110 is the largest of [104, 106, 110, 107, 105]. It is the first confirmed high, so it is labelled swing-high rather than compared with anything. Note where it is published: the high occurred at bar 2, but nothing could be said about it until bar 4.

At t = 6 the pivot is bar 4, whose low of 98 is the smallest of [104, 103, 98, 99, 101]. First confirmed low, so swing-low.

At t = 9 the pivot is bar 7, an outside bar. Its high of 112 is the largest of [106, 108, 112, 109, 110] and its low of 96 is the smallest of [99, 101, 96, 103, 104]. Both series are populated — swing_high is 112 and swing_low is 96 — but structure can hold only one label. The high branch writes HH, because 112 beats the previous high of 110; the low branch then runs and overwrites it with LL, because 96 does not beat the previous low of 98. The published string is LL, and the higher high is visible only in the swing_high series. Read both series, not just the label.

At t = 12 the pivot is bar 10, whose high of 110 merely ties bar 9's high inside the window [109, 110, 110, 108, 107]. The equality test admits it. Against the previous confirmed high of 112 it is not higher, so it is labelled LH. Bar 9 itself never confirms: its own window [112, 109, 110, 110, 108] peaks at 112.

Bars 12 and 13 close the series without ever being tested as pivots, because no bar exists two positions to their right.

Every number in that table is a synthetic teaching input or an author-derived calculation. It was chosen because you can check it with a calculator. It is not a historical security, provider observation, or backtest.

The visual below makes the audit sequence explicit. Read from input contract to intermediate state, then to the selected boundary, and only then to output.

Swing Structure Detector worked-contract trace

Open the worked-contract trace at full size.

Implementation blueprint

The most useful reference implementation returns diagnostics rather than one naked number. In language-neutral pseudocode:

Plain text
function calculate(observations, parameters):
    contract = freeze_source_clock_basis_and_variant(parameters)
    rows = validate_sort_and_align(observations, contract)
    if rows are invalid:
        return { ready: false, state: "invalid", reason: exact_reason }
    if rows are shorter than the declared warm-up:
        return { ready: false, state: "waiting", reason: "insufficient_history" }

    intermediate = build_causal_state(rows, contract)
    if required denominator or state is undefined:
        return { ready: false, state: "undefined", diagnostics: intermediate }

    value = apply_selected_formula(intermediate, contract)
    return {
        ready: true,
        state: "calculated",
        value: value,
        parameters: contract.parameters,
        window_start: intermediate.window_start,
        window_end: intermediate.window_end,
        diagnostics: intermediate.audit_fields
    }

This package deliberately does not claim that such pseudocode is a finished Python or TypeScript implementation. A production implementation still needs independent expected values, boundary tests, shared fixtures, numerical tolerances, and parity checks in every delivered language.

Use the guided lab

Open the self-contained Swing Structure Detector guided lab. It begins in an informative canonical state and offers three scenarios:

  1. Canonical — enough valid synthetic evidence to calculate.
  2. Boundary — one warm-up or equality decision remains unresolved.
  3. Failure — invalid timing, ordering, basis, or numeric input is rejected.

Use Back and Step to expose one stage at a time. Change the declared window and notice that the lab resets dependent state. Play uses the same transition as Step; with reduced motion, Play advances exactly once. The chart is an evidence-readiness trace, not a simulated market return.

Tests that protect meaning

A strong test suite for Swing Structure Detector should cover more than a happy-path value:

TestWhat it protects
canonical synthetic fixtureformula, units, sign, and displayed example
one observation before warm-upwaiting remains distinct from zero
equality at every thresholdinclusive versus strict comparisons
zero denominator or zero rangedefined null/error policy
NaN, infinity, duplicate, reverse ordervalidation before arithmetic
parameter minimum and maximumrejected versus supported variants
split, roll, or session discontinuityconsistent basis and calendar
prefix replayno later observation changes an earlier causal output
independent arithmeticexpected values do not call the implementation under test

For recursive methods, also test the seed, restart behavior, long-history convergence, and a flat series. For rolling statistics, test ties and interpolation. For patterns, test one-tick boundary failures and prior-only context. For phase methods, test phase wrap, sampling regularity, and unstable-period handling.

Where implementations disagree

Two charts carrying the same title can differ for legitimate reasons:

  • one uses close while another uses midpoint or typical price;
  • one includes the current bar in an extremum while another uses prior-only history;
  • one seeds from the first observation while another seeds from an initial average;
  • one emits the earliest mathematical value while another removes an unstable period;
  • one resets at an exchange session while another runs continuously;
  • one treats equality as a match while another requires a strict crossing;
  • one adjusts historical OHLC but not volume consistently; or
  • the short label refers to materially different published formulas.

The cure is not to hunt for a universally correct screenshot. Compare contracts: source fields, coefficients, window boundaries, seed, warm-up, reset, equality, missing-data policy, and first valid index.

Compare nearby methods by the question they answer

The nearest comparison set is range, trend, volatility, entropy, and breakout classifiers under the same causal clock. Use this decision table:

DecisionChoose Swing Structure Detector when…Choose a nearby method when…
target featureWhich highs and lows qualify as causal swings rather than provisional extrema? is the exact diagnosticanother method measures the feature you actually need
unitsits raw or normalized scale is usefulcross-asset comparability needs another denominator
responsivenessits selected window and smoothing fit the clockyou need a different lag/noise trade-off
auditabilityyou can publish inputs and intermediate statea proprietary or opaque approximation cannot be validated
evidencedescriptive measurement is enougha decision requires a separately validated forecast or causal model

Neither column is automatically superior. The right method is the one whose contract matches the question and whose failure modes your system can monitor.

Practical use—and responsible limits

Use Swing Structure Detector as a feature, diagnostic, chart annotation, alert input, screening field, or quality-control measurement only after its availability clock is explicit. Store the parameters and reason codes beside the value so a later reviewer can reconstruct why the state changed.

Do not treat a threshold crossing as an order, a pattern match as confirmation, or a high/low oscillator reading as destiny. Regime labels compress a path; they are model outputs with uncertainty, not permanent market truths. If you want to claim association with future returns, design a point-in-time study with a frozen universe, survivorship and look-ahead controls, transaction costs, multiple-testing controls, out-of-sample evaluation, and uncertainty intervals.

Historical-example decision

Not useful for definition. A named episode would add story value but no stronger understanding of the deterministic calculation. The synthetic example is smaller, fully redistributable, and independently checkable. A later empirical companion can add real data only after identity, venue, session, adjustment basis, retrieval time, revision status, parameters, costs, biases, uncertainty, and licensing are frozen.

What to remember

  • Swing Structure Detector asks: Which highs and lows qualify as causal swings rather than provisional extrema?
  • The selected formula is swing high at p iff H_p = max(H_(p-2..p+2)); swing low at p iff L_p = min(L_(p-2..p+2)); emitted at bar p+2.
  • Input source, clock, basis, seed, warm-up, window, and equality policy are part of the algorithm.
  • Undefined and insufficient-history states must not be converted to zero.
  • The worked values are synthetic and author-derived.
  • Correct calculation does not establish prediction or profitability.

You can now audit Swing Structure Detector from source data to interpretation. Continue with Higher-High/Lower-Low Structure and compare which assumption changes, while keeping Directional Persistence nearby as the preceding family reference.

Primary and authoritative references

<!-- LEVEL-2-ENHANCEMENT:START -->

Choose Swing Structure Detector deliberately

The useful choice is not “which indicator is best?” It is “which contract answers my question with the fewest hidden choices?” Use this decision table before adding the method to a chart, feature pipeline, or research notebook.

ChoiceUse it whenVerify before accepting output
Swing Structure DetectorYou need the exact question and convention printed in this package.Validate readiness, diagnostics, and the topic-specific failure state.
Simpler baselineYou first need an unambiguous reference from range, trend, volatility, entropy, and breakout classifiers under the same causal clock.Prefer interpretability; record the same source, basis, clock, and window.
Nearby alternativeYour actual question differs in smoothing, normalization, geometry, or state semantics.Freeze its contract separately; never swap formulas under one label.
No outputInputs are missing, non-finite, misordered, basis-mixed, future-dated, or still warming up.Return waiting, invalid, or undefined with a reason—not zero.

Swing Structure Detector decision guide

Decision takeaway: choose the selected method only when its exact measurement question matches yours. Otherwise prefer the simpler baseline, freeze a different variant, or withhold output. Open the decision guide at full size.

Learning path and related topics

  • Prepare with: D08-F07-A14. Confirm you understand the family's input basis and availability clock first.
  • Compare with: D08-F07-A01, D08-F07-A02. Compare questions, not screenshots; nearby titles may use different windows, normalization, seeds, or state definitions.
  • Continue to: D08-F07-A16. Carry forward ready, available_at, parameters, and diagnostics instead of forwarding a naked number.
  • Implementation boundary: this is a complete implementation package with Python and TypeScript entry points, topic-owned fixtures, and parity checks. The pseudocode remains a teaching blueprint for the shipped contract.

The relationship IDs are stored in metadata.yaml so the visitor layer can resolve stable cards when these article-only topics later clear the complete-package publishing gate.

<!-- LEVEL-2-ENHANCEMENT:END --> <!-- IMPLEMENTATION-RELEASE:START -->

Executable reference package

This topic now includes a causal reference calculation, a 96-observation synthetic multi-regime fixture, a flat/zero-volume boundary fixture, Python tests, and a Node/TypeScript API parity test. Synthetic observations are teaching data, not issuer history or evidence of predictive value. Run python tests/test_reference.py and node --experimental-strip-types tests/reference.test.ts from this topic directory.

<!-- IMPLEMENTATION-RELEASE:END -->

Swing Structure Detector calculation flow

Purpose: keep validation, timing, calculation, and interpretation separate.

Takeaway: an output is publishable only when its input clock and selected convention are visible.

Swing Structure Detector readiness and evidence states

Takeaway: waiting, rejected, and calculated are different states; a system should not coerce them into zero.

ReferencesPrimary sources and evidence notes

Expand the source trail, evidence role, and limitations behind the engineering choices.

S1 — Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)

  • Organization or authors: Gordon Scott, Michael Carr and Mark Cremonie; CFA Institute Research Foundation
  • Source type: Professional-body literature review
  • Publication/effective date: CFA Institute Research Foundation Literature Review, 2016
  • Version/accessed: accessed 2026-08-11
  • URL: Technical Analysis: Modern Perspectives (CFA Institute Research Foundation)
  • Jurisdiction/applicability: technical education and reproducible software convention
  • Supports: the professional-body account of technical-analysis practice that places Swing Structure Detector in context
  • Limitations: Professional curriculum context for trend, support, resistance, indicators, and pattern interpretation.

S2 — TA-Lib maintained source

  • Organization or authors: TA-Lib project contributors
  • Source type: Maintained open-source reference implementation
  • Publication/effective date: Undated living repository, main branch
  • Version/accessed: accessed 2026-08-11
  • URL: TA-Lib maintained source
  • Jurisdiction/applicability: technical education and reproducible software convention
  • Supports: the maintained reference implementation whose naming, parameter defaults and calculation order Swing Structure Detector is compared against
  • Limitations: Reference source for rolling extrema, ATR, and related primitives where applicable.

S3 — Long-Term Storage Capacity of Reservoirs

  • Organization or authors: H. E. Hurst
  • Source type: Peer-reviewed original research
  • Publication/effective date: Transactions of the American Society of Civil Engineers, volume 116, pages 770-799, 1951
  • Version/accessed: accessed 2026-08-11
  • URL: Long-Term Storage Capacity of Reservoirs
  • Jurisdiction/applicability: technical education and reproducible software convention
  • Supports: the original rescaled-range analysis in the lineage behind Swing Structure Detector
  • Limitations: Hurst's original rescaled-range work; modern estimators and financial interpretations require additional care.

Evidence decision

The package uses synthetic teaching inputs and author-derived arithmetic. A named security example is not useful for defining Swing Structure Detector because it would add market story without improving the deterministic contract. A later empirical article would need licensed point-in-time data, instrument and venue identity, session and adjustment basis, retrieval time, corrections, parameter version, costs, bias controls, uncertainty, and redistribution permission.

<!-- LEVEL-1-EVIDENCE:START -->

Level 1 evidence map

Claim classSupportPublication boundary
lineage and maintained terminologyS1–S3 abovesource naming does not establish universal formula parity
selected mathematical conventionresearch/DEFINITION-CONTRACT.mdexplicit repository choice unless an exact primary formula source is named
numerical teaching valuesarticle worked examplesynthetic inputs and author-derived arithmetic, not provider facts
causal and invalid-state policydata-contract/CONTRACT.mdsafety and reproducibility policy, not a performance claim
historical casenot-useful-for-definitionrequires a separately evidenced point-in-time study before publication

Reviewed 2026-08-11. No current market fact, named security result, forecast, or profitability claim is made.

<!-- LEVEL-1-EVIDENCE:END -->
swing_structure_detector.ts
/** Dependency-free native TypeScript entry point for D08-F07-A15: Swing Structure Detector. */
import { swingStructureDetector as nativeSwingStructureDetector, type TopicInput, type TopicResult } from "../../../../../../shared/missing_152/typescript/referenceRuntime.ts";

export const TOPIC_ID = "D08-F07-A15";
export const TITLE = "Swing Structure Detector";

export function swingStructureDetector(input: TopicInput): TopicResult {
  return nativeSwingStructureDetector(input);
}
Full-height labguided labOpen full screen
Written by

Fintech engineer building market-data and financial systems, and the author of every article, glossary record, and reference implementation on The Fintech Builder.