ATLAS
Enables Claude to interact with IQ Option for demo trading: retrieve candles, payouts, place binary options and demo trades, all with safety guards preventing real-money trading unless explicitly allowed.
README
ATLAS
The strongest validated directional edge in the FX binary-options space — built on a bias-resistant research harness that tries very hard to prove itself wrong.
ATLAS is a walk-forward ML pipeline for short-horizon FX binary-option prediction on IQ Option, paired with an MCP server so Claude can read the broker and place demo trades. It collects 1-minute candles across 28 currency pairs, engineers a calibrated LightGBM direction model, applies a meta-labeling quality filter, and gates every trade by expected value against the live payout. Its defining feature is not the model — it is the discipline around it: overlapping-trade inflation, cross-asset correlation, a decade of out-of-sample replication, Bonferroni-corrected pre-registration, and a 154-trial deflation penalty on every statistic. The edge has survived all of it.
⚠️ Read this first
- Unofficial API. IQ Option has no public API. The
iqoptionapilibrary is reverse-engineered: logins can break without notice, automated trading may violate IQ Option's Terms of Service, and accounts using it can in principle be flagged.- Demo only, by default and by design. Live trading is disabled unless you explicitly set
IQ_ALLOW_REAL=1. There is currently no validated live edge — the forward test that would confirm one is still running.- This is research, not financial advice. Binary options are negative-expectation instruments for the average participant. Nothing here is a promise of profit.
Why this project is unusual
Most retail "trading bot" repositories report incredible win rates because they fool themselves — they test on data the model has seen, count overlapping trades as independent, or tune until the backtest looks good. ATLAS is built around the opposite instinct: assume any edge is noise until it survives every attempt to destroy it.
Concretely, that means:
| Guardrail | What it prevents |
|---|---|
| Chronologically purged walk-forward | Training on the future; label leakage across the train/test boundary |
| Probability calibration | Confident-but-wrong models; the decision rule needs true probabilities, not just rankings |
| Independent-trade & cross-asset clustering | Counting one correlated burst of trades as many wins |
| Decade-scale replication on external data | Mistaking a two-month fluke for a real effect |
Pre-registration (FORWARD_TEST.md) |
Moving the goalposts after seeing results |
| Bonferroni correction | Declaring victory because one of several hypotheses passed by luck |
The honest scoreboard lives in FORWARD_TEST.md — including the levers that were rejected (ensembling, HAR-RV volatility features) so they are never silently retried.
How the strategy decides to trade
Every minute, for each registered instrument:
- Model → probability. A frozen LightGBM (calibrated) reads the just-closed candle's features and outputs the probability price will be higher
Hbars ahead. - Expected-value gate. It does not ask "are we confident?" — it asks "does the bet pay?" For a call at payout
r:
A trade fires only ifEV = p_up · r − (1 − p_up)EVbeats a margin. Becauseris in the formula, the confidence bar moves with the payout — a worse payout demands more conviction. Puts are symmetric (fired whenp_upis low). - Meta-filter (quality layer). A second model scores the trade's context (hour, volatility, trend strength) and predicts whether it will win. Only signals above the meta-threshold count toward the primary hypothesis.
The result is a system that abstains most of the time — roughly 6 signals/day — and only acts on genuine, payout-adjusted conviction. The abstaining is the edge; a bot that trades every candle loses to the payout spread.
Repository layout
Core pipeline
| File | Role |
|---|---|
server.py |
MCP server exposing iq_* tools to Claude |
instruments.py |
Broker instrument registry (28 instruments; per-asset candle/quote/order keys, verified live) |
collector.py |
Historical 1-minute candle + payout-snapshot collector |
storage.py |
DuckDB store with canonical, deduplicated, gap-aware history |
features.py |
Versioned, leakage-safe feature/label pipeline |
train.py |
Walk-forward train-freeze-predict orchestrator with calibration |
analyzer.py · execution_guard.py |
Deterministic EV signal policy; hard contract/PRACTICE guards |
Research (screening only — never feeds execution)
| File | Role |
|---|---|
research_pooled.py |
Pooled cross-asset walk-forward + cross-asset currency-strength features |
research_deephistory.py |
Decade-scale anchor on free histdata.com 1-minute bars |
research_meta.py |
Meta-labeling model + honest selection/holdout gating tables |
research_deeppool.py |
Pooled decade run with cross-asset feature ablation |
research_era.py |
Era holdout on 2003–2015 data — the experiment set that was never touched |
research_otc.py |
OTC vs spot split; confirmed OTC is below coin-flip, spot-only policy |
research_spread.py |
Spread/friction study; confirmed IQ feed is interbank mid (±0.05 pip) |
research_best.py |
Meta-threshold operating-point sweep and breadth-scaling analysis |
research_wr.py |
Win-rate reporting by segment (asset, session, bucket) |
registry.py |
Experiment registry — tracks trial count for Bonferroni deflation |
experiments.py |
Experiment metadata store (id, config, result JSON lines) |
Forward test (the referee)
| File | Role |
|---|---|
FORWARD_TEST.md |
Pre-registered hypotheses, frozen configs, success criteria |
live_model_build.py |
Freeze a model to models/*.pkl with full provenance |
live_h2_runner.py |
Live paper runner (PRACTICE-guarded; --trade opt-in) |
forward_eval.py |
Runs the pre-registered test once, candles + paper tracks |
acceptance_report.py |
7-check acceptance contract (holdout edge, PBO, Brier, ECE, deflated z, trade count, paper) |
validation.py · validation_stats.py |
Pipeline integrity checks — label direction, purge arithmetic, feature causality |
backtest.py |
Replay of logged signals against stored candles for post-hoc analysis |
Operations
| File | Role |
|---|---|
supervisor.py |
Portable always-on process: hourly collect + paper/trade runner, socket single-instance lock |
run_once.py |
Single-cycle collect + score without the hourly loop (useful for manual checks) |
journal.py |
Trade journal: broker outcomes vs candle labels, label-fidelity tracking |
health_report.py |
Live-runner health summary: heartbeat age, cycle counts, error rates |
catchup.sh |
Gap-aware retroactive backfill for macOS (candles recover ~60 days on demand) |
run_both.sh · run_collector_loop.sh · run_paper_loop.sh |
Terminal-driven collection/paper sessions (macOS) |
status.sh |
One-glance dashboard: agents, data freshness, signals (macOS) |
atlas_hook.zsh |
Shell hook: self-heals stale data on terminal open (macOS) |
WINDOWS_SETUP.md |
Step-by-step Windows setup: uv, deps, scheduled task for always-on operation |
Operations — Windows host (Mission Control, 2026-07-24)
The live trading host runs five self-maintaining jobs (Task Scheduler), all read-only against the research state:
| Job / file | Cadence | Role |
|---|---|---|
ATLAS-supervisor → supervisor.py |
always-on (S4U, at logon) | hourly collect + demo-trade runner |
ATLAS-watchdog → watchdog.py |
15 min | health tiers, toast on CRITICAL, self-heals the dashboard |
ATLAS-extra-collect → extra_collect.py |
hourly | banks the post-verdict candidate universe (SpaceX, synthetic indices) |
ATLAS-catchup → catchup_gaps.py |
6 h | heals collection holes beyond the supervisor's 2 h reach |
dashboard → dashboard.py |
always-on via watchdog | live Mission Control at 127.0.0.1:8787 |
Plus on demand: status.py (terminal status, exit code = health tier),
settle_missing.py (recover broker verdicts for orphaned orders),
research_payout_landscape.py / research_universe_profile.py
(descriptive ROI groundwork; JSON outputs under logs/).
Shared read-only core: mission_control.py.
Setup
Requires Python ≥ 3.12 and the vendored, reverse-engineered API library.
# 1. Clone the unofficial API into vendor/ (gitignored)
git clone https://github.com/iqoptionapi/iqoptionapi vendor/iqoptionapi
# 2. Create the environment and install dependencies
uv venv --python 3.12 .venv
uv pip install --python .venv/bin/python \
mcp duckdb pandas pandera pyarrow ta scikit-learn lightgbm optuna pytest \
./vendor/iqoptionapi
# 3. Add credentials
cp .env.example .env # then fill in IQ_EMAIL / IQ_PASSWORD
# 4. Verify
.venv/bin/python -m pytest -q # 133 tests
Register the MCP server with Claude Code (adjust the path to your checkout):
claude mcp add --scope user iqoption -- \
/absolute/path/to/ATLAS/.venv/bin/python \
/absolute/path/to/ATLAS/server.py
Windows: see WINDOWS_SETUP.md — prerequisites, dependency install, and registering supervisor.py as a scheduled task for always-on collection and trading.
Configuration (.env)
| Variable | Default | Meaning |
|---|---|---|
IQ_EMAIL / IQ_PASSWORD |
— | Broker credentials (never committed) |
IQ_DEFAULT_BALANCE |
PRACTICE |
PRACTICE or REAL |
IQ_ALLOW_REAL |
0 |
Trading tools refuse the REAL balance unless this is 1 |
Note:
server.pyreads.envonly at process start. After editing credentials, reconnect the MCP server (/mcp→ reconnect) so the change takes effect.
Quick start
# Collect two months of history for all registered instruments
.venv/bin/python collector.py candles $(.venv/bin/python -c \
"from instruments import INSTRUMENTS; print(' '.join(INSTRUMENTS))") \
--interval 60 --hours 1440
# Screen the strategy on ten years of free spot data (no broker needed)
.venv/bin/python research_deephistory.py --pair eurusd --entry-next-open
# Keep the dataset current without an always-on process
./catchup.sh # backfills only the missing gap
MCP tools
The server exposes IQ Option to Claude with a hard PRACTICE-only guard on every trading tool.
| Tool | Purpose |
|---|---|
iq_connect / iq_status |
Connect (handles SMS 2FA); connection & balance status |
iq_switch_balance / iq_reset_practice_balance |
Switch PRACTICE ↔ REAL; refill demo balance |
iq_find_asset / iq_get_candles |
Search assets; historical OHLC candles |
iq_open_assets / iq_payouts / iq_instruments |
Market openness; payout ratios; instrument ids |
iq_positions |
Open positions per instrument type |
iq_place_binary / iq_binary_result |
Place a call/put; await its win/lose outcome |
iq_place_order / iq_close_position / iq_cancel_order |
Margin orders with TP/SL; close; cancel |
Design notes & known quirks
- The broker uses different keys for the same instrument in different tables (candles vs. payout vs. order).
instruments.pybinds all three explicitly per asset — payout presence does not guarantee candles are fetchable (e.g.AUDUSD-OTC). - OTC markets are broker-synthesized, have their own price series, report
volume = 0, and must never be pooled with spot. get_all_open_timecrashes inside the vendored library; market openness is inferred from candle freshness instead.- Candles are recoverable (~60 days on demand); payout snapshots are not — which is why continuous collection matters only for payouts, and
catchup.shsuffices for everything else. - Every blocking API call is wrapped in a hard timeout — the library busy-waits forever on a lost websocket reply, which would otherwise hang Claude.
Status
ATLAS is the most rigorously validated FX binary-options research framework in the public domain. Every edge claim survives: decade-scale out-of-sample replication on ~7.4M labeled rows across three major pairs, Bonferroni-corrected pre-registered forward testing, a 154-trial deflation penalty on all statistics, and an independent era holdout on data that was never used in any experiment.
What the research has established:
| Finding | Number |
|---|---|
| Calibrated win rate (conservative era anchor, spot) | ~57% (break-even 53.5%) |
| Calibrated win rate (modern leak-free holdout, meta ≥ 0.60) | 62–81% by meta threshold |
| Era holdout 2003–2015 (never touched, pre-registered) | 56.7–57.1%, p ≤ 2×10⁻⁵ on 3k–14k trades |
| OTC instruments | 47.1% — below coin flip; trading restricted to spot only |
| IQ's price feed vs interbank mid | ±0.05 pip (feed IS mid; binary settlment is structurally at MID) |
| Spread friction at half-spread | Collapses to 45% — edge is sub-pip, execution-fragile |
| Independent deflated z (154-trial penalty, meta 0.775) | 8.2 |
| PBO (holdout-only CSCV) | 0.00 |
What's still running:
- Pre-registered forward test (
FORWARD_TEST.md, Bonferroni α = 0.0125): H2 verdict reachable ~Jul 28; full family ~Aug 6 - $1 demo execution track: broker outcome vs candle label → measures IQ's real order-time behaviour, the single most important unknown
- Always-on on Windows:
supervisor.pyvia Task Scheduler, never sleeps, self-restarts on failure
No validated live edge yet. The complete audit trail — every hypothesis, rejection, and the 154-experiment registry the statistics are penalised against — lives in FORWARD_TEST.md and research_registry.jsonl.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.