Deterministic ICT (Inner Circle Trader) market annotation — killzones with DST handled correctly, a liquidity map, and higher-timeframe structure — computed in exact, reproducible Python. Built for humans, scripts, and AI agents that need timezone/session math and resting-liquidity levels done right, without asking a language model to eyeball a chart or do date arithmetic (a classic silent-bug spot).
This is analysis tooling, not a trading signal. It annotates data; it never recommends a trade. "ICT" refers to the published Inner Circle Trader methodology (after Michael J. Huddleston) as documented — this project has no affiliation with him or any broker.
- Time — New York session, active killzone(s), macro window, silver- bullet hour, and the ICT "true day" open, for any bar — DST-correct without needing a system tzdata install.
- Liquidity — previous day/week high-low, session ranges, equal highs/lows, untouched (unswept) old swing extremes, and the latest day/week opening gaps.
- HTF structure — per higher timeframe: labeled swing sequence (HH/HL/LH/LL) and where price sits in the current dealing range (premium / equilibrium / discount).
A standout feature: you don't need to know your broker's UTC offset.
infer_broker_offset derives it from the data's own weekly reopen gap (FX
markets reopen at a fixed, known instant — Sunday 17:00 New York) — a wrong
or missing configured offset silently corrupts every session/killzone tag
downstream, so this makes that failure mode close to impossible.
pip install -e .
ict-tools annotate examples/sample_packet.json{
"broker_utc_offset": 3.0,
"time": {
"ny_time": "2024-07-11 04:00",
"weekday": "Thursday",
"session": "london",
"killzones": ["killzone_london"],
"silver_bullet": null,
"macro": null,
"midnight_open": 1.088,
"true_day_open": 1.088
},
"liquidity": { "...": "..." },
"htf_ladder": { "...": "..." }
}No --offset was passed — 3.0 was inferred from the sample packet's own
weekend gap. See docs/output-schema.md for every
field, and examples/sample_packet.json for
a full worked input.
ict-tools annotate <packet.json|-> [--offset H] [--text] [--indent N]
ict-tools offset <packet.json|-> # resolved offset + its source
ict-tools windows --time "2024-07-11 08:30" [--offset H] # no bars needed
ict-tools gate <packet.json|-> --seed SEED [--passthrough FRAC] [--offset H]gate decides whether to act on a bar based on killzone membership alone —
useful when whatever comes next (an LLM call, an order, an alert) is
expensive and you want to skip clearly off-killzone bars while still
sampling a small, deterministic fraction of them so a regression in
off-killzone behavior doesn't go unnoticed:
$ ict-tools gate examples/sample_packet.json --seed "EURUSD:1h:2024-07-11 04:00"
{
"in_killzone": true,
"should_skip": false,
"passthrough_fired": false
}<packet.json> can be a full packet ({"frames": {...}, ...}), a bare
{tf: [bars]} dict, or a bare list of bars — all three are normalized
automatically (order-detected and re-aliased as needed). Use - to read
from stdin.
from ict_tools import build_ict_block
block = build_ict_block(packet) # offset resolved automatically
block = build_ict_block(packet, 3.0) # or force it explicitlySKILL.md packages this as an ICT-analyst skill for Claude
Code / Hermes-style agents: when to reach for the tool, how to source bars,
the ICT interpretive method (the decision hierarchy the tool's output feeds
into), and the field glossary. scripts/setup.sh bootstraps the venv.
ICT_BROKER_UTC_OFFSET (hours). TLC_BROKER_UTC_OFFSET is also accepted as
a fallback, for anyone migrating from a TLC-based setup.
pip install -e ".[dev]"
pytestNo runtime dependencies. Python 3.9+.
MIT — see LICENSE.