Files
QuanTAlib/lib/momentum/bop/Bop.md
T

3.4 KiB

BOP: Balance of Power

"The market is a tug of war between buyers and sellers. BOP tells you who's pulling harder."

The Balance of Power (BOP) indicator measures the strength of buying and selling pressure by comparing the closing price to the opening price, relative to the high-low range. It oscillates between -1 and 1, providing a clear picture of market dominance.

Historical Context

Developed by Igor Livshin and published in the August 2001 issue of Stocks & Commodities magazine, BOP was designed to expose the underlying action of price movement. Unlike trend-following indicators that lag, BOP is a momentum oscillator that can identify hidden accumulation or distribution patterns.

Architecture & Physics

BOP is a stateless, zero-lag indicator in its raw form. It evaluates each bar independently, calculating the ratio of the body (Close - Open) to the range (High - Low).

  • Inertia: None (raw).
  • Momentum: Instantaneous.
  • Range: Bounded [-1, 1].

The Zero-Range Challenge

A key architectural challenge is handling bars where High == Low. In these cases, the range is zero, leading to a potential division by zero. QuanTAlib handles this by returning 0, indicating a neutral balance of power (no movement).

Mathematical Foundation

The formula is deceptively simple:

BOP = \frac{Close - Open}{High - Low}

Where:

  • Close > Open: Positive BOP (Buyers dominate)
  • Close < Open: Negative BOP (Sellers dominate)
  • Close = Open: Zero BOP (Balance)
  • High = Low: Zero BOP (No movement)

Performance Profile

BOP is extremely lightweight, requiring minimal computation.

Zero-Allocation Design

The implementation uses stackalloc and Span<T> where applicable, ensuring no heap allocations during the Update cycle. The Calculate method is fully vectorized using SIMD instructions (AVX2) when available, processing multiple bars in parallel.

Metric Score Notes
Throughput 1ns O(1) per bar, SIMD-optimized.
Allocations 0 Zero allocations in the hot path.
Complexity O(1) Constant time per update.
Accuracy 10/10 Exact mathematical calculation.
Timeliness 10/10 Zero lag.
Overshoot 0/10 Bounded -1 to 1.
Smoothness 0/10 Raw signal, very noisy.

Validation

BOP is validated against major technical analysis libraries to ensure correctness.

Library Status Notes
TA-Lib Matches TA_BOP exactly.
Skender Matches GetBop.
Tulip Matches ti.bop.
Ooples Matches CalculateBalanceOfPower.

Common Pitfalls

  • Noise: The raw BOP is very volatile. It is often smoothed with a Moving Average (e.g., SMA-14) to identify trends. QuanTAlib provides the raw signal, allowing you to chain any smoothing algorithm you prefer.
  • Doji Candles: When Open equals Close, BOP is 0. This is mathematically correct but can be interpreted as a lack of momentum.

Usage

using QuanTAlib;

// 1. Streaming (Real-time)
var bop = new Bop();
TValue result = bop.Update(new TBar(time, open, high, low, close, volume));
Console.WriteLine($"BOP: {result.Value}");

// 2. Batch (Historical)
var bars = new TBarSeries(...);
var bopSeries = Bop.Batch(bars);

// 3. Chaining (Smoothing)
var smoothedBop = new Sma(14);
var bop = new Bop();
// ... inside loop ...
var raw = bop.Update(bar);
var smooth = smoothedBop.Update(raw);