Skip to content

Contributing to tradedesk

We welcome contributions to tradedesk. This guide covers the standards and workflow you need to contribute successfully.

What this repository holds

This repository holds the tradedesk framework: the Python package (tradedesk/) with its tests, docs and examples, and the Rust crates (crates/tradedesk-data and crates/tradedesk-backtest) with theirs, plus the CI and release workflows. It holds no trading strategies, no research artefacts (hypotheses, registrations, registries, results, verdicts) and no venue- or deployment-specific configuration (accounts, credentials, live sizing, portfolio or strategy configs). Those belong elsewhere, and a pull request that carries them is declined.

"Trading strategies" means the venture's strategies: the ideas, parameters and configurations that trade its capital, which live in the private strategy repository. Four things that look like strategies are framework and belong here: the generic strategy base and runtime glue in tradedesk/strategy/ (the MLDirectionStrategy runs any predict_proba model through the portfolio's risk controls and carries no model, instrument or parameters of its own); the documentation examples in docs/examples/, which exist to show the API; the backtester's test strategy (crates/tradedesk-backtest/tests/toy/), which exists only to drive its tests; and its builtin cost table (crates/tradedesk-backtest/config/costs.toml), which is reference data: the venues' published fees, each with its source, that any run can replace with its own file. The test of any of them is that it names no instrument, parameter set or result that is the venture's.

Review enforces this boundary for now; tooling to check it is still to come. The pre-commit guard below catches the most common path-based cases.

Getting Started

  1. Fork the repository and create a feature branch from main.
  2. Clone locally and install the dev dependencies:
pip install -e '.[dev]'
  1. We use uv for dependency management. If you have uv installed you can use it directly:
uv sync --extra dev
  1. Install the pre-commit hooks. These run ruff-format and a guard that blocks private strategy research from being committed to this public repo (paths under research/, killstack/, or anything containing private):
pre-commit install

The guard script lives at scripts/hooks/block-private-research.sh and is also runnable on demand against the staged tree. If a commit is rejected with Blocked: private research content detected — commit to ig_trader instead, the listed files belong in the private ig_trader repo, not here.

Code Standards

Python Version

Python 3.11+ is required.

Style and Linting

We use ruff for linting and formatting:

ruff check .
ruff format --check .

Rules enforced: E, F, I (import sorting), TID (tidy imports). Line length is 100 characters.

Type Checking

We use mypy in strict mode:

mypy .

All contributions must pass with zero type errors.

Import Conventions

Cross-domain imports must use top-level re-exports. For example, code in tradedesk.execution should import from tradedesk.marketdata, never from tradedesk.marketdata.events. Classes and functions intended for use outside their domain must be explicitly exported in __init__.py.

Testing

We use pytest:

pytest

The Rust crates have their own gates, run from the repository root with the toolchain pinned in rust-toolchain.toml; CI runs them when a Rust path changes:

cargo build --workspace --all-targets --locked
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo test --workspace --locked
cargo fmt --check
cargo deny check
  • All new and existing tests must pass following any code change.
  • Include tests for new functionality or bug fixes.
  • Code coverage must not decrease.

Credentials and Release Automation

Local development, CI, and backtests do not require repository secrets.

Live IG execution uses environment variables read by tradedesk.execution.ig.settings.Settings:

  • IG_API_KEY (required)
  • IG_USERNAME (required)
  • IG_PASSWORD (required)
  • IG_ENVIRONMENT (optional, defaults to DEMO; must be DEMO or LIVE)

Do not commit real IG values in examples, shell history snippets, or tests. The library negotiates the short-lived IG session headers (CST and X-SECURITY-TOKEN) during authentication, so contributors should not try to store or configure those manually.

Maintainers triggering .github/workflows/prepare-release.yml must configure these repository secrets:

  • RELEASE_APP_ID
  • RELEASE_APP_PRIVATE_KEY

The shared reusable release workflow uses those values to mint a GitHub App token for checkout, version bumping, pushing the release commit, and creating the GitHub release. .github/workflows/publish.yml uses PyPI trusted publishing via GitHub OIDC (id-token: write), so no PyPI API token secret is expected in this repository.

Pull Requests

  • Keep changes small, well-scoped, and documented in PR descriptions.
  • Open PRs against main.
  • Rebase your branch onto main before submitting — we do not use merge commits.
  • Provide a brief rationale and expected impact in the PR description.
  • Do not include secrets or internal data.

Commit Messages

Follow Conventional Commits:

feat(strategy): add trailing stop support
fix(portfolio): correct position sizing on partial fills
docs: update backtesting guide

Reporting Issues

If you find a bug or have a feature request, open an issue describing the goal and expected behaviour. Include steps to reproduce for bugs.

If unsure, open an issue describing the goal and request guidance before implementing.


License

Licensed under the Apache License, Version 2.0. See: https://www.apache.org/licenses/LICENSE-2.0

Copyright 2026 Radius Red Ltd. | Contact