mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-18 02:28:05 +00:00
90 lines
3.4 KiB
Markdown
90 lines
3.4 KiB
Markdown
# 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
|
|
|
|
```csharp
|
|
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);
|