Skip to main content
Glama

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 iqoptionapi library 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:

  1. Model → probability. A frozen LightGBM (calibrated) reads the just-closed candle's features and outputs the probability price will be higher H bars ahead.

  2. Expected-value gate. It does not ask "are we confident?" — it asks "does the bet pay?" For a call at payout r:

    EV = p_up · r − (1 − p_up)

    A trade fires only if EV beats a margin. Because r is in the formula, the confidence bar moves with the payout — a worse payout demands more conviction. Puts are symmetric (fired when p_up is low).

  3. 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-supervisorsupervisor.py

always-on (S4U, at logon)

hourly collect + demo-trade runner

ATLAS-watchdogwatchdog.py

15 min

health tiers, toast on CRITICAL, self-heals the dashboard

ATLAS-extra-collectextra_collect.py

hourly

banks the post-verdict candidate universe (SpaceX, synthetic indices)

ATLAS-catchupcatchup_gaps.py

6 h

heals collection holes beyond the supervisor's 2 h reach

ATLAS-backupbackup_state.py

6 h

offsite copy of the irreplaceable forward evidence

dashboard → dashboard.py

always-on via watchdog

live Mission Control at 127.0.0.1:8787

On demand:

Tool

Use

selfcheck.py

whole-host audit: tasks, disk, safety switches, model provenance, DB, backup, git, tests. Exit 0/1/2 — run before leaving the host unattended

status.py

live trader status; exit code is the health tier

probe_order_record.py

dumps a settled order's RAW broker record and flags price-like fields — the fast path to the label-fidelity answer if IQ exposes its strike

settle_missing.py

recovers broker verdicts for orders orphaned by a mid-flight crash

research_payout_landscape.py

payout stats per (asset, kind) × UTC hour → logs/payout_landscape.json

research_universe_profile.py

structure profile of candidate instruments → logs/universe_profile.json

Shared read-only core: mission_control.py.

Broker API caveat (probed live 2026-07-25). Several vendored history calls do not work on this account and must not be used: get_optioninfo_v2, get_position_history (v1) and get_positions all time out (they busy-wait for a websocket reply that never arrives). check_win_v4 only settles orders bought in the SAME process. What does respond: get_position_history_v2(instrument_type, limit, offset, start, end) and get_optioninfo(limit) — note the v1 payload nests under msg.result.closed_options, one level deeper than v2.


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.py reads .env only 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.py binds 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_time crashes 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.sh suffices 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.py via 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.

-
license - not tested
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Noctilucenty/ATLAS'

If you have feedback or need assistance with the MCP directory API, please join our Discord server