# rsi-divergence-detector
**Lightweight, tested Python library & CLI for detecting RSI divergences (regular & hidden) on time‑series price data.**
It uses **Wilder‑style RSI**, **robust peak finding** via SciPy, and **deterministic, monotonic pivot pairing** with adaptive defaults so you can get useful results with minimal tuning. Clean function contracts, no hidden globals, and a tidy tabular output.
> **Python**: 3.9–3.13 · **Dependencies**: NumPy (>=1.26), pandas (>=2.2.2), SciPy (>=1.13), Typer (for the CLI)
---
## Table of Contents
* [Features](#features)
* [Install](#install)
* [Quickstart (Python API)](#quickstart-python-api)
* [Quickstart (CLI)](#quickstart-cli)
* [Returned Schema](#returned-schema)
* [Concepts & Algorithm](#concepts--algorithm)
* [Divergences we detect](#divergences-we-detect)
* [RSI (Wilder‑style)](#rsi-wilderstyle)
* [Peak detection (SciPy)](#peak-detection-scipy)
* [Monotonic pivot pairing](#monotonic-pivot-pairing)
* [API Reference](#api-reference)
* [`calculate_rsi`](#calculate_rsi)
* [`find_divergences`](#find_divergences)
* [Tuning Tips](#tuning-tips)
* [Examples](#examples)
* [Testing](#testing)
* [Versioning / Compatibility](#versioning--compatibility)
* [Limitations & Notes](#limitations--notes)
* [Roadmap](#roadmap)
* [License](#license)
* [References](#references)
* [SEO Keywords](#seo-keywords)
---
## Features
* ✅ **Regular & hidden RSI divergences**: `regular_bullish`, `regular_bearish`, `hidden_bullish`, `hidden_bearish`.
* ✅ **Deterministic pairing**: nearest‑in‑time RSI pivots for each consecutive price pivot pair; **monotonic in time** (no re‑use/backtracking).
* ✅ **Adaptive defaults** for peak gates (prominence/width/distance) to stay scale‑aware without hand‑tuning.
* ✅ **Clear contracts**: explicit, stateless functions returning a tidy DataFrame.
* ✅ **CLI + Python API** (Typer‑powered CLI with `--help`).
* ✅ **Tests**: unit tests (RSI consistency & divergence scenarios) + property tests (Hypothesis) + CLI smoke tests.
---
## Install
From PyPI:
```bash
pip install rsi-divergence-detector
```
> Uses prebuilt wheels for NumPy/SciPy on common platforms; keep Python/pip recent for smooth installs.
---
## Quickstart (Python API)
```python
import pandas as pd
from rsi_divergence import calculate_rsi, find_divergences
# Price series with DatetimeIndex
close = pd.read_csv("ohlc.csv", index_col=0, parse_dates=True)["close"]
# Wilder-style RSI (period=14)
rsi = calculate_rsi(close, period=14)
# Detect divergences using adaptive defaults
divs = find_divergences(
prices=close,
rsi=rsi,
rsi_period=14, # used for adaptive defaults
max_lag=3, # bars allowed between paired price/RSI pivots
include_hidden=True, # include hidden (continuation) divergences
)
print(divs.head())
```
---
## Quickstart (CLI)
Read a CSV with a `close` column (index = timestamps):
```bash
rsi_divergence --file ohlc.csv --rsi-period 14
```
Optional tuning (omit to use adaptive defaults):
```bash
rsi_divergence \
--file ohlc.csv \
--rsi-period 14 \
--price-prominence 0.25 \
--rsi-prominence 5 \
--price-width 2 \
--rsi-width 2 \
--distance 7 \
--max-lag 3 \
--include-hidden
```
> The CLI is built with **Typer**; `--help` shows all options and help text.
---
## Returned Schema
The detector returns a `pd.DataFrame` with one row per divergence:
```
['kind','p1_idx','p1_price','p2_idx','p2_price','r1_idx','r1_val','r2_idx','r2_val']
```
* `kind`: one of `regular_bullish`, `regular_bearish`, `hidden_bullish`, `hidden_bearish`
* `p1_idx`, `p2_idx`: timestamps of the price pivots (first → second)
* `p1_price`, `p2_price`: price at those pivots
* `r1_idx`, `r2_idx`: timestamps of the paired RSI pivots
* `r1_val`, `r2_val`: RSI values at those pivots
---
## Concepts & Algorithm
### Divergences we detect
* **Regular bullish**: price makes **lower low (LL)**, RSI makes **higher low (HL)** → potential reversal up.
* **Regular bearish**: price makes **higher high (HH)**, RSI makes **lower high (LH)** → potential reversal down.
* **Hidden bullish**: price **HL**, RSI **LL** → continuation of **uptrend**.
* **Hidden bearish**: price **LH**, RSI **HH** → continuation of **downtrend**.
> Hidden divergences are commonly framed as **trend continuation**; regular divergences as **reversal‑leaning**.
### RSI (Wilder‑style)
We compute RSI exactly as described by Wilder: average gains/losses smoothed with **Wilder’s smoothing** (a form of exponential smoothing with $\alpha = 1/\text{period}$), then
$\text{RSI} = 100 - \frac{100}{1+RS} \quad \text{where} \quad RS = \frac{\text{avg gain}}{\text{avg loss}}.$
The output is aligned to the input index and lives in **\[0, 100]** (initial warm‑up may contain NaNs).
### Peak detection (SciPy)
We locate local extrema on **price** and **RSI** using `scipy.signal.find_peaks`. Minima are obtained by applying `find_peaks` to the **negated series**. The following gates control selection:
* **prominence** — how much a peak stands out relative to its surroundings
* **width** — peak “thickness” in samples
* **distance** — minimum separation between neighboring peaks
**Adaptive defaults** (used when the parameter is `None`):
* `price_prominence` ≈ `0.5 * rolling_std(pct_change, window=rsi_period).iloc[-1] * last_price` (scale‑aware)
* `rsi_prominence` = `5.0` (RSI points)
* `price_width` = `2`, `rsi_width` = `2`
* `distance` = `max(1, rsi_period // 2)`
### Monotonic pivot pairing
For each **consecutive price pivot pair** (minima for bullish paths, maxima for bearish), we pick the **nearest‑in‑time RSI pivots** within ±`max_lag` bars. Pairing is **monotonic**: the second RSI pivot must occur **after** the first RSI pivot used in that loop, and we don’t re‑use RSI pivots out of order. When comparisons below hold, we append a row:
* `regular_bullish`: `price2 < price1` **and** `rsi2 > rsi1`
* `regular_bearish`: `price2 > price1` **and** `rsi2 < rsi1`
* `hidden_bullish`: `price2 > price1` **and** `rsi2 < rsi1`
* `hidden_bearish`: `price2 < price1` **and** `rsi2 > rsi1`
`allow_equal=True` (default) makes comparisons inclusive (tolerant to ties on intrabar data).
---
## API Reference
### `calculate_rsi`
```python
calculate_rsi(prices: pd.Series, period: int = 14) -> pd.Series
```
**Contract**
* `prices`: non‑empty `pd.Series` with a **monotonic increasing `DatetimeIndex`**.
* Returns an RSI `pd.Series` aligned to `prices.index` with values in **\[0,100]** (warm‑up may contain NaNs).
* Implements **Wilder‑style** smoothing (equivalent to an EMA with `alpha = 1/period`, `adjust=False`).
### `find_divergences`
```python
find_divergences(
prices: pd.Series,
rsi: pd.Series,
*,
rsi_period: int = 14,
price_prominence: float | None = None,
rsi_prominence: float | None = None,
price_width: int | None = None,
rsi_width: int | None = None,
distance: int | None = None,
max_lag: int = 3,
include_hidden: bool = True,
allow_equal: bool = True,
) -> pd.DataFrame
```
**Inputs**
* `prices`, `rsi`: numeric `pd.Series` with the **same `DatetimeIndex`** (RSI will be reindexed to `prices`).
* `rsi` can have initial NaNs (warm‑up).
* **Adaptive defaults** apply when gates are `None` (see above).
**Pairing & rules**
* For each consecutive price pivot pair, find nearest RSI pivots within ±`max_lag` bars, enforcing **monotonic time**.
* Append a row when the rule for the target divergence holds (see [Monotonic pivot pairing](#monotonic-pivot-pairing)).
**Returns**
* A tidy `pd.DataFrame` with the [columns described here](#returned-schema).
---
## Tuning Tips
* Too **few** pivots? Lower `price_prominence` / `rsi_prominence` and/or `distance`, or increase `max_lag`.
* Too **many/weak** pivots? Increase **prominence** and **width**.
* Intraday noise: increase `width` and `distance` to suppress micro‑wiggles.
* Interested in classical RSI zones (≈30/70)? Filter results post‑hoc by `r1_val`/`r2_val` ranges. (Heuristics, not hard rules.)
---
## Examples
**Minimal flow**
```python
import pandas as pd
from rsi_divergence import calculate_rsi, find_divergences
close = pd.read_csv("ohlc.csv", index_col=0, parse_dates=True)["close"]
rsi = calculate_rsi(close, period=14)
divs = find_divergences(close, rsi, rsi_period=14, include_hidden=True)
print(divs.tail())
```
**Filtering for “strong” bearish signals**
```python
strong = divs[(divs["kind"].str.contains("bearish")) & (divs["r2_val"] > 65.0)]
```
**Plotting (optional)**
Layer `p1/p2` and `r1/r2` pivots over candles (e.g., with `mplfinance`) to visualize each divergence. Plotting is intentionally **out‑of‑scope** here to keep the core lightweight.
---
## Testing
We ship unit tests and property tests:
* **Unit tests**: RSI contract, range, Wilder consistency; deterministic divergence scenarios; CLI smoke test.
* **Property tests** (Hypothesis): generator‑driven random but valid series; **no crashes**, **stable schema**.
Run the suite:
```bash
pip install -r requirements-dev.txt # or: pip install -e ".[dev]"
pytest -q
```
---
## Versioning / Compatibility
* **Python**: 3.9–3.13
* **NumPy**: ≥ 1.26 (works with NumPy 2.x)
* **pandas**: ≥ 2.2.2
* **SciPy**: ≥ 1.13
We avoid strict upper pins to reduce resolver conflicts across environments.
---
## Limitations & Notes
* Divergences can **persist** without immediate reversal/continuation; confirm with broader structure/flow.
* Peak‑based methods are **parameter‑sensitive**; adaptive defaults help, but **context matters** (market, timeframe).
* This library **does not** predict or place orders; it **annotates structure** to support your own analysis.
---
## Roadmap
A forward‑looking sketch (subject to change):
* Optional **zone‑aware scoring** (down‑weight signals far from RSI 30/70 bands).
* **Multi‑timeframe** aggregation (e.g., 1h pivots confirming 5m signals).
* **Volume/OI/CVD** hooks for richer filters.
* **Numba/JIT** fast‑path for large universes.
* Streaming examples (WebSocket → rolling detection).
PRs welcome!
---
## References
* **RSI (Wilder)** and smoothing background — StockCharts “RSI” notes; TC2000 help; Wikipedia overview.
* StockCharts: [https://chartschool.stockcharts.com/table-of-contents/technical-indicators-and-overlays/technical-indicators/relative-strength-index-rsi](https://chartschool.stockcharts.com/table-of-contents/technical-indicators-and-overlays/technical-indicators/relative-strength-index-rsi)
* TC2000 Help: [https://help.tc2000.com/m/69404/l/747071-rsi-wilder-s-rsi](https://help.tc2000.com/m/69404/l/747071-rsi-wilder-s-rsi)
* Wikipedia: [https://en.wikipedia.org/wiki/Relative\_strength\_index](https://en.wikipedia.org/wiki/Relative_strength_index)
* **Divergence** (regular vs hidden) — Babypips primers; Investopedia overviews.
* Babypips Hidden Divergence: [https://www.babypips.com/learn/forex/hidden-divergence](https://www.babypips.com/learn/forex/hidden-divergence)
* Babypips Divergence Cheatsheet: [https://www.babypips.com/learn/forex/divergence-cheat-sheet](https://www.babypips.com/learn/forex/divergence-cheat-sheet)
* Investopedia Divergence: [https://www.investopedia.com/terms/d/divergence.asp](https://www.investopedia.com/terms/d/divergence.asp)
* **SciPy peak selection** — `find_peaks`, `peak_prominences`, `peak_widths`.
* find\_peaks: [https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find\_peaks.html](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html)
* peak\_prominences: [https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak\_prominences.html](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak_prominences.html)
* peak\_widths: [https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak\_widths.html](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak_widths.html)
* **Typer (CLI)** — official docs.
* Typer: [https://typer.tiangolo.com/](https://typer.tiangolo.com/)
---
## SEO Keywords
RSI divergence detector, RSI hidden divergence, Wilder RSI Python, RSI Wilder smoothing, RSI divergence Python library, SciPy find_peaks RSI, RSI divergence CLI, regular vs hidden divergence, price oscillator divergence, RSI 30/70 heuristic, pandas RSI, quantitative trading divergence, Python technical analysis.
Raw data
{
"_id": null,
"home_page": null,
"name": "rsi-divergence-detector",
"maintainer": null,
"docs_url": null,
"requires_python": "<3.14,>=3.9",
"maintainer_email": null,
"keywords": "rsi, divergence, finance, trading, technical-analysis",
"author": "Tomi \u0160eregi",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/b1/c5/a8f65a79464b213adfc32d134d549a03b9b8b624e0bc34c48fe6473f5878/rsi_divergence_detector-0.1.0.tar.gz",
"platform": null,
"description": "# rsi-divergence-detector\n\n**Lightweight, tested Python library & CLI for detecting RSI divergences (regular & hidden) on time\u2011series price data.**\n\nIt uses **Wilder\u2011style RSI**, **robust peak finding** via SciPy, and **deterministic, monotonic pivot pairing** with adaptive defaults so you can get useful results with minimal tuning. Clean function contracts, no hidden globals, and a tidy tabular output.\n\n> **Python**: 3.9\u20133.13 \u00b7 **Dependencies**: NumPy (>=1.26), pandas (>=2.2.2), SciPy (>=1.13), Typer (for the CLI)\n\n---\n\n## Table of Contents\n\n* [Features](#features)\n* [Install](#install)\n* [Quickstart (Python API)](#quickstart-python-api)\n* [Quickstart (CLI)](#quickstart-cli)\n* [Returned Schema](#returned-schema)\n* [Concepts & Algorithm](#concepts--algorithm)\n\n * [Divergences we detect](#divergences-we-detect)\n * [RSI (Wilder\u2011style)](#rsi-wilderstyle)\n * [Peak detection (SciPy)](#peak-detection-scipy)\n * [Monotonic pivot pairing](#monotonic-pivot-pairing)\n* [API Reference](#api-reference)\n\n * [`calculate_rsi`](#calculate_rsi)\n * [`find_divergences`](#find_divergences)\n* [Tuning Tips](#tuning-tips)\n* [Examples](#examples)\n* [Testing](#testing)\n* [Versioning / Compatibility](#versioning--compatibility)\n* [Limitations & Notes](#limitations--notes)\n* [Roadmap](#roadmap)\n* [License](#license)\n* [References](#references)\n* [SEO Keywords](#seo-keywords)\n\n---\n\n## Features\n\n* \u2705 **Regular & hidden RSI divergences**: `regular_bullish`, `regular_bearish`, `hidden_bullish`, `hidden_bearish`.\n* \u2705 **Deterministic pairing**: nearest\u2011in\u2011time RSI pivots for each consecutive price pivot pair; **monotonic in time** (no re\u2011use/backtracking).\n* \u2705 **Adaptive defaults** for peak gates (prominence/width/distance) to stay scale\u2011aware without hand\u2011tuning.\n* \u2705 **Clear contracts**: explicit, stateless functions returning a tidy DataFrame.\n* \u2705 **CLI + Python API** (Typer\u2011powered CLI with `--help`).\n* \u2705 **Tests**: unit tests (RSI consistency & divergence scenarios) + property tests (Hypothesis) + CLI smoke tests.\n\n---\n\n## Install\n\nFrom PyPI:\n\n```bash\npip install rsi-divergence-detector\n```\n\n> Uses prebuilt wheels for NumPy/SciPy on common platforms; keep Python/pip recent for smooth installs.\n\n---\n\n## Quickstart (Python API)\n\n```python\nimport pandas as pd\nfrom rsi_divergence import calculate_rsi, find_divergences\n\n# Price series with DatetimeIndex\nclose = pd.read_csv(\"ohlc.csv\", index_col=0, parse_dates=True)[\"close\"]\n\n# Wilder-style RSI (period=14)\nrsi = calculate_rsi(close, period=14)\n\n# Detect divergences using adaptive defaults\ndivs = find_divergences(\n prices=close,\n rsi=rsi,\n rsi_period=14, # used for adaptive defaults\n max_lag=3, # bars allowed between paired price/RSI pivots\n include_hidden=True, # include hidden (continuation) divergences\n)\n\nprint(divs.head())\n```\n\n---\n\n## Quickstart (CLI)\n\nRead a CSV with a `close` column (index = timestamps):\n\n```bash\nrsi_divergence --file ohlc.csv --rsi-period 14\n```\n\nOptional tuning (omit to use adaptive defaults):\n\n```bash\nrsi_divergence \\\n --file ohlc.csv \\\n --rsi-period 14 \\\n --price-prominence 0.25 \\\n --rsi-prominence 5 \\\n --price-width 2 \\\n --rsi-width 2 \\\n --distance 7 \\\n --max-lag 3 \\\n --include-hidden\n```\n\n> The CLI is built with **Typer**; `--help` shows all options and help text.\n\n---\n\n## Returned Schema\n\nThe detector returns a `pd.DataFrame` with one row per divergence:\n\n```\n['kind','p1_idx','p1_price','p2_idx','p2_price','r1_idx','r1_val','r2_idx','r2_val']\n```\n\n* `kind`: one of `regular_bullish`, `regular_bearish`, `hidden_bullish`, `hidden_bearish`\n* `p1_idx`, `p2_idx`: timestamps of the price pivots (first \u2192 second)\n* `p1_price`, `p2_price`: price at those pivots\n* `r1_idx`, `r2_idx`: timestamps of the paired RSI pivots\n* `r1_val`, `r2_val`: RSI values at those pivots\n\n---\n\n## Concepts & Algorithm\n\n### Divergences we detect\n\n* **Regular bullish**: price makes **lower low (LL)**, RSI makes **higher low (HL)** \u2192 potential reversal up.\n* **Regular bearish**: price makes **higher high (HH)**, RSI makes **lower high (LH)** \u2192 potential reversal down.\n* **Hidden bullish**: price **HL**, RSI **LL** \u2192 continuation of **uptrend**.\n* **Hidden bearish**: price **LH**, RSI **HH** \u2192 continuation of **downtrend**.\n\n> Hidden divergences are commonly framed as **trend continuation**; regular divergences as **reversal\u2011leaning**.\n\n### RSI (Wilder\u2011style)\n\nWe compute RSI exactly as described by Wilder: average gains/losses smoothed with **Wilder\u2019s smoothing** (a form of exponential smoothing with $\\alpha = 1/\\text{period}$), then\n$\\text{RSI} = 100 - \\frac{100}{1+RS} \\quad \\text{where} \\quad RS = \\frac{\\text{avg gain}}{\\text{avg loss}}.$\nThe output is aligned to the input index and lives in **\\[0, 100]** (initial warm\u2011up may contain NaNs).\n\n### Peak detection (SciPy)\n\nWe locate local extrema on **price** and **RSI** using `scipy.signal.find_peaks`. Minima are obtained by applying `find_peaks` to the **negated series**. The following gates control selection:\n\n* **prominence** \u2014 how much a peak stands out relative to its surroundings\n* **width** \u2014 peak \u201cthickness\u201d in samples\n* **distance** \u2014 minimum separation between neighboring peaks\n\n**Adaptive defaults** (used when the parameter is `None`):\n\n* `price_prominence` \u2248 `0.5 * rolling_std(pct_change, window=rsi_period).iloc[-1] * last_price` (scale\u2011aware)\n* `rsi_prominence` = `5.0` (RSI points)\n* `price_width` = `2`, `rsi_width` = `2`\n* `distance` = `max(1, rsi_period // 2)`\n\n### Monotonic pivot pairing\n\nFor each **consecutive price pivot pair** (minima for bullish paths, maxima for bearish), we pick the **nearest\u2011in\u2011time RSI pivots** within \u00b1`max_lag` bars. Pairing is **monotonic**: the second RSI pivot must occur **after** the first RSI pivot used in that loop, and we don\u2019t re\u2011use RSI pivots out of order. When comparisons below hold, we append a row:\n\n* `regular_bullish`: `price2 < price1` **and** `rsi2 > rsi1`\n* `regular_bearish`: `price2 > price1` **and** `rsi2 < rsi1`\n* `hidden_bullish`: `price2 > price1` **and** `rsi2 < rsi1`\n* `hidden_bearish`: `price2 < price1` **and** `rsi2 > rsi1`\n\n`allow_equal=True` (default) makes comparisons inclusive (tolerant to ties on intrabar data).\n\n---\n\n## API Reference\n\n### `calculate_rsi`\n\n```python\ncalculate_rsi(prices: pd.Series, period: int = 14) -> pd.Series\n```\n\n**Contract**\n\n* `prices`: non\u2011empty `pd.Series` with a **monotonic increasing `DatetimeIndex`**.\n* Returns an RSI `pd.Series` aligned to `prices.index` with values in **\\[0,100]** (warm\u2011up may contain NaNs).\n* Implements **Wilder\u2011style** smoothing (equivalent to an EMA with `alpha = 1/period`, `adjust=False`).\n\n### `find_divergences`\n\n```python\nfind_divergences(\n prices: pd.Series,\n rsi: pd.Series,\n *,\n rsi_period: int = 14,\n price_prominence: float | None = None,\n rsi_prominence: float | None = None,\n price_width: int | None = None,\n rsi_width: int | None = None,\n distance: int | None = None,\n max_lag: int = 3,\n include_hidden: bool = True,\n allow_equal: bool = True,\n) -> pd.DataFrame\n```\n\n**Inputs**\n\n* `prices`, `rsi`: numeric `pd.Series` with the **same `DatetimeIndex`** (RSI will be reindexed to `prices`).\n* `rsi` can have initial NaNs (warm\u2011up).\n* **Adaptive defaults** apply when gates are `None` (see above).\n\n**Pairing & rules**\n\n* For each consecutive price pivot pair, find nearest RSI pivots within \u00b1`max_lag` bars, enforcing **monotonic time**.\n* Append a row when the rule for the target divergence holds (see [Monotonic pivot pairing](#monotonic-pivot-pairing)).\n\n**Returns**\n\n* A tidy `pd.DataFrame` with the [columns described here](#returned-schema).\n\n---\n\n## Tuning Tips\n\n* Too **few** pivots? Lower `price_prominence` / `rsi_prominence` and/or `distance`, or increase `max_lag`.\n* Too **many/weak** pivots? Increase **prominence** and **width**.\n* Intraday noise: increase `width` and `distance` to suppress micro\u2011wiggles.\n* Interested in classical RSI zones (\u224830/70)? Filter results post\u2011hoc by `r1_val`/`r2_val` ranges. (Heuristics, not hard rules.)\n\n---\n\n## Examples\n\n**Minimal flow**\n\n```python\nimport pandas as pd\nfrom rsi_divergence import calculate_rsi, find_divergences\n\nclose = pd.read_csv(\"ohlc.csv\", index_col=0, parse_dates=True)[\"close\"]\nrsi = calculate_rsi(close, period=14)\ndivs = find_divergences(close, rsi, rsi_period=14, include_hidden=True)\nprint(divs.tail())\n```\n\n**Filtering for \u201cstrong\u201d bearish signals**\n\n```python\nstrong = divs[(divs[\"kind\"].str.contains(\"bearish\")) & (divs[\"r2_val\"] > 65.0)]\n```\n\n**Plotting (optional)**\nLayer `p1/p2` and `r1/r2` pivots over candles (e.g., with `mplfinance`) to visualize each divergence. Plotting is intentionally **out\u2011of\u2011scope** here to keep the core lightweight.\n\n---\n\n## Testing\n\nWe ship unit tests and property tests:\n\n* **Unit tests**: RSI contract, range, Wilder consistency; deterministic divergence scenarios; CLI smoke test.\n* **Property tests** (Hypothesis): generator\u2011driven random but valid series; **no crashes**, **stable schema**.\n\nRun the suite:\n\n```bash\npip install -r requirements-dev.txt # or: pip install -e \".[dev]\"\npytest -q\n```\n\n---\n\n## Versioning / Compatibility\n\n* **Python**: 3.9\u20133.13\n* **NumPy**: \u2265 1.26 (works with NumPy 2.x)\n* **pandas**: \u2265 2.2.2\n* **SciPy**: \u2265 1.13\n\nWe avoid strict upper pins to reduce resolver conflicts across environments.\n\n---\n\n## Limitations & Notes\n\n* Divergences can **persist** without immediate reversal/continuation; confirm with broader structure/flow.\n* Peak\u2011based methods are **parameter\u2011sensitive**; adaptive defaults help, but **context matters** (market, timeframe).\n* This library **does not** predict or place orders; it **annotates structure** to support your own analysis.\n\n---\n\n## Roadmap\n\nA forward\u2011looking sketch (subject to change):\n\n* Optional **zone\u2011aware scoring** (down\u2011weight signals far from RSI 30/70 bands).\n* **Multi\u2011timeframe** aggregation (e.g., 1h pivots confirming 5m signals).\n* **Volume/OI/CVD** hooks for richer filters.\n* **Numba/JIT** fast\u2011path for large universes.\n* Streaming examples (WebSocket \u2192 rolling detection).\n\nPRs welcome!\n\n---\n\n## References\n\n* **RSI (Wilder)** and smoothing background \u2014 StockCharts \u201cRSI\u201d notes; TC2000 help; Wikipedia overview.\n\n * StockCharts: [https://chartschool.stockcharts.com/table-of-contents/technical-indicators-and-overlays/technical-indicators/relative-strength-index-rsi](https://chartschool.stockcharts.com/table-of-contents/technical-indicators-and-overlays/technical-indicators/relative-strength-index-rsi)\n * TC2000 Help: [https://help.tc2000.com/m/69404/l/747071-rsi-wilder-s-rsi](https://help.tc2000.com/m/69404/l/747071-rsi-wilder-s-rsi)\n * Wikipedia: [https://en.wikipedia.org/wiki/Relative\\_strength\\_index](https://en.wikipedia.org/wiki/Relative_strength_index)\n* **Divergence** (regular vs hidden) \u2014 Babypips primers; Investopedia overviews.\n\n * Babypips Hidden Divergence: [https://www.babypips.com/learn/forex/hidden-divergence](https://www.babypips.com/learn/forex/hidden-divergence)\n * Babypips Divergence Cheatsheet: [https://www.babypips.com/learn/forex/divergence-cheat-sheet](https://www.babypips.com/learn/forex/divergence-cheat-sheet)\n * Investopedia Divergence: [https://www.investopedia.com/terms/d/divergence.asp](https://www.investopedia.com/terms/d/divergence.asp)\n* **SciPy peak selection** \u2014 `find_peaks`, `peak_prominences`, `peak_widths`.\n\n * find\\_peaks: [https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find\\_peaks.html](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html)\n * peak\\_prominences: [https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak\\_prominences.html](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak_prominences.html)\n * peak\\_widths: [https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak\\_widths.html](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak_widths.html)\n* **Typer (CLI)** \u2014 official docs.\n\n * Typer: [https://typer.tiangolo.com/](https://typer.tiangolo.com/)\n\n---\n\n## SEO Keywords\n\nRSI divergence detector, RSI hidden divergence, Wilder RSI Python, RSI Wilder smoothing, RSI divergence Python library, SciPy find_peaks RSI, RSI divergence CLI, regular vs hidden divergence, price oscillator divergence, RSI 30/70 heuristic, pandas RSI, quantitative trading divergence, Python technical analysis.\n\n",
"bugtrack_url": null,
"license": "BSD-3-Clause",
"summary": "A tool to detect RSI divergences in price data.",
"version": "0.1.0",
"project_urls": {
"Repository": "https://github.com/AKzar1el/rsi_divergence_detector"
},
"split_keywords": [
"rsi",
" divergence",
" finance",
" trading",
" technical-analysis"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "36f540d322b507455b2dd0c0e8852ebcbfd4e0b9440c57160fa1a29df21ad031",
"md5": "594a8972ee59127e67b8026cdc8fbd95",
"sha256": "e5129f9d58f30a4a15640cf5e493775876e20bf82b81accee69fa11c54d6fb9f"
},
"downloads": -1,
"filename": "rsi_divergence_detector-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "594a8972ee59127e67b8026cdc8fbd95",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<3.14,>=3.9",
"size": 12061,
"upload_time": "2025-08-11T16:23:54",
"upload_time_iso_8601": "2025-08-11T16:23:54.018533Z",
"url": "https://files.pythonhosted.org/packages/36/f5/40d322b507455b2dd0c0e8852ebcbfd4e0b9440c57160fa1a29df21ad031/rsi_divergence_detector-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "b1c5a8f65a79464b213adfc32d134d549a03b9b8b624e0bc34c48fe6473f5878",
"md5": "75a0b186693f7ca7365b54e3cfd94c89",
"sha256": "a64d020d297f02bb078635865c4723dfd583f6047869b8f444ddf970335520a7"
},
"downloads": -1,
"filename": "rsi_divergence_detector-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "75a0b186693f7ca7365b54e3cfd94c89",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<3.14,>=3.9",
"size": 14169,
"upload_time": "2025-08-11T16:23:55",
"upload_time_iso_8601": "2025-08-11T16:23:55.275885Z",
"url": "https://files.pythonhosted.org/packages/b1/c5/a8f65a79464b213adfc32d134d549a03b9b8b624e0bc34c48fe6473f5878/rsi_divergence_detector-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-11 16:23:55",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "AKzar1el",
"github_project": "rsi_divergence_detector",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "rsi-divergence-detector"
}