Skip to main content

TradePose Client

TradePose Client is the public Python SDK and command-line workspace for reproducible quantitative trading research. It keeps strategy source, experiment definitions, and research evidence connected from the first local check through portfolio selection.

The primary workflow is:

Strategy Family -> Experiment -> Preview -> Run -> Evidence -> PortfolioVersion -> Risk

TradePose Client is Alpha software. Expect the authoring and research interfaces to evolve between releases. Client 3.5.0 is an approved minor breaking release with direct removals and no compatibility facade; preserve active workspace evidence and follow the packaged docs/MIGRATION_3_6.md guide before upgrading.

Requirements and installation

  • Python 3.13 or newer
  • macOS or Linux
  • A TradePose account and API key only when you choose remote execution

For a new project, install with uv:

uv init --python 3.13
uv add tradepose-client

If you already have an activated Python 3.13+ environment, pip install tradepose-client is also supported.

Client 3.6.0 selects tradepose-models>=2.11.0,<3.0.0. Do not install or pin Models separately. tradepose-analyzer is not a Client runtime dependency or installable Client extra.

Five-minute local workflow

Start in the clean project directory created above:

uv run tradepose init .
uv run tradepose doctor

uv run tradepose strategy new rsi_reversion --template rsi-reversion
uv run tradepose strategy show rsi_reversion
uv run tradepose strategy check rsi_reversion

uv run tradepose experiment new rsi_2024 \
  --source working:rsi_reversion \
  --year 2024

uv run tradepose experiment check rsi_2024
uv run tradepose experiment preview rsi_2024 --verbose

Everything through Preview is local-only. These commands do not construct a Gateway client, create a Run, or consume remote execution usage. Preview resolves the exact source revision, parameter selection, execution configuration, request identity, and remote-work count before anything is submitted.

The generated Working Source is playbook/strategies/rsi_reversion.py. Edit its typed parameters and recipe, then rerun the Strategy and Experiment checks to catch authoring errors locally.

Remote execution is explicit

Set an API key only when the preview is ready to run:

export TRADEPOSE_API_KEY="..."
uv run tradepose experiment run rsi_2024

experiment run is the explicit remote-execution boundary. Before submission it shows the exact remote-work count and asks for confirmation. Remote execution is subject to the usage limits applicable to your account.

For intentional automation, --yes skips the confirmation prompt. Use it only when the automation has already reviewed the preview and remote-work count.

Each accepted execution creates one durable Run. An unprotected terminal Run becomes eligible for local cleanup after seven days by default. Preserve important evidence as an explicit research decision:

uv run tradepose run keep <run-id> --reason "selected for forward evaluation"

run unkeep removes that protection. state clean previews eligible cleanup unless you explicitly apply it, and local removal never cancels remote work.

Research lifecycle and evidence

A Strategy Family owns the stable research idea. Its Working Source is the editable Python implementation. Exact source revisions let Experiments and Runs retain the code that produced their results even after the Working Source changes.

An Experiment records periods, Strategy Family members, parameter selection, and build mode. It is revisioned rather than overwritten, so changes remain reviewable. Useful local commands include:

uv run tradepose experiment show rsi_2024
uv run tradepose experiment history rsi_2024
uv run tradepose experiment diff rsi_2024
uv run tradepose experiment clone rsi_2024 --as rsi_2025

A Run is the evidence root for one remote execution. It connects the submitted request, source snapshots, results, and selected configurations. Inspect evidence locally with:

uv run tradepose run list
uv run tradepose run show <run-id> --verbose
uv run tradepose inspect run:<run-id>

Portfolio promotion records exact selected evidence instead of copying an untraceable configuration. A Portfolio version can later create a new-period evaluation Experiment without automatically executing it.

Published catalogs enter the same lifecycle through explicit resolution. Use client.definitions.materialize_experiment(...) for exact Definition/Policy selections or client.portfolios.materialize_evaluation_experiment(...) for an immutable published PortfolioVersion. Both seal verified Gateway bytes and refs into an ordinary local Experiment revision; later preview, prepare, run, resume, and result access are local workspace operations and never recompile Working Source or implicitly refresh Gateway.

Catalog publication is also explicit. Publish one complete compiled Definition/Policy set with client.definitions.register(compilation). After a Run is complete and locally verified, use client.portfolios.publish_verified_run_version(...); the Gateway independently revalidates the completed remote work, admitted source binding, and canonical artifact bundle before publishing one immutable PortfolioVersion. Neither operation is part of Preview or ordinary Run recovery.

The public async client exposes client.risk_policies for the post-publication sizing handoff: register an immutable policy/account binding, inspect replaceable projections, request formal batch evaluation, and resolve a sizing Engagement's canonical context. These calls return typed tradepose-models contracts; the removed local Portfolio-to-order-event handoff has no sizing fallback. Returned quantities are authoritative Gateway pre-execution sizing evidence, not live margin, open-heat, liquidity, or broker-execution authorization.

Strategy authoring model

TradePose strategies are typed Python modules. A source declares market data and indicators, a Base opportunity describes the market event, and optional post-Base policies describe entry and exit decisions. Parameters remain separate from assembly so one definition can produce reproducible baseline, sweep, or policy cases.

The generated RSI template is executable documentation. Its central shape is:

from tradepose_client import authoring as tp


@tp.strategy(RsiReversionParams)
def rsi_reversion(
    builder: tp.DefinitionBuilder,
    params: RsiReversionParams,
) -> None:
    """Build the documented RSI mean-reversion Base opportunity."""

    primary = params.primary
    opportunity = params.opportunity
    rsi = builder.col(primary.rsi)
    long_entry = rsi < opportunity.lower_level
    long_exit = rsi >= 50.0
    short_entry = rsi > (100.0 - opportunity.lower_level)
    short_exit = rsi <= 50.0
    entry, exit = (
        (long_entry, long_exit)
        if opportunity.direction == tp.TradeDirection.LONG
        else (short_entry, short_exit)
    )
    builder.data.set_volatility_scale(primary.volatility_atr)
    builder.base(
        direction=opportunity.direction,
        trend=opportunity.trend,
        entry=entry,
        exit=exit,
    )

Use strategy show to inspect the public parameter interface and strategy check to validate source identity, completed-bar causality, indicator dependencies, and build contracts. Experiment Preview then expands parameter selections and reports exact work without crossing the remote boundary.

Policy and Experiment authoring describe executable entry and exit behavior only. Position sizing belongs to the Gateway-owned RiskPolicy resource after verified selection and explicit Portfolio Version publication; it is not a Policy sweep or compatibility input.

Discover published portfolios and risk policies

Gateway discovery uses tenant-scoped typed resources:

async with TradePoseClient(api_key=api_key) as client:
    portfolios = await client.portfolios.list(limit=20)
    for portfolio in portfolios.portfolios:
        print(portfolio.name, portfolio.portfolio_ref, portfolio.version_count)
        versions = await client.portfolios.list_versions(
            portfolio_ref=portfolio.portfolio_ref,
            publication_status="approved",
            limit=20,
        )
        for version in versions.versions:
            exact = await client.portfolios.get_version(version.portfolio_version_ref)
            policies = await client.risk_policies.list(
                portfolio_version_ref=exact.portfolio_version_ref, limit=20
            )
            for summary in policies.risk_policies:
                print(summary.portfolio_name, summary.summary, summary.risk_policy_ref)
                policy = await client.risk_policies.get(summary.risk_policy_ref)

All three lists use limit (default 50, range 1–100) and offset (default 0, nonnegative). count is the number of entries on the returned page. Follow next_offset until it is None, retaining the same filters. Ordering is descending creation time, then descending exact ref (portfolio_ref for Portfolios); ties do not duplicate or omit entries while the collection is unchanged. Offset pagination is not a transactional snapshot across concurrent creates/deletes. Empty and out-of-range pages contain no entries and have next_offset=None.

The HTTP endpoints are GET /api/v1/portfolios, GET /api/v1/portfolios/{portfolio_ref}, GET /api/v1/portfolio-versions, GET /api/v1/portfolio-versions/{portfolio_version_ref}, GET /api/v1/risk-policies, and GET /api/v1/risk-policies/{risk_policy_ref}. Omitted parent filters include all tenant-owned resources. A supplied missing or inaccessible parent ref returns the same 404 response; malformed refs, pagination values, and unsupported publication statuses return 422. The only publication status is approved. Exact version reads and version discovery validate persisted publication evidence; corrupted authorized publication data returns 409, including Portfolio latest-version summaries.

Portfolio list items expose the current name, portfolio_ref, created_at, is_archived, version_count, and latest_version. Read current metadata by exact ref with client.portfolios.get(portfolio_ref). Published selections are returned by get_version(portfolio_version_ref). archived=True includes archived Portfolios; it does not mean archived-only. Versions and policies remain discoverable after their Portfolio is archived, and exact version reads remain available. Portfolios without versions and versions without RiskPolicies are retained in discovery.

portfolio.name is the current mutable display label. latest_version.portfolio_name, version.portfolio_name, and RiskPolicy summaries' portfolio_name are publication-time snapshot labels. A rename does not alter published content or exact identity. RiskPolicy summary describes risk fraction, history lookback, minimum samples, and evaluator; it is a display aid, not an identity or unique name. Use exact refs for subsequent reads.

RiskPolicy detail returns effective stored rules, omitting overrides whose optional fields are all None. Partial overrides retain None and inherit defaults without expanding them. Selector ref order, Decimal values, UTC timestamps, canonical expression encoding/payload, evaluator revision, and the stored risk_policy_ref are preserved. Discovery does not guarantee reconstruction of the original registration payload: omitted and explicitly empty overrides may produce distinct stored identities with the same discovered effective rules. Those policies remain separate list entries with their own refs and creation times. A policy bound to multiple accounts appears once. Discovery does not register policies, evaluate sizing, append decisions, or schedule work.

Local state and retention

Workspace metadata lives in .tradepose/state.sqlite3. Canonical request bytes and source snapshots stay with Run records; larger downloaded artifacts live below results/runs/<run-id>/.

uv run tradepose state info
uv run tradepose state clean

Keep .tradepose/state.sqlite3 and retained result artifacts together when backing up a workspace. SQLite schema 11 is authoritative. Close running clients before executing tradepose state migrate to upgrade a schema 10 workspace. The command creates a complete SQLite/results backup under .tradepose/migration-backups/, preserves historical Run records and artifacts verbatim, and restores that backup if activation fails. Ordinary commands refuse SQLite access while an interrupted migration journal exists. Close clients and rerun tradepose state migrate to recover explicitly before creating new work. Ordinary commands never migrate or delete existing data. Historical Runs cannot be read or resumed; prepare new Runs using current Experiment inputs after upgrading. Earlier SQLite schemas must remain intact in their original workspace; create a new workspace for current work.

Instruments and optional agent skills

The workspace instrument catalog supplies canonical identifiers and market metadata. After configuring remote access, synchronize it deliberately:

uv run tradepose instruments sync
uv run tradepose instruments status

The Client also ships optional Claude and Codex skills for strategy authoring and research workflow guidance. Install and verify them in a workspace with:

uv run tradepose skills install --agents claude,codex
uv run tradepose skills check

After upgrading the SDK, synchronize the selected agents and check the result so the workspace uses the bundled guidance from the installed version:

uv run tradepose skills sync --agents claude,codex
uv run tradepose skills check

These generated guidance files are local tooling. They do not submit research or grant an agent remote-execution authority.

Interactive notebook API

ResearchWorkspace is the public durable notebook interface. Opening a workspace and looking up an Experiment are local-only. Creating remote work requires the explicit authorize_remote=True boundary, and every handle shares the workspace's single SubmissionEngine runtime owner:

from tradepose_client import (
    ResearchWorkspace,
    RunSubmissionInterruptedError,
    RunWaitTimeoutError,
)

with ResearchWorkspace.open(".") as research:
    experiment = research.experiments.get("rsi_2024")
    preview = experiment.preview()  # local-only; no Run and no network runtime
    try:
        run = experiment.run(authorize_remote=True, preview=preview)
        run_id = run.run_id
    except RunSubmissionInterruptedError as interrupted:
        # The Run already exists. Resume this identity; never create a replacement.
        run_id = interrupted.run_id
        run = research.runs.open(run_id).resume()
    try:
        run.wait(timeout=1_800)
    except RunWaitTimeoutError:
        # The local deadline stopped observation only. Reopen the same durable Run later.
        pass

with ResearchWorkspace.open(".") as research:
    run = research.runs.open(run_id)
    run.wait(timeout=1_800)
    evidence = run.evidence()
    result = run.result()  # kind-directed, complete verified local artifacts only
    frame = result.frame()  # concatenated trades, or one physical OHLCV DataFrame
    presentation = result.presentation()  # verified offline notebook projection
    friendly = presentation.frame
    policy_index = presentation.policies
    indicator_index = presentation.indicators

Use experiment.prepare(preview=preview) when the durable evidence boundary must be separate from remote submission. Preparation commits exact source bytes, Experiment revision, resolved Params, canonical Definition and Workload bytes/refs, BuildEvidence, catalog snapshot bytes/digest, and environment provenance. A changed source or catalog fails closed before submission. run.result() works after restart without network I/O and never exposes internal remote-work identities or artifact paths. It verifies complete exact Run evidence before exposing results and loads artifact content lazily with a fresh digest check at use time; incomplete, incompatible, corrupt, or digest-invalid evidence or artifacts raise typed RunResultUnavailableError outcomes.

presentation() keeps every canonical column unchanged and appends UTC execution windows, the exact workload_ref, and kind-directed readable Policy/Indicator columns. Its fixed-schema indexes are derived only from retained request, Workload, BuildEvidence, and Worker manifests; it does not read Working Source, query a catalog, or call the Gateway.

RunHandle.close(), a local timeout, and Ctrl-C never claim to cancel accepted remote work. diagnostics() exposes detailed lifecycle and internal remote-work identities on request; those identities and artifact paths are not the primary notebook interface. If Ctrl-C interrupts the initial submission after durable Run creation, RunSubmissionInterruptedError.run_id identifies the only Run that may be reopened and resumed.

Use run.rerun(authorize_remote=True) only for an intentional new execution. It creates a new Run linked by rerun_of, copies the saved exact canonical requests without recompiling the current Working Source, and obtains fresh idempotency keys, Tasks, and admission evidence.

Run network recovery is operation-aware and bounded. An ambiguous submission replays only the exact persisted request bytes with its durable idempotency key, so it resolves to the same logical remote work; a key/content conflict is terminal. Polling and downloads retry only network failures, temporary rate limits, and selected server failures with capped jittered backoff. Temporary rate limits honor a bounded Retry-After; quota, authentication, validation, and other deterministic failures do not retry. If the attempt cap or local wait deadline is reached, reopen the same Run to continue from SQLite state. Completed artifact bundles are still checksum-, schema-, identity-, and compatibility-verified before they become locally available.

Support, status, and license

Compilation and selection evidence

StrategyRecipe.compile() produces one complete canonical Definition, its exact Workload, and BuildEvidence for each typed Params occurrence. Expand a ParamGrid with .expand(params) and compile every result independently. A PolicySet supplies the complete managed Policy set for one occurrence. Strategy check and Experiment check/preview use this same compiler.

Preview JSON exposes workloads, policies, and exact refs. Each selection retains its DefinitionRef, WorkloadRef, PolicyRef, AuthoringOccurrence, actual resolved Params, and member lineage. AuthoringOccurrence also retains the exact volatility_scale_node selected by the recipe, even when multiple logical indicators share one physical computation. Identical complete Workloads share a request per Period. Run preparation, resume, results, and Portfolio publication verify these exact refs and retained bytes.

Download files

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

Source Distribution

tradepose_client-3.6.0.tar.gz (383.3 kB view details)

Uploaded Source

Built Distribution

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

tradepose_client-3.6.0-py3-none-any.whl (291.3 kB view details)

Uploaded Python 3

File details

Details for the file tradepose_client-3.6.0.tar.gz.

File metadata

  • Download URL: tradepose_client-3.6.0.tar.gz
  • Upload date:
  • Size: 383.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for tradepose_client-3.6.0.tar.gz
Algorithm Hash digest
SHA256 588a2b6d0b9ac5ce8b2c3a13eebe38142dcb5c5d167b042aff42164e34663e44
MD5 e94dc2b3554f5992095ba39e166a67c9
BLAKE2b-256 281d2c11b0ecb6a45164b18432f9277091c39b6348b1ae67655b656f81a95a5f

See more details on using hashes here.

File details

Details for the file tradepose_client-3.6.0-py3-none-any.whl.

File metadata

File hashes

Hashes for tradepose_client-3.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e1c19c0bec5ede8e79b1ad8c0235e1574726222750bd48d3b516a9caac19b02f
MD5 b48ced60e8b214fbd826f33fc4f9d064
BLAKE2b-256 581a6eeb6a7439cabb3f210b2be47af0e62e8d6853a8b1d9bfe4850a8540039d

See more details on using hashes here.

Release history Release notifications | RSS feed

3.11.1

2 files

3.11.0

2 files

3.10.0

2 files

3.9.0

2 files

3.8.0

2 files

3.7.0

2 files

3.6.1

2 files

This release

3.6.0 This release

2 files

3.5.1

2 files

3.5.0

2 files

3.4.3

2 files

3.4.2

2 files

3.4.1

2 files

3.4.0

2 files

3.3.1

2 files

3.3.0

2 files

3.2.5

2 files

3.2.4

2 files

3.2.3

2 files

3.2.2

2 files

3.2.1

2 files

3.2.0

2 files

3.1.0

2 files

3.0.0

2 files

2.6.2

2 files

2.6.1

2 files

2.6.0

2 files

2.5.0

2 files

2.4.0

2 files

2.3.0

2 files

2.2.0

2 files

2.1.0

2 files

2.0.0

2 files

1.8.1

2 files

1.8.0

2 files

1.7.1

2 files

1.7.0

2 files

1.6.0

2 files

1.5.0

2 files

1.4.0

2 files

1.2.0

2 files

1.1.0

2 files

1.0.0

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page