smc-python-library — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited smc-python-library (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
USE FOR:
tags: [SMC, ICT, Python, FVG, order-blocks, BOS, CHoCH, liquidity, swing-highs-lows, kill-zones] kind: library category: ict-smart-money
Python library implementing all core ICT/SMC indicators on OHLC DataFrames.
pip install smartmoneyconcepts["open", "high", "low", "close", "volume"]pip install smartmoneyconceptsfrom smartmoneyconcepts import smc
import pandas as pdfvg = smc.fvg(ohlc, join_consecutive=False)Returns per row:
FVG: 1 (bullish gap) · -1 (bearish gap) · NaN (no gap)Top: upper boundary of the gapBottom: lower boundary of the gapMitigatedIndex: candle index that closed/filled the gapConcept:
Bullish FVG: candle[i-1].high < candle[i+1].low → gap above
Bearish FVG: candle[i-1].low > candle[i+1].high → gap belowParameters:
join_consecutive=True: merges adjacent FVGs → single zone (highest top, lowest bottom)swings = smc.swing_highs_lows(ohlc, swing_length=50)Returns:
HighLow: 1 (swing high) · -1 (swing low) · NaNLevel: price of the swing pointConcept:
Swing High: highest high within swing_length candles before AND after
Swing Low: lowest low within swing_length candles before AND after# Requires swing_highs_lows output first
swings = smc.swing_highs_lows(ohlc, swing_length=50)
structure = smc.bos_choch(ohlc, swings, close_break=True)Returns:
BOS: 1 (bullish BOS) · -1 (bearish BOS)CHOCH: 1 (bullish CHoCH) · -1 (bearish CHoCH)Level: price level that was brokenBrokenIndex: candle that broke the level`close_break` parameter:
True → break confirmed only when candle CLOSES beyond level
False → break on wick touch (high/low crosses level)BOS vs CHoCH:
BOS → continuation: structure break in direction of trend
CHoCH → reversal: structure break AGAINST current trend directionswings = smc.swing_highs_lows(ohlc, swing_length=50)
ob = smc.ob(ohlc, swings, close_mitigation=False)Returns:
OB: 1 (bullish OB) · -1 (bearish OB)Top: upper boundaryBottom: lower boundaryOBVolume: sum of current + 2 previous candle volumesPercentage: strength = min(highVol, lowVol) / max(highVol, lowVol)Strength interpretation:
Percentage → 1.0 (100%) = equal bull/bear volume = strongest OB
Percentage → 0.1 (10%) = highly imbalanced = weaker OBswings = smc.swing_highs_lows(ohlc, swing_length=50)
liq = smc.liquidity(ohlc, swings, range_percent=0.01)Returns:
Liquidity: 1 (buy-side) · -1 (sell-side)Level: price of liquidity clusterEnd: index of last swing in the clusterSwept: index of candle that swept the liquidityConcept:
Multiple swing highs within range_percent (1%) of each other
→ clustered stops/liquidity pool above = buy-side liquidity
→ price will likely sweep these before reversingprev_hl = smc.previous_high_low(ohlc, time_frame="1D")Returns:
PreviousHigh · PreviousLowBrokenHigh: 1 when price breaks prior period highBrokenLow: 1 when price breaks prior period lowSupported timeframes: "15m" · "1H" · "4H" · "1D" · "1W" · "1M"
session = smc.sessions(ohlc, session="London open kill zone",
start_time=None, end_time=None, time_zone="UTC")Built-in sessions:
"Sydney" "Tokyo"
"London" "New York"
"Asian kill zone" "London open kill zone"
"New York kill zone" "london close kill zone"
"Custom" → requires start_time + end_time "HH:MM"Returns:
Active: 1 if candle is within session · 0 if notHigh: session high so farLow: session low so farswings = smc.swing_highs_lows(ohlc, swing_length=50)
ret = smc.retracements(ohlc, swings)Returns:
Direction: 1 (bullish move) · -1 (bearish move)CurrentRetracement%: current retracement from last swingDeepestRetracement%: max retracement seen in this movefrom smartmoneyconcepts import smc
import pandas as pd
# Load OHLCV data (lowercase columns required)
df = pd.read_csv("EURUSD_H1.csv")
df.columns = ["open", "high", "low", "close", "volume"]
# Step 1: Swing structure (prerequisite for most indicators)
swings = smc.swing_highs_lows(df, swing_length=20)
# Step 2: Market structure
structure = smc.bos_choch(df, swings, close_break=True)
# Step 3: Order blocks
ob = smc.ob(df, swings, close_mitigation=False)
# Step 4: Fair value gaps
fvg = smc.fvg(df, join_consecutive=True)
# Step 5: Liquidity pools
liq = smc.liquidity(df, swings, range_percent=0.005)
# Step 6: Session filter (only trade London open kill zone)
session = smc.sessions(df, session="London open kill zone")
# Step 7: Previous day high/low
prev_hl = smc.previous_high_low(df, time_frame="1D")
# Combine: find bullish OBs that are active during London kill zone
bullish_ob = ob[ob["OB"] == 1]
london_active = session[session["Active"] == 1]
confluence = bullish_ob.index.intersection(london_active.index)
print(f"Bullish OBs during London KZ: {len(confluence)}")def find_confluences(df, swing_length=20):
swings = smc.swing_highs_lows(df, swing_length)
bos = smc.bos_choch(df, swings, close_break=True)
ob = smc.ob(df, swings)
fvg = smc.fvg(df)
liq = smc.liquidity(df, swings, range_percent=0.005)
signals = []
for i in df.index:
bullish = (
ob.loc[i, "OB"] == 1 if i in ob.index else False, # Bullish OB
fvg.loc[i, "FVG"] == 1 if i in fvg.index else False, # Bullish FVG
bos.loc[i, "BOS"] == 1 if i in bos.index else False, # BOS up
)
if all(bullish):
signals.append({"index": i, "type": "LONG", "level": ob.loc[i, "Bottom"]})
return pd.DataFrame(signals)~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.