SMC and summaries
Smart Money Concepts (SMC) is a price-action framework that labels zones, levels and structural breaks from OHLC patterns. wickworks reports what the configured algorithms detected in the bars you sent. It does not see orders, and it does not predict whether price will react to a level.
Most of these outputs come from the smartmoneyconcepts library 0.0.26. wickworks runs a numba port of its order block, FVG, BOS/CHoCH and swing functions (smc_fast.py) that the test suite proves gives the same results as the library. Support and resistance levels, touch counts and the summaries are wickworks’ own code.
Every output on this page needs at least MIN_BARS bars (default 50; see configuration). For how to request them, see the indicators object.
Terms
- Order block: the zone of the last opposite-direction candle before a qualifying move, as the algorithm detects it.
- Fair value gap (FVG): a three-bar pattern where the first and third bars’ wicks do not overlap, leaving a gap.
- Mitigation: a later return of price into a zone.
- Swing high or low: a local pivot. SMC reads trend from the sequence of swings: higher highs and higher lows up, lower highs and lower lows down.
- BOS (break of structure): a break of a swing level in the direction of the current structure.
- CHoCH (change of character): a break of a swing level against the current structure. It is not proof of a reversal.
- Liquidity: in SMC terms, clusters of equal highs or equal lows, where stop orders are assumed to sit.
The shared analysis pass
orderBlocks, fvg, bosChoch, swingLevels, srLevels, recentRange and all six summaries read from one analysis of the whole history. wickworks runs it at most once per request, the first time an output needs it. Asking for all of them costs about the same as asking for one.
liquidity, previousHighLow, sessions and retracements are computed separately and take parameters.
Time fields
Structural objects carry three timestamps, all UTC unix seconds, so you can tell where a pattern formed from when it became knowable:
| Field | Meaning |
|---|---|
originAt | Time of the bar where the pattern formed (the same value as time) |
confirmedAt | Time of the first bar at which the pattern was knowable. null when that bar is past the end of your data |
observedAsOf | Time of the last bar you sent, the moment the snapshot describes |
A backtest that only uses objects with confirmedAt at or before its current bar avoids lookahead.
orderBlocks
Every order block found in the submitted history, mitigated or not, with the state you need to apply your own freshness rule. No parameters.
{
"type": "bearish",
"top": 1.1762299999999999,
"bottom": 1.17388,
"candleIdx": 136,
"time": 1776834000,
"originAt": 1776834000,
"confirmedAt": 1776866400,
"observedAsOf": 1777593600,
"mitigatedWickAt": null,
"mitigatedCloseAt": null,
"distancePct": 0.097,
"mitigatedWick": false,
"mitigatedClose": false,
"touchCount": 3,
"touchEvents": [1, 8, 74, 157]
}
| Field | Type | Description |
|---|---|---|
type | "bullish" or "bearish" | Zone direction. Bullish zones sit below price as support, bearish ones above as resistance |
top, bottom | number | Zone boundaries |
candleIdx | integer | Zero-based index of the origin bar in your bars |
time, originAt, confirmedAt, observedAsOf | integer | See time fields |
mitigatedWick | boolean | A later bar’s wick went through the zone in the invalidating direction |
mitigatedWickAt | integer or null | Time of that bar |
mitigatedClose | boolean | A later bar closed through the zone in the invalidating direction |
mitigatedCloseAt | integer or null | Time of that bar |
touchEvents | array of integers | Each entry is the offset in bars from the origin bar where price entered the zone again after leaving it. [1, 8] means the next bar touched the zone, price left, and a new touch started 8 bars after the origin |
touchCount | integer | Entries in touchEvents with an offset above 5. The first five bars after the origin are the move that created the block, so wickworks does not count them as tests |
distancePct | number | Signed distance from price to the near edge, in percent of the last close: (close - top) / close × 100 for bullish blocks, (bottom - close) / close × 100 for bearish ones. Negative when price is already past that edge |
Returns at most 40 blocks, sorted by absolute distancePct, nearest first.
fvg
Fair value gaps that price has not yet filled. Also accepted as fvgs. No parameters.
| Field | Type | Description |
|---|---|---|
type | "bullish" or "bearish" | Gap direction |
top, bottom | number | Gap boundaries |
candleIdx | integer | Zero-based index of the bar the gap is attributed to |
time, originAt, confirmedAt, observedAsOf | integer | See time fields. confirmedAt is one bar after the origin |
distancePct | number | Absolute distance from the last close to the middle of the gap, in percent of the close |
Returns at most 15 gaps, nearest first. Mitigated gaps are dropped, so the mitigation fields order blocks carry do not appear here.
bosChoch
Breaks of structure and changes of character found in the last 50 bars. No parameters.
{
"event": "BOS",
"direction": "bullish",
"level": 1.0918,
"time": 1700125200,
"originAt": 1700125200,
"confirmedAt": 1700132400,
"observedAsOf": 1700200000
}
event is "BOS" or "CHoCH", direction is "bullish" or "bearish", level is the broken swing level (number or null). confirmedAt is the time of the bar that broke the level. Returns the 10 most recent events, oldest first.
swingLevels
Swing highs and lows from the structural pass in the last 50 bars, the raw input SMC builds its trend on. Useful for drawing structure or writing your own break detection. No parameters.
{
"type": "high",
"level": 1.17203,
"time": 1777420800,
"originAt": 1777420800,
"confirmedAt": 1777474800,
"observedAsOf": 1777593600
}
type is "high" or "low". wickworks treats a swing as confirmed 15 bars after its pivot, so confirmedAt is the time of the bar 15 bars after originAt, or null when that bar is past the end of your data. Returns the 10 most recent, oldest first.
srLevels
wickworks’ own support and resistance levels. No parameters.
- Take at most the latest 500 bars.
- Take pivots from a 7-bar swing detector.
- Keep a swing high above the last close as resistance, or a swing low below it as support, when bars came within half an ATR (14) of it at least twice, counting touches more than five bars apart.
- Space kept levels at least three ATR apart.
- Return up to three levels below price and three above, nearest first.
{
"level": 1.17547,
"type": "resistance",
"distancePct": 0.233,
"touches": 8
}
type is "support" or "resistance", touches is the touch count (at least 2), and distancePct is the distance from the last close in percent. Returns an empty array with fewer than 50 bars or when ATR is zero.
recentRange
The high and low of the last 20 bars next to the high and low of everything you sent. No parameters.
{
"high": 1.17415,
"low": 1.16576,
"periodHigh": 1.18489,
"periodLow": 1.16548
}
liquidity
Clusters of equal highs or equal lows among swing points, grouped when they lie within rangePercent of each other.
| Parameter | Type | Default | Description |
|---|---|---|---|
swingLength (swing_length) | integer | 10 | Swing detection window |
rangePercent (range_percent) | number | 0.01 | Largest distance, as a fraction, for grouping levels. At most 1 |
Returns an array of SMC events, one per cluster, with the library’s fields Liquidity (1 for highs, -1 for lows), Level, End (bar index of the last level in the cluster) and Swept (bar index of the candle that took it out).
previousHighLow
The high and low of the previous completed period, on every bar.
| Parameter | Type | Default | Description |
|---|---|---|---|
timeFrame (time_frame) | string | "1D" | The period length: 15m, 30m, 1H, 4H, 1D, 1W or 1M. The spellings 15min, 30min, 1h, 4h, 1d, 1w and 1ME also work |
Periods are fixed UTC buckets, not exchange sessions. Weeks run Monday to Sunday. Despite the name, timeFrame has nothing to do with the request’s top-level timeframe label.
Returns an array of SMC events, one per bar from the second period on, with PreviousHigh, PreviousLow, and BrokenHigh / BrokenLow, which become 1 once a bar in the current period has gone above the previous high or below the previous low.
sessions
Marks which bars fall inside a fixed UTC clock window.
| Parameter | Type | Default | Description |
|---|---|---|---|
session | string | "London" | A named window from the table below, or "Custom" |
startTime (start_time) | "HH:MM" | none | UTC start. Required for "Custom", rejected for named windows |
endTime (end_time) | "HH:MM" | none | UTC end. Required for "Custom", rejected for named windows |
session | UTC window |
|---|---|
Sydney | 21:00 to 06:00 |
Tokyo | 00:00 to 09:00 |
London | 07:00 to 16:00 |
New York | 13:00 to 22:00 |
Asian kill zone | 00:00 to 04:00 |
London open kill zone | 06:00 to 09:00 |
New York kill zone | 11:00 to 14:00 |
london close kill zone | 14:00 to 16:00 |
The names are case sensitive, including the lowercase london close kill zone. The windows never move for holidays or daylight saving time.
Returns an array of SMC events, one per bar, with Active (1 inside the window, 0 outside) and the session’s running High and Low.
retracements
How far price has pulled back from the most recent swing.
| Parameter | Type | Default | Description |
|---|---|---|---|
swingLength (swing_length) | integer | 10 | Swing detection window |
Returns an array of SMC events, one per bar, with Direction (1 bullish, -1 bearish, 0 before the first swing), CurrentRetracement% and DeepestRetracement%. These are percentages of the swing leg. wickworks does not compute Fibonacci levels; compare the percentages with 38.2, 50 or 61.8 yourself if you want them.
SMC events
liquidity, previousHighLow, sessions and retracements return arrays of flat objects. Each has idx (zero-based bar index) and time, plus the library’s columns for that output, named as the library names them (so CurrentRetracement%, not camelCase). Fields that are null for a bar are left out of that object. Numbers are rounded to six decimal places, and flags such as Active come out as 1.0 and 0.0.
Analysis summaries
Six outputs that describe the last bar, read from the shared analysis pass. Use them for a one-call “where are we now” view instead of requesting full series and reading the last value. None takes parameters. Numbers are rounded to six decimal places, except price.
| Output | Returns |
|---|---|
price | The last close, a plain number |
levels | { ema21, sma50, sma100, sma200, atr, vwap, donchianUpper, donchianLower, donchianMid }, each a number or null |
momentum | { rsi, mfi, macdHist, macdLine, macdSignal, adx, stochK, stochD }, each a number or null |
volume | { volRatio, obv, isSpike }. volRatio is the last bar’s volume divided by its moving average (number or null), isSpike is true when volRatio is above 2 |
position | Whether the last close is "above" or "below" each of ema21, sma50, sma100, sma200 and vwap. A key is missing when that line has no value yet |
slope | Whether each of the same lines is "up" or "down" compared with 10 bars earlier. A key is missing when the line has no value at either end or did not change |
The lines behind the summaries use fixed settings: EMA 21, SMA 50, 100 and 200, ATR 14, a daily UTC-anchored VWAP, Donchian 20, RSI 14, MFI 14, MACD 12/26/9, ADX 14 and Stochastic 14/3/3. Run the matching indicator with your own parameters if you need different ones.
The moving average under volRatio picks its length from the median spacing of your bar times: 200 bars for 1-minute bars, 100 for 5-minute, 60 for 15-minute, 50 for 30-minute, hourly and 4-hour, 200 for daily, 52 for weekly, aiming at about two weeks of history.
sma200 and its position and slope entries stay null or missing until you send at least 200 bars.
Example with 300 hourly bars:
{
"price": 1.1727400000000001,
"levels": {
"ema21": 1.171421,
"sma50": 1.16987,
"sma100": 1.170796,
"sma200": 1.171686,
"atr": 0.001253,
"vwap": 1.1727,
"donchianUpper": 1.17415,
"donchianLower": 1.16576,
"donchianMid": 1.169955
},
"momentum": {
"rsi": 60.91879,
"mfi": 51.890517,
"macdHist": 0.000153,
"macdLine": 0.00116,
"macdSignal": 0.001006,
"adx": 28.226202,
"stochK": 79.810212,
"stochD": 81.760339
},
"volume": {
"volRatio": 0.725984,
"obv": -157406.0,
"isSpike": false
},
"position": {
"ema21": "above",
"sma50": "above",
"sma100": "above",
"sma200": "above",
"vwap": "above"
},
"slope": {
"ema21": "up",
"sma50": "up",
"sma100": "up",
"sma200": "down",
"vwap": "up"
}
}