Skip to main content

iqair

An unofficial Python wrapper for IQ Option's websocket trading API.

This is v1.0 - a ground-up rebuild of an older, long-unmaintained iqoptionapi fork. Every endpoint listed as "implemented" below has been independently re-verified against the live backend (never assumed from old code or documentation), typically by capturing real trade traffic from IQ Option's own web UI (HAR capture) and matching this library's requests against it byte-for-byte. Where something is confirmed vs. presumed, the docstring on the relevant method says so explicitly - see iqair/broker.py's module docstring for the full picture.

This talks to a real trading account. Every example below and every test in tests/ runs against the PRACTICE balance only - never REAL. Use your own judgment before pointing this at anything else.

Install

pip install -e .

Requires Python 3 and requests, websocket-client (see setup.py).

Quickstart

from iqair.client import IQOptionClient

api = IQOptionClient("you@example.com", "your-password")
check, reason = api.connect()
if not check:
    raise SystemExit(f"connect failed: {reason}")

api.change_balance("PRACTICE")

# Low-level: place a turbo option directly
check, order_id = api.buy(1, "EURUSD", "call", 1)  # $1, 1-minute turbo

The OOP wrapper (api.broker)

For most use cases, api.broker is friendlier than the low-level per-mode methods - one trade()/.close() interface across every mode:

from iqair.broker import TradeMode, TradeSide

trade = api.broker.trade(
    mode=TradeMode.TURBO,
    asset="EURUSD",
    side=TradeSide.CALL,
    amount=1,
    expiration=1,
)
trade.wait()          # blocks until the trade settles
print(trade.pnl)

# Margin modes (forex/crypto/cfd) need `leverage`; `amount` is margin,
# not stake, for these:
trade = api.broker.trade(
    mode=TradeMode.FOREX,
    asset="EURUSD",
    side=TradeSide.BUY,
    amount=10,       # margin, in dollars
    leverage=100,
)
print(trade.state, trade.pnl)
trade.close()

For the full end-to-end guide (every mode, streaming, positions/P&L, error handling), see docs/USAGE.md. For finding valid ticker strings specifically, see docs/TICKERS.md - the short version is api.get_asset_metadata().

Using this with an LLM orchestrator / agent

iqair.agent wraps the library as flat JSON-in/JSON-out tools for LLM function-calling (direct import, a generic call_tool(name, args) dispatcher, or an optional HTTP server via pip install iqair[agent]). See docs/AGENT.md.

Supported trading modes

Mode Open Close Notes
Turbo / Binary ✅ live-verified ✅ live-verified api.buy() / api.sell_option()
Digital options ✅ live-verified ✅ live-verified api.buy_digital_spot() / api.close_digital_option() - resolves a real, currently-tradable instrument server-side rather than constructing one client-side
Forex (margin) ✅ live-verified ✅ live-verified api.buy_forex_market() / api.close_margin_position()
Crypto (margin) ✅ live-verified ✅ live-verified api.buy_crypto_market()
CFD (margin) ✅ live-verified ✅ live-verified api.buy_cfd_market() - covers commodities, stocks, indices, AND ETFs; IQ Option has no separate mode for any of these, they're all marginal-cfd

All six are also available through api.broker.trade(mode=TradeMode.*, ...).

The old buy_order() / close_position() / close_position_v2() methods are confirmed dead (they send flat, non-namespaced message names IQ Option's backend no longer responds to at all) and are kept only for backwards compatibility - they emit a DeprecationWarning. Use the methods in the table above instead.

Streaming (api.stream)

for candle in api.stream.candles("EURUSD", timeframe=60):
    print(candle)

for tick in api.stream.price("EURUSD"):
    print(tick.bid, tick.ask)

for update in api.stream.trade_updates():   # all position-changed events
    print(update)

for event in api.stream.connection():       # connection state changes
    print(event)

api.stream.payout() and api.stream.asset_status() are poll-based (IQ Option doesn't push these two live) rather than true push streams; api.stream.news() is a documented stub - a live news feed wasn't captured/confirmed during this project.

Every stream returns a Subscription - iterate it directly, or call .close() to unsubscribe early.

Positions, history, P&L

ok, positions = api.get_positions("digital-option")   # or "turbo-option", "marginal-forex", etc.
ok, history = api.get_position_history_v2("marginal-cfd", limit=10, offset=0)
pnl = api.get_pnl(positions["positions"][0])          # takes a raw position dict

Matching a position back to the order id that opened it is not always a plain equality check - digital and margin positions key external_id as the position id, not the order id (order ids live in a separate list). Use IQOptionClient.position_matches_order_id() rather than comparing external_id directly if you're writing your own matching logic; get_digital_position() / get_margin_position() / Trade.refresh() already do this correctly.

Testing

See tests/README.md for the full test suite - it runs against the real backend (PRACTICE balance), gated behind IQ_EMAIL/IQ_PASSWORD and opt-in flags (IQ_ALLOW_TRADE, IQ_ALLOW_DIGITAL, IQ_ALLOW_MARGIN) for anything that places a trade.

export IQ_EMAIL="you@example.com"
export IQ_PASSWORD="your-password"
pytest                    # read-only tests
IQ_ALLOW_TRADE=1 IQ_ALLOW_DIGITAL=1 IQ_ALLOW_MARGIN=1 pytest   # everything

Project layout

iqair/
  client.py         high-level client (IQOptionClient) - most users start here
  broker.py         OOP wrapper (api.broker) - Trade/TradeMode/TradeSide
  streaming.py       api.stream namespace
  api.py             low-level request/response plumbing
  models.py          typed dataclasses (Position, Candle, etc.)
  ws/                websocket client + per-endpoint request builders
  agent/              LLM tool-calling / orchestrator integration (tools, dispatcher, HTTP server)
docs/
  USAGE.md            full end-to-end usage guide
  AGENT.md            orchestrator / LLM tool-calling integration guide
  TICKERS.md          how to find valid ticker strings per trading mode
tests/                live-backend test suite (see tests/README.md)

Disclaimer

This is an unofficial, community-maintained wrapper, not affiliated with or endorsed by IQ Option. IQ Option's API is undocumented and can change without notice - endpoints that work today may not tomorrow. Use at your own risk, and always test against the PRACTICE balance before trusting anything with real funds.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

iqair-1.0.0.tar.gz (88.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

iqair-1.0.0-py3-none-any.whl (98.0 kB view details)

Uploaded Python 3

File details

Details for the file iqair-1.0.0.tar.gz.

File metadata

  • Download URL: iqair-1.0.0.tar.gz
  • Upload date:
  • Size: 88.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for iqair-1.0.0.tar.gz
Algorithm Hash digest
SHA256 001237669577e35ca8c413d236556b29e06122048f81e6675bab03c65d007406
MD5 2a5cb67f21f8b8e4b5cb88f7d2c486e6
BLAKE2b-256 8edc9c709f7258eee0f2dc136d14ae5d33ed76096fe02c22acddeb6eeb264462

See more details on using hashes here.

Provenance

The following attestation bundles were made for iqair-1.0.0.tar.gz:

Publisher: publish.yml on Omerhrr/iqair

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file iqair-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: iqair-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 98.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for iqair-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b0ec8aebfd8b6a6b9880b1fe896786b6545d050e82d4b19aaa123611c961e50d
MD5 ce631dbb06939ed637f2e5908aa14d75
BLAKE2b-256 e3be015611fa5d9c35aae0b21234fac8540e594bf455ea5c663dc69e79ff7221

See more details on using hashes here.

Provenance

The following attestation bundles were made for iqair-1.0.0-py3-none-any.whl:

Publisher: publish.yml on Omerhrr/iqair

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page