Production-grade IG Markets streaming client for building 3-minute OHLC candles on the Dow Jones Index (IX.D.DOW.IFS.IP).
- Streams real-time 1-minute OHLC data via IG's Lightstreamer API
- Aggregates into 3-minute candles
- Keltner Channel calculator with incremental (real-time) updates
- Live runner that streams candles + computes KC on the fly
- Experiment tracking — all runs are automatically grouped by config hash
- Charts and logs are routed to per-experiment folders for clean A/B testing
- Market distance analysis — automatically records how far the market price was from the planned entry at signal time
- Rejection diagnostics — captures IG rejection reasons (e.g. "Order level too close to market level") for every failed attempt
- Interactive charts show execution status, entry distance, planned TP, and IG rejection messages on hover
JuneKCTrading/
├── src/
│ ├── ig_dow_candle_stream.py # Main production streamer
│ ├── keltner.py # Keltner Channel calculator (EMA + Wilder ATR)
│ └── signal_detector.py # Signal detection logic (entry/stop rules)
├── scripts/
│ ├── plot_kc.py # Visualization tool with order execution status + rejection analysis
│ ├── audit_ig_orders_v2.py # Audit working-order attempts against IG history/activity
│ └── diagnose_tp_placement.py # Diagnostic for wrong-side TP detection
├── run_kc_live.py # Live runner: streams candles + computes KC in real time
├── config.py # ExperimentConfig — single source of truth for parameters
├── docs/
│ └── HOW_TO_PUSH_TO_GITHUB.md
├── logs/
│ └── experiments/ # Per-experiment output (see below)
├── results/
│ └── experiments/ # Per-experiment charts (see below)
├── .env.example
├── .gitignore
└── README.md
pip install trading-ig python-dotenv lightstreamer-clientPhase 1 introduced a multi-account credential system. Instead of a single .env file, you now use per-account files:
account1.env.demo # Account 1 – Demo
account1.env.live # Account 1 – Live
account2.env.demo # Account 2 – Demo
account2.env.live # Account 2 – Live
Location: Place these files either in the project root or in an accounts/ folder.
Example file content (account1.env.demo):
IG_USERNAME=your_demo_username
IG_PASSWORD=your_password
IG_API_KEY=your_demo_api_key
IG_ACC_TYPE=DEMOBoth price streaming and order execution now use the same accountX.env.* files.
The legacy single .env file is only used as a fallback if the account file cannot be found.
Key config.py settings (order execution):
account_name="account1" # Which account files to use
paper_trading=True # True = demo, False = live
size=1.0 # £ per point
min_risk_reward=1.5 # Minimum RR to place orderThis runs the streamer + Keltner Channel calculator together:
cd C:\Users\alexy\.openclaw\workspace\JuneKCTrading
py run_kc_live.pyIt will:
- Stream 3-minute Dow candles from IG in real time
- Compute Keltner Channels using parameters from
config.py - Automatically create an experiment folder:
logs/experiments/<config_id>/ - Write
experiment_config.json,kc_stream.log, and weekly JSONL inside it - Auto-reconnect if the Lightstreamer connection drops
Each run is tagged with a deterministic config_id (short hash of all parameters). Changing any setting (period, multiplier, offsets, etc.) produces a new folder so experiments stay cleanly separated.
cd C:\Users\alexy\.openclaw\workspace\JuneKCTrading
py src\ig_dow_candle_stream.pyNote (Tier 1 execution tracking): After pulling the latest code, restart the runner once. From that moment onward, every signal will include an execution object in the JSONL (containing deal_id, deal_reference, status, rr, and reason). The plotter (plot_kc.py) reads this field directly for accurate color-coded markers.
After running the live KC runner, you can visualize the Keltner Channel + candlesticks.
cd C:\Users\alexy\.openclaw\workspace\JuneKCTrading
py scripts/plot_kc.py # latest kc_*.jsonl, interactive HTML
py scripts/plot_kc.py logs/kc_2026-W28.jsonl
py scripts/plot_kc.py --export png # also save static PNG
# Filter to a specific US trading day (ET timezone)
py scripts/plot_kc.py --date 2026-07-08 # US trading session only (09:30–16:00 ET)
py scripts/plot_kc.py --date 2026-07-08 --full-day # Full US Eastern calendar day (00:00–23:59 ET)The --date filter uses US Eastern Time (ET):
--date 2026-07-08→ only the regular trading session (09:30–16:00 ET)--date 2026-07-08 --full-day→ the entire calendar day in New York time (00:00–23:59 ET / EDT)
Both modes correctly convert the requested window from Eastern Time to UTC when filtering the log files. Output filenames are automatically suffixed with the date (e.g. kc_2026-W28_2026-07-08.html).
Experiment-aware chart routing:
- If the log file lives under
logs/experiments/<config_id>/(or contains aconfig_idfield), charts are automatically saved toresults/experiments/<config_id>/. - Old logs without experiment metadata fall back to the top-level
results/folder. - This keeps every experiment's HTML/PNG outputs cleanly isolated.
Install the required packages once:
pip install pandas plotly kaleidoGenerated plots are saved to results/experiments/<config_id>/ when an experiment is detected (gitignored).
plot_kc.py automatically renders detected trading signals:
- ▼ black — SHORT signal (placed 8 points above the candle high)
- ▲ black — LONG signal (placed 8 points below the candle low)
Hover over any marker to see:
- Signal direction
- Entry price
- Stop-loss price
- Signal ID
If a log file contains no signals, the chart renders normally with no markers. This makes it easy to visually validate signal logic against the Keltner Channel bands and candle action.
Important: The OHLC candles are built using Offer (Ask) prices as primary, with Bid as fallback when Offer is unavailable.
All runs are now automatically grouped by a deterministic config_id (8-character hash of the full parameter set).
config.pydefines a singleExperimentConfigdataclass (period, multiplier, offsets, bar size, version, etc.).- On every start,
run_kc_live.pycallsCONFIG.ensure_dirs()which creates:logs/experiments/<config_id>/results/experiments/<config_id>/
- Inside the experiment folder you will find:
experiment_config.json— exact parameter snapshot for reproducibilitykc_stream.log— full console + error output for this runkc_2026-Wxx.jsonl— the actual 3-minute bars + KC values + any detected signals
- When you run
scripts/plot_kc.pyon a log inside an experiment folder, charts are written to the matchingresults/experiments/<config_id>/folder.
This design makes A/B testing trivial: change any parameter in config.py, restart the runner, and everything lands in a brand-new folder.
Fallback behavior: Logs that pre-date the experiment system (or lack a config_id) are routed to the top-level logs/ and results/ folders.
Each line is a complete 3-minute candle:
{
"timestamp_utc": "2026-07-01T17:12:00+00:00",
"open": 52151.4,
"high": 52182.3,
"low": 52151.4,
"close": 52174.6,
"resolution": "3min",
"epic": "IX.D.DOW.IFS.IP"
}Logs rotate daily. Old log files are safe to archive or delete.
- Python 3.9+
- Valid IG Markets account with API access
trading-ig+ Lightstreamer client libraries
- Never commit
.envor any file containing credentials - Use fine-grained GitHub Personal Access Tokens when pushing
- The
.gitignoreis configured to exclude secrets and logs
Internal use for JuneKCTrading project.
Last updated: 2026-07-09