Files
QuanTAlib/lib/core/midbody/Midbody.md
T
Miha Kralj 33d20f2a18 feat(dynamics): add PlusDI, MinusDI, PlusDM, MinusDM indicators
Complete thin Dx-composition wrapper indicators with full test coverage:

- PlusDi/MinusDi: Directional Indicator wrappers (DiPlus/DiMinus from Dx)
- PlusDm/MinusDm: Directional Movement wrappers (DmPlus/DmMinus from Dx)
- Individual validation tests per indicator directory (TALib, Skender, bounds)
- Combined unit tests (DiDm.Tests.cs) and validation tests (DiDm.Validation.Tests.cs)
- Quantower wrappers + tests for all 4 indicators
- PineScript v6 implementations with compensated RMA
- Normalized .md documentation for all indicators and categories
- 182 tests passing, 0 failures
2026-03-11 20:21:52 -07:00

4.9 KiB

MIDBODY: Open-Close Average

The average of open and close reveals the candle body's center — where intent met execution.

Property Value
Category Core
Inputs OHLCV bar (TBar)
Parameters None
Outputs Single series (Midbody)
Output range Varies (see docs)
Warmup 1 bars

Midbody computes the arithmetic mean of Open and Close prices: (O + C) \times 0.5. It captures where price started and ended within a bar, ignoring intra-bar extremes. No lookback period, no state, always hot after the first bar. Equivalent to TBar.OC2.

Historical Context

The Open-Close average has no formal attribution in technical analysis literature. Unlike HL2 (Median Price) or HLC3 (Typical Price) which appear in TA-Lib and classic references, OC2 exists primarily as a computed property in modern libraries like Skender.Stock.Indicators (CandlePart.OC2).

The rationale for OC2 is straightforward: Open and Close represent the consensus prices at session boundaries. High and Low represent transient extremes that may reflect noise or stops being triggered. By averaging only the session endpoints, OC2 filters out intra-bar volatility entirely.

OC2 is useful as an input to trend-following indicators when you want the trend signal to reflect directional bias (where did the bar open and close?) rather than range (how far did it swing?). It also serves as the natural center for Heikin-Ashi calculations (HA Close = OHLC4, but HA state tracking uses the prior bar's OC2).

Architecture & Physics

1. Core Formula

\text{Midbody} = (O + C) \times 0.5

The multiplication form avoids a division operation. The JIT compiles * 0.5 to a single vmulsd instruction.

2. State Management

OC2 is stateless. Each bar's output depends only on that bar's Open and Close values. The State record struct tracks only:

  • LastValidOpen / LastValidClose for NaN substitution
  • LastResult for fallback when both inputs are non-finite
  • Count for IsHot tracking

3. Complexity

Metric Value
Time (streaming) O(1)
Time (batch) O(n)
Space O(1) — no buffers
Warmup 1 bar

Mathematical Foundation

Parameters

None. OC2 is parameterless.

Weight Distribution

Component Weight
Open 0.5
High 0
Low 0
Close 0.5

Comparison with Other Price Transforms

Transform Formula Components Used Bias
Midbody (O+C) \times 0.5 O, C Session endpoints only
MEDPRICE (H+L) \times 0.5 H, L Range-centered; ignores O/C
TYPPRICE (O+H+L) / 3 O, H, L Opening-biased range
HLC3 (H+L+C) / 3 H, L, C Close-influenced range
AVGPRICE (O+H+L+C) \times 0.25 O, H, L, C Fully balanced
WCLPRICE (H+L+2C) \times 0.25 H, L, C Close double-weighted

Output Interpretation

  • OC2 > Close: bar closed below its midpoint (bearish lean)
  • OC2 < Close: bar closed above its midpoint (bullish lean)
  • OC2 = Close: Open = Close (doji-like bar)

Performance Profile

Operation Count (Streaming Mode)

Operation Count
Addition 1
Multiplication 1
Comparison 0
Memory access 2 (O, C)
Total 4 ops

Batch Mode (SIMD Analysis)

The batch loop is a trivial element-wise (a[i] + b[i]) * 0.5. Auto-vectorization by the JIT is expected for aligned spans. Manual SIMD is not implemented because the operation is already memory-bandwidth-bound at this simplicity level.

Validation

Library Method Tolerance Status
Skender CandlePart.OC2 1e-7 Batch + Streaming + Span
TA-Lib N/A Not available
TBar.OC2 Property 1e-10 All bars match

Common Pitfalls

  1. Confusing OC2 with MEDPRICE. MEDPRICE is (H+L)/2; OC2 is (O+C)/2. They answer different questions: range center vs. session endpoint average.
  2. Confusing OC2 with Midpoint. Midpoint is (Highest(V,N) + Lowest(V,N))/2 — a rolling indicator with a period parameter. OC2 has no period.
  3. Using OC2 for volatility estimation. OC2 deliberately ignores H and L. For volatility-aware price proxies, use HLC3 or OHLC4 instead.
  4. Expecting TA-Lib compatibility. TA-Lib does not implement OC2. Validation is against Skender only.
  5. Gap analysis with OC2. When Open and Close are nearly equal (doji bars), OC2 converges to Close. This is correct behavior, not a bug.

Resources

  • Skender.Stock.Indicators CandlePart.OC2 enum documentation.
  • Murphy, J.J. Technical Analysis of the Financial Markets. New York Institute of Finance, 1999.