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.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。