@@ -83,6 +83,8 @@ pip install pyindicators
8383 * [ Order Blocks] ( #order-blocks )
8484 * [ Market Structure Break] ( #market-structure-break )
8585 * [ Market Structure CHoCH/BOS] ( #market-structure-chochbos )
86+ * [ Liquidity Sweeps] ( #liquidity-sweeps )
87+ * [ Buyside & Sellside Liquidity] ( #buyside--sellside-liquidity )
8688* [ Pattern recognition] ( #pattern-recognition )
8789 * [ Detect Peaks] ( #detect-peaks )
8890 * [ Detect Bullish Divergence] ( #detect-bullish-divergence )
@@ -1678,6 +1680,152 @@ The function returns:
16781680
16791681![ MARKET_STRUCTURE_CHOCH_BOS] ( https://github.com/coding-kitties/PyIndicators/blob/main/static/images/indicators/market_structure_choch_bos.png )
16801682
1683+ #### Liquidity Sweeps
1684+
1685+ Liquidity Sweeps is a Smart Money Concept indicator that detects when price momentarily pierces a swing high or swing low—grabbing resting liquidity—before reversing. This behaviour is a hallmark of institutional order flow: stop-loss clusters sitting above swing highs (buyside liquidity) or below swing lows (sellside liquidity) get triggered, and price quickly snaps back.
1686+
1687+ Three detection modes are available:
1688+
1689+ - ** Wicks** – the candle wick pierces the swing level but the close remains on the original side.
1690+ - ** Outbreak / Retest** – price closes beyond the level, then a later candle retests it from the other side while closing back.
1691+ - ** All** – combines both wick and outbreak/retest sweeps.
1692+
1693+ ``` python
1694+ def liquidity_sweeps (
1695+ data : Union[PdDataFrame, PlDataFrame],
1696+ swing_length : int = 5 ,
1697+ mode : str = " wicks" ,
1698+ high_column : str = " High" ,
1699+ low_column : str = " Low" ,
1700+ close_column : str = " Close" ,
1701+ bullish_sweep_column : str = " liq_sweep_bullish" ,
1702+ bearish_sweep_column : str = " liq_sweep_bearish" ,
1703+ sweep_high_column : str = " liq_sweep_high" ,
1704+ sweep_low_column : str = " liq_sweep_low" ,
1705+ sweep_type_column : str = " liq_sweep_type" ,
1706+ ) -> Union[PdDataFrame, PlDataFrame]:
1707+ ```
1708+
1709+ Example
1710+
1711+ ``` python
1712+ import pandas as pd
1713+ from pyindicators import (
1714+ liquidity_sweeps,
1715+ liquidity_sweep_signal,
1716+ get_liquidity_sweep_stats
1717+ )
1718+
1719+ # Create sample OHLC data
1720+ df = pd.DataFrame({
1721+ ' High' : [... ],
1722+ ' Low' : [... ],
1723+ ' Close' : [... ]
1724+ })
1725+
1726+ # Detect liquidity sweeps (wick-through mode)
1727+ df = liquidity_sweeps(df, swing_length = 5 , mode = " wicks" )
1728+ print (df[[' liq_sweep_bullish' , ' liq_sweep_bearish' , ' liq_sweep_high' , ' liq_sweep_low' ]])
1729+
1730+ # Generate trading signals
1731+ # 1 = bullish sweep, -1 = bearish sweep, 0 = no sweep
1732+ df = liquidity_sweep_signal(df)
1733+ bullish_sweeps = df[df[' liq_sweep_signal' ] == 1 ]
1734+
1735+ # Get statistics
1736+ stats = get_liquidity_sweep_stats(df)
1737+ print (f " Total bullish sweeps: { stats[' total_bullish' ]} " )
1738+ print (f " Total bearish sweeps: { stats[' total_bearish' ]} " )
1739+ ```
1740+
1741+ The function returns:
1742+ - ` liq_sweep_bullish ` : 1 when a bullish liquidity sweep is detected (sell-side liquidity grabbed)
1743+ - ` liq_sweep_bearish ` : 1 when a bearish liquidity sweep is detected (buy-side liquidity grabbed)
1744+ - ` liq_sweep_high ` : Price level of the swept swing high
1745+ - ` liq_sweep_low ` : Price level of the swept swing low
1746+ - ` liq_sweep_type ` : Type of sweep (` "wick" ` or ` "outbreak_retest" ` )
1747+
1748+ ** Trading Strategy:**
1749+ - Bullish sweeps below swing lows indicate potential long entries (smart money accumulation)
1750+ - Bearish sweeps above swing highs indicate potential short entries (smart money distribution)
1751+ - Use the sweep level (` liq_sweep_high ` / ` liq_sweep_low ` ) as a reference for stop-loss placement
1752+
1753+ ![ LIQUIDITY_SWEEPS] ( https://github.com/coding-kitties/PyIndicators/blob/main/static/images/indicators/liquidity_sweeps.png )
1754+
1755+ #### Buyside & Sellside Liquidity
1756+
1757+ Buyside & Sellside Liquidity is a Smart Money Concept indicator that identifies clustered swing-point liquidity pools, their breaches, and optional liquidity voids.
1758+
1759+ A * buyside liquidity level* forms when multiple swing highs (≥ ` min_cluster_count ` ) cluster within an ATR-scaled margin band. A * sellside liquidity level* is the mirror image for swing lows. When price breaks through a level, a * breach* is recorded. Optionally, * liquidity voids* (large directional candles with minimal overlap) can be detected as areas price is likely to revisit.
1760+
1761+ ``` python
1762+ def buyside_sellside_liquidity (
1763+ data : Union[PdDataFrame, PlDataFrame],
1764+ detection_length : int = 7 ,
1765+ margin : float = 6.9 ,
1766+ buyside_margin : float = 2.3 ,
1767+ sellside_margin : float = 2.3 ,
1768+ detect_voids : bool = False ,
1769+ atr_period : int = 10 ,
1770+ atr_void_period : int = 200 ,
1771+ min_cluster_count : int = 3 ,
1772+ max_swings : int = 50 ,
1773+ high_column : str = " High" ,
1774+ low_column : str = " Low" ,
1775+ open_column : str = " Open" ,
1776+ close_column : str = " Close" ,
1777+ ) -> Union[PdDataFrame, PlDataFrame]:
1778+ ```
1779+
1780+ Example
1781+
1782+ ``` python
1783+ import pandas as pd
1784+ from pyindicators import (
1785+ buyside_sellside_liquidity,
1786+ buyside_sellside_liquidity_signal,
1787+ get_buyside_sellside_liquidity_stats
1788+ )
1789+
1790+ # Create sample OHLC data
1791+ df = pd.DataFrame({
1792+ ' Open' : [... ],
1793+ ' High' : [... ],
1794+ ' Low' : [... ],
1795+ ' Close' : [... ]
1796+ })
1797+
1798+ # Detect buyside and sellside liquidity levels
1799+ df = buyside_sellside_liquidity(df, detection_length = 7 , detect_voids = True )
1800+ print (df[[' buyside_liq_level' , ' sellside_liq_level' , ' buyside_liq_broken' , ' sellside_liq_broken' ]])
1801+
1802+ # Generate trading signals
1803+ # 1 = sellside breached (may reverse up), -1 = buyside breached (may reverse down)
1804+ df = buyside_sellside_liquidity_signal(df)
1805+ breach_events = df[df[' bsl_signal' ] != 0 ]
1806+
1807+ # Get statistics
1808+ stats = get_buyside_sellside_liquidity_stats(df)
1809+ print (f " Buyside levels: { stats[' total_buyside_levels' ]} " )
1810+ print (f " Sellside levels: { stats[' total_sellside_levels' ]} " )
1811+ print (f " Total breaches: { stats[' total_breaches' ]} " )
1812+ ```
1813+
1814+ The function returns:
1815+ - ` buyside_liq_level ` / ` sellside_liq_level ` : Price of the liquidity level
1816+ - ` buyside_liq_top ` / ` buyside_liq_bottom ` : Upper and lower bounds of the buyside zone
1817+ - ` sellside_liq_top ` / ` sellside_liq_bottom ` : Upper and lower bounds of the sellside zone
1818+ - ` buyside_liq_broken ` / ` sellside_liq_broken ` : 1 when the level is breached
1819+ - ` liq_void_bullish ` / ` liq_void_bearish ` : 1 when a liquidity void is detected (if ` detect_voids=True ` )
1820+ - ` liq_void_top ` / ` liq_void_bottom ` : Bounds of the void zone
1821+
1822+ ** Trading Strategy:**
1823+ - Buyside levels act as resistance; a breach signals institutional selling (potential reversal down)
1824+ - Sellside levels act as support; a breach signals institutional buying (potential reversal up)
1825+ - Liquidity voids are imbalance zones that price often revisits—use as take-profit targets
1826+
1827+ ![ BUYSIDE_SELLSIDE_LIQUIDITY] ( https://github.com/coding-kitties/PyIndicators/blob/main/static/images/indicators/buy_side_sell_side_liquidity.png )
1828+
16811829### Pattern Recognition
16821830
16831831#### Detect Peaks
0 commit comments