Skip to main content

Safe, typed synchronous and asynchronous clients for IG Trading APIs

Project description

IG Trading Library v3

Safe, typed synchronous and asynchronous IG REST and streaming clients.

Install

pip install ig-trading-lib

Python 3.11–3.13 is supported.

Start safely

Use a demo account while building an agent. Credentials are explicit, immutable objects and are redacted from representations and error diagnostics.

from ig_trading_lib import Environment, IGClient, IGConfig, SessionCredentials

config = IGConfig(
    environment=Environment.DEMO,
    credentials=SessionCredentials(
        api_key="…",
        identifier="…",
        password="…",
    ),
)

with IGClient(config) as client:
    markets = client.markets.search("EURUSD")
    for market in markets.items:
        print(market.epic, market.market_status)

The synchronous and asynchronous clients expose matching service namespaces:

Sync Async
IGClient(config) AsyncIGClient(config)
client.markets.search("EURUSD") await client.markets.search("EURUSD")
client.positions.list() await client.positions.list()
client.positions.create(...) await client.positions.create(...)
from ig_trading_lib import AsyncIGClient

async with AsyncIGClient(config) as client:
    accounts = await client.accounts.list()
    print(accounts.items)

Live-trading boundary

Guarded live mutations require an explicit permit in addition to Environment.LIVE. A missing permit fails before authentication or network I/O.

from ig_trading_lib import Environment, IGClient, IGConfig, TradingPermit

live_config = IGConfig(environment=Environment.LIVE, credentials=config.credentials)
client = IGClient(live_config, trading_permit=TradingPermit())

# Position create, update, and close operations are guarded.
client.positions.create({"epic": "CS.D.EURUSD.TODAY.IP", "direction": "BUY", "size": "1"})

The guarded typed surfaces are positions.create, positions.update, positions.close, accounts.update_preferences, and mutation methods on watchlists, working_orders, costs, and applications. ResourceClient instances without a guard are not covered by this boundary.

Do not retry a failed mutation yourself. The client raises AmbiguousExecutionError when a network failure means IG may have accepted it; resolve that outcome with the deal reference or a confirmation before issuing another order.

REST services

Canonical services normalise provider keys to snake_case and paginate with Page plus lazy iter_pages / async iter_pages methods.

with IGClient(config) as client:
    for activity in client.activity.iter_pages(item_key="activities"):
        print(activity)

    position = client.positions.get("DEAL_ID")
    confirmation = client.confirms.get("/DEAL_REFERENCE")

The endpoint catalog is maintained in ig_trading_lib.endpoint_catalog and contract-tested against the maintained DOCUMENTED_ENDPOINTS catalog.

Streaming

Streaming is lazy: no Lightstreamer session is opened until iteration begins. IG requires CST/XST security tokens even for OAuth users; the client obtains them when needed, preserves subscriptions during SDK recovery, and exposes terminal stream errors instead of silently dropping data.

from ig_trading_lib import StreamSubscription

subscription = StreamSubscription(
    key="eurusd",
    mode="MERGE",
    items=("MARKET:CS.D.EURUSD.TODAY.IP",),
    fields=("BID", "OFFER", "UPDATE_TIME"),
)

with IGClient(config) as client:
    updates = client.streaming.iter_updates(subscription)
    try:
        for update in updates:
            print(update.item_name, update.changed_fields)
    finally:
        updates.close()
async with AsyncIGClient(config) as client:
    async for update in client.streaming.aiter_updates(subscription):
        print(update.changed_fields)

Errors and observability

Operational failures derive from IGError. Errors carry a safe provider request ID, a client operation ID, retry timing when supplied by IG, and redacted details. LiveTradingPermissionError is a separate PermissionError raised by the live-mutation guard.

from ig_trading_lib import AmbiguousExecutionError, RateLimitError, TransportError

try:
    client.markets.search("EURUSD")
except RateLimitError as error:
    print(error.retry_after_seconds)
except TransportError as error:
    print(error.operation_id)
except AmbiguousExecutionError as error:
    print("Resolve the deal outcome before retrying", error.operation_id)

Successful requests emit ig.http.response through the ig_trading_lib.transport standard-library logger. The structured record includes method, path, status, retry count, provider request ID, and client operation ID; passwords and tokens are never logged.

Tests and development

poetry sync --with dev
poetry run pytest tests/unit/v3
poetry run ruff format --check src tests scripts examples
poetry run ruff check src tests scripts examples
poetry run pyright
poetry run python scripts/check_documentation_contract.py
poetry run mkdocs build --strict
poetry run playwright install chromium
poetry export --only main --without-hashes --output /tmp/ig-trading-lib-requirements.txt
poetry run pip-audit --strict --requirement /tmp/ig-trading-lib-requirements.txt
poetry build

The default test suite is deterministic and has no IG network dependency. Demo integration runs are deliberately separate and must be invoked only with explicit credentials and opt-in approval. Never store credentials in the repository.

Versioned releases

Documentation and packages are validated on pull requests, main, and develop, but those runs never publish release artifacts. Publishing is restricted to a pushed SemVer tag beginning with v.

Tag Published documentation latest and root redirect
v3.0.0 https://evgesha9400.github.io/ig-trading-lib/3.0.0/ Updated to 3.0.0
v3.1.0-rc.1 https://evgesha9400.github.io/ig-trading-lib/3.1.0-rc.1/ Unchanged

Each versioned site is immutable: a tagged workflow rejects an existing version before mike deploys it. Publish a corrected release under a new SemVer tag instead of changing published documentation.

If a tagged run partially succeeds, maintainers may use the manual release_tag recovery input. The workflow verifies documentation provenance, retains existing immutable Pages content, skips existing PyPI artifacts only during explicit recovery, and completes the remaining release steps.

git tag -a v3.0.1 -m "Release v3.0.1"
git push origin v3.0.1

The tagged workflow publishes immutable documentation, uploads the validated package to PyPI, creates the GitHub Release record, and dispatches evgesha9400/evgesha9400.github.io's rebuild-library-pages.yml workflow. Configure PYPI_API_TOKEN for package publication and LIBRARY_PORTAL_DISPATCH_TOKEN for the portal hand-off.

Disclaimer

This project is not affiliated with IG. Trading involves material risk. Review IG’s REST reference, REST guide, and streaming guide before connecting an agent to an account.

Project details


Download files

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

Source Distribution

ig_trading_lib-3.0.1.tar.gz (21.9 kB view details)

Uploaded Source

Built Distribution

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

ig_trading_lib-3.0.1-py3-none-any.whl (24.4 kB view details)

Uploaded Python 3

File details

Details for the file ig_trading_lib-3.0.1.tar.gz.

File metadata

  • Download URL: ig_trading_lib-3.0.1.tar.gz
  • Upload date:
  • Size: 21.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for ig_trading_lib-3.0.1.tar.gz
Algorithm Hash digest
SHA256 1cc99c34acd69055854f6dcc69e7d8255ff7d18b3a2c3c2d9595fbea37f1444e
MD5 409751b4b0d3d6c554745b4aa4fbd407
BLAKE2b-256 7a1a74b35b36129142da053db52f7a3fc2babf810f674cdaba4ccfad6d05b556

See more details on using hashes here.

File details

Details for the file ig_trading_lib-3.0.1-py3-none-any.whl.

File metadata

  • Download URL: ig_trading_lib-3.0.1-py3-none-any.whl
  • Upload date:
  • Size: 24.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for ig_trading_lib-3.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 378ec7572347a5c7c8666e3a68013de882ed487872f70d28b430cd7ee27a4405
MD5 d15bef5c263be4a45db76a2b9762f671
BLAKE2b-256 521b16908937cd8de1f4f4893c70423c3883cb29111422e54fc1180543bd93d5

See more details on using hashes here.

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