Skip to main content

TradePose Client

Client 3.10.0 development targets Models 2.14.0. Local compilation changes and release preparation are described in docs/COMPILATION_PERFORMANCE.md. The published Client 3.9.0 is paired with Models 2.14.0. Installation and migration details are provided in the Client package’s docs/RESULTS.md; release evidence is maintained in the repository’s docs/releases/client-3.9.0-models-2.14.0.md. Analyzer is installed locally from the same release source and is not published to PyPI.

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.9.0 is an Alpha minor-breaking release and requires coordinated Gateway/Worker task and expression contracts. Preserve active workspace evidence and follow the packaged docs/RESULTS.md guide before upgrading.

Requirements and installation

Client 3.9.0/Models 2.14.0 已於 2026-09-13 發布至 PyPI,可直接安裝以下配對。

  • 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==3.9.0' 'tradepose-models==2.14.0'

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

Client 3.9.0 requires tradepose-models>=2.14.0,<3.0.0. Upgrade the pair together. For Client 3.8.0, preserve the existing lock or pin Models 2.13.0, including during the Models-first publication window. 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. Restrictive database references also protect Runs from removal and appear as storage_reference protection reasons. Cleanup preserves those references and continues removing other eligible Runs without changing the workspace schema.

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>

Verified Result selections publish an immutable Gateway PortfolioVersion with explicit name, allocation and reference notional. Use result.select(selection_id, allocation_weight=...) and client.portfolios.publish_verified_run_version(portfolio_name=..., reference_notional=..., selections=...). Memory and saved Runs share this seam; publication never creates a SQLite store.

Published catalogs enter the research lifecycle through explicit resolution. client.portfolios.materialize_evaluation_experiment(research, version=version, period=...) returns an actionable memory Experiment pinned to immutable Gateway bytes. It supports preview(), explicit save(name), and run(preview=...) without a catalog lookup. Current Working Source never replaces published content. Definition-only materialization remains available through client.definitions.materialize_experiment(...).

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 published evidence, 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 provides one authoring and execution entry point. Experiments start in memory and accept the imported recipe, typed Params and immutable UTC Period. experiment.save(name) explicitly saves settings; lookup can select an exact revision. preview() is optional and local. run() prepares one Run, starts background submission, and returns its handle before the whole batch is accepted. Local validation and Run creation errors are synchronous; submission errors are recorded on that Run and observed through diagnostics() and wait(). Acceptance does not mean remote computation completed. All handles share the workspace's single lazy SubmissionEngine runtime owner. Backtests always produce trade artifacts; persist_trades=False is the default. Set it to True only to additionally save trades to Gateway PostgreSQL.

The executable examples in examples/research_single.py and examples/research_three_members.py run independently in an empty research directory. Personal notebooks remain local ignored files.

The example uses the actual rsi-reversion strategy created as alpha.py:

from playbook.strategies.alpha import RsiReversionParams, rsi_reversion
from tradepose_client import Period, ResearchWorkspace

with ResearchWorkspace.open(".") as research:
    experiment = research.experiments.backtest(
        source=rsi_reversion, params=RsiReversionParams(), period=Period.from_year(2024),
    )
    preview = experiment.preview()  # Optional local inspection
    run = experiment.run()
    trades = run.wait(timeout=1_800).result().trades()
    # Call run.save() here if this same execution should survive the session.

Runs default to memory. experiment.run(save=True) explicitly saves identity, exact requests, source bytes and evidence before the first remote submission. run.save() returns the same handle, never submits work, and retains its ID. Saving during execution switches subsequent observed state and results to local storage after the snapshot transaction succeeds. Failed saves can be retried; repeated saves create no additional Run. Failed or incomplete Runs may be saved for diagnosis but never yield partial analysis results. Experiment creation captures exact source and instrument catalog bytes plus concrete Params. Editing or deleting workspace sources does not change the Experiment, including after save()/get() and restart. with_period() retains captured sources; with_members() captures the supplied members anew. Opening an existing Run never creates replacement work.

Use research.runs.open(run_id) for an exact session or saved identity. Only saved Runs survive restart. experiment.prepare(save=True) separates the durable boundary from submission; without save=True, preparation remains in memory. RunSubmissionError, RunSubmissionInterruptedError, RunSaveError and RunSaveInterruptedError carry the affected Run ID and original cause. After an interrupted save, inspect run.is_saved and retry on the same handle. A validation failure before Run creation does not invent an ID.

The preparation and execution signatures are:

experiment.prepare(*, preview: ExperimentPreview | None = None,
                   save: bool = False, memory_limit_bytes: int = 512 * 1024 * 1024) -> RunHandle
experiment.run(*, preview: ExperimentPreview | None = None,
               save: bool = False, memory_limit_bytes: int = 512 * 1024 * 1024) -> RunHandle

An optional Preview must match the Experiment's captured content. prepare() performs no submission. run() starts submission; resume() joins an active attempt or explicitly retries an ended attempt with the same bytes, keys and retry window. wait() joins the same attempt and then observes tasks and artifacts. Gateway initialization belongs to that attempt: initialization failures remain observable through repeated waits until explicit resume() retries. A wait timeout or handle close leaves submission running. Workspace close drains local tasks and releases its runtime; it does not cancel remote computation. Saved Runs can be reopened and resumed. Completed Run waits still perform task observation; no completed-result wait cache is implied.

For timing, measure Experiment creation, prepare() return, run() handle return and resume() return separately: resume() returns after submission ends. Earlier handle availability does not imply faster remote computation.

run.result() accepts only complete verified evidence and artifacts. Backtest trades(), OHLCV indicators() and OHLCV signals() return kind-specific Polars DataFrames with readable identity columns. raw_frame() is the advanced canonical frame and follows the same complete verification. Backtest trades() expands shared Workloads by exact Case/Policy: two cases sharing 100 physical trades produce 200 analysis rows, with scalar case_id, member_id and selection_id. cases() retains metadata even for zero trades. Portfolio allocation requires an explicit select(selection_id, allocation_weight=...).

run.evidence() and result.evidence() expose named periods, members, Params selections, sources and request states. preview.compare(run) reports named differences and separates research equality, request equality and Run identity. Notebook display reads captured metadata only. Query saved identities with research.runs.list(), then open the selected ID; open(run_id, kind=ExperimentKind.BACKTEST) checks the expected kind for typed analysis. The Result guide (docs/RESULTS.md in the source distribution) covers dtypes, ordering, zero trades, raw access and verification limits. Results retain their content owner for offline use; the last remaining owner controls its lifetime.

memory_limit_bytes defaults to 512 MiB per encoded download and for retained aggregate artifact bytes. Concurrent buffers and decoded DataFrames need additional memory. A RunMemoryLimitError never spills to disk: explicitly save that Run, then wait again, or choose local saving initially. Workspace configuration, named settings and source/instrument caches may write catalog state independently; memory Runs write no Run rows, execution evidence, result files or artifact temporary files. Local saving does not change remote retention or persist_trades.

One workspace owns a shared lazy event loop, transport client and concurrency budgets. Handle/workspace close, Ctrl-C and a local wait timeout stop observation without cancelling accepted remote work. Closing does not promise background downloads. Resume a saved Run later to continue observing and downloading its existing remote work.

Run network recovery is operation-aware and bounded. An ambiguous submission replays only the exact captured request bytes with its idempotency key before the known confirmation deadline, 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; authentication, validation, and other deterministic failures do not retry. Explicitly temporary submission capacity/rate refusals retry the exact bytes and key, for at most three attempts. Retry-After is never shortened: a server delay beyond the retry policy budget (default 60 seconds) ends automatic retry. An unknown or expired confirmation deadline prevents replay of ambiguous outcomes. If the attempt cap or local wait deadline is reached, reopen the same Run to continue from its captured state. Completed artifact bundles are still checksum-, schema-, identity-, and compatibility-verified before they become locally available.

SDK submission, polling and download concurrency default to the local HTTP connection capacity (100), configured with TRADEPOSE_MAX_CONNECTIONS. TRADEPOSE_MAX_KEEPALIVE_CONNECTIONS defaults to 20. These are local resource settings, not membership quotas. Separate poll/download budgets cover active I/O; a remote execution waiting for completion does not block observation of later work. TRADEPOSE_POLL_INTERVAL defaults to two seconds with no increasing poll backoff; run.wait(poll_interval=...) overrides it for that wait. Faster polling consumes more of the shared HTTP allowance. Server rate/capacity refusals remain visible when retries are exhausted.

Server defaults per user are:

Membership Shared HTTP requests/min Research ingest starts/min Occupied execution slots
Free 30 10 10
Pro 360 120 120
Enterprise 720 240 240

Submission, status queries and downloads share the HTTP counter. Ingest starts have a separate counter; threefold HTTP headroom does not mean a Run uses only three requests. Global defaults are 1,200 ingest starts/min and 1,200 occupied execution slots. Monthly usage is telemetry, not an admission quota. Temporary refusal is retried only within the attempt, Retry-After and confirmation budgets described above. A 429 after an unconfirmed write does not prove the original remote execution was rejected; reopen the same Run with its persisted bytes/key to recover within its deadline.

Remote executions have fixed service limits: 300 seconds queued, 900 seconds executing (including save and publication), and 1800 seconds for a sharded parent through merge. Finished executions and their artifacts remain available for 24 hours from termination; querying does not renew that window. Resume cannot resubmit expired or failed remote work. Download and verify within the window; already downloaded results remain usable locally. First Portfolio publication needs live verified evidence, while an already published Portfolio retains its own business Workload independently of remote artifact retention.

Gateway retains SQL execution history and execution statistics through batched lifecycle events. Those records may lag live Redis state; a verified terminal event can correct a deadline inference. Historical status is neither live execution permission nor proof of a business save, and cannot restore expired remote artifacts.

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.

Python research contract

Use public imports, a real strategy source, typed Params and Period directly. Create an Experiment, optionally inspect preview = experiment.preview(), then call experiment.run(). Catalog publication and named Experiment saving are optional. Preview is local and does not authorize remote work; an agent must have explicit research execution intent within the user's approved bounds. Memory storage still submits remote work and may incur usage.

run() returns after local preparation and starts background submission; acceptance is not compute completion. Immediate wait/resume join that same submission. A wait timeout or handle close leaves submission running; workspace close drains local work.

Runs default to memory, including experiment.prepare(). Choose save=True initially or call run.save() during execution or after completion. Saving returns the same Run and ID; subsequent observed states and downloaded results persist locally. persist_trades separately controls Gateway PostgreSQL trade-table persistence; backtests return trade artifacts by default either way. Closing a handle/workspace or a RunWaitTimeoutError stops local observation and does not cancel accepted remote work or promise background downloads. Save before closing, then list research.runs.list() and explicitly open that exact saved ID with research.runs.open(run_id), call resume() and wait() as needed. Running an Experiment again creates a different Run, even when requests are identical.

Only all-success, fully verified Runs provide a Result. Use trades() for backtests, indicators() or signals() for OHLCV. OHLCV accepts one Period and one distinct Workload. raw_frame(), descriptor tables and artifact bytes obey the same complete verification. Three members may share two Workloads: inspect Preview's exact remote work: raw_frame() retains physical rows; trades() expands exact Case/Policy rows. Use cases() for metadata and explicit select() for Portfolio allocation. Successful zero trades retain the complete schema. Preserve RunFailedError and RunResultUnavailableError.kind; never turn failure into an empty DataFrame. Experiment creation fixes source, catalog bytes and Params, including after save/get. with_period() keeps those sources; with_members() captures new member sources. Workspace source edits do not change an existing Experiment. Recovery uses the same Run's captured evidence, exact requests, keys and retry window. Historical unsupported Runs require no data migration for new research; create current sources and Runs in a fresh workspace.

PolicySet 是本機 typed model;單組傳 policies=,多組以 ExperimentCase 配對後傳 cases=。 Experiment 固定具體候選與 seed,保存/重開不重新搜尋;完整 Definition 保留 baseline,執行依 selection。

Shared offline sizing

tradepose_client.sizing provides SizingDraft, typed per-Policy budgets, a native Polars expression profile, a finite-history planner, and SizingInputs.evaluate(). tradepose_analyzer.TradesPerformance(result) or (result.frame) accepts every NoOrder row, retaining raw points separately from USD outcomes. Models owns the shared floor rounding and cost calculation. Given validated SizingInputs, evaluation is entirely offline:

from tradepose_client.sizing import SizingDraft
from tradepose_analyzer import TradesPerformance

result = inputs.evaluate(SizingDraft(risk_amount_usd=1000))
performance = TradesPerformance(result)

The default budget is USD risk per trade, not purchase notional. Snapshot adapters must verify transport, artifact digests, identity, and coverage before supplying inputs; hand-built fixtures do not establish that verification or save/open.

Policy discovery 與 sizing snapshot

client.definitions.list_policies(...)get_policy_contexts(...) 回傳 tenant-owned Policy 與 typed Definition contexts。SizingSnapshotRequest.for_policies(...) 接受 複數 refs/typed contexts,for_portfolio(...) 接受 exact published PortfolioVersion。 await client.definitions.get_sizing_snapshot(request) 原子取得並驗證整批 artifact。

來源必須有已提交完整 extraction coverage;合法零交易有獨立證據,未知/缺口明確拒絕, 不觸發 Worker。Snapshot 複製 canonical source bytes,不依賴暫存結果的保留期限。 SizingSnapshot.save/open/evaluate 支援完全離線反覆 sizing,結果直接交 Analyzer。 使用者範例 examples/sizing_snapshot.py 支援 Policy discovery 與 Portfolio 兩個入口; examples/sizing_snapshot_offline.py 可開啟已保存 artifact。

Verified Result、Portfolio publication 與再研究

Gateway Portfolio metadata 管理名稱與版本集合,PublishedPortfolioVersion 保存 immutable refs、allocation、reference notional 與 execution evidence。研究選擇由完整 verified BacktestRunResult 產生;memory 與 saved Run 使用同一公開入口:

from decimal import Decimal

result = run.result()
candidates = tuple(item for item in result.evidence().selections if item.resolved_policy is not None)
chosen = result.select(candidates[0].selection_id, allocation_weight=Decimal("100"))
version = await client.portfolios.publish_verified_run_version(
    portfolio_name="chosen_research",
    reference_notional=Decimal("100000"),
    selections=(chosen,),
)
evaluation = await client.portfolios.materialize_evaluation_experiment(
    research, version=version, period=result.periods,
)
preview = evaluation.preview()
# 使用者明確要求新研究時才呼叫 evaluation.run(preview=preview)。

選擇候選、名稱及 allocation 是使用者決策。SDK 推導 exact Run/Definition/Policy/remote work refs, 發布時重新驗證完整 Result evidence;任意 frame 無法建立 typed selection。 此步驟不建立 SQLite、不強迫 memory Run 先 save。Saved Run 可由 research.runs.open(run_id).result() 取得相同選擇。保存研究不延長 remote work 的首次發布期限; Gateway 首次發布需要尚未過期的 tenant remote work、sealed binding 及 canonical artifacts。 已存在相同 content hash 的版本可冪等讀回;直接 get_version(ref) 不重新要求 remote work evidence。

materialize_evaluation_experiment(research, version=version, period=Period(...)) 回傳可操作 memory Experiment;save(name) 才保存設定,run(preview=...) 才產生新工作。 它固定 published Definition/Policy bytes 與 evidence,不編譯目前本地 source。

Sizing 使用既有 SizingSnapshotRequest.for_portfolio(version, periods=...)SizingSnapshotRequest.for_policies(chosen_contexts, periods=...),再呼叫 client.definitions.get_sizing_snapshot(request)。Policy-only 入口不需要 Portfolio。 Snapshot 的 save/open 不建立 remote work、SQLite 或 session;離線重複 snapshot.evaluate(SizingDraft(risk_amount_usd="1000")) 不下載資料。 TradesPerformance(sized_result) 直接接受 quantity/USD/NoOrder 及 raw facts, 每個 Policy/Period 保持獨立。Analyzer scoring 與組合挑選仍由既有 Analyzer API 負責。

完整範例:examples/portfolio_research.py(Run → publication → snapshot → sizing → Analyzer) 與 examples/sizing_snapshot.py(複數 Policy contexts → snapshot → sizing → Analyzer)。

Operational schedules and refresh

client.risk_policies provides typed create_schedule, get_schedule, list_schedules, update_schedule, pause_schedule, resume_schedule, request_refresh and get_refresh. Keep the same operation identity after a timeout. Accepted/running receipts do not imply completed sizing; schedule pause does not change binding eligibility or Live Authorization. Use Models requests with operation_ref, reason, expected_version and an explicit IANA timezone. Cadence accepts five or six Unix cron fields.

Exact Research submission evidence

Compiled requests use the single current ResearchTaskRequest collection shape. experiment/_physical.py preserves authored aliases and occurrence indices even when multiple selections share a physical request. Complete original Definitions remain separate from selected baseline/managed Policies. Canonical request identity includes supplied authoring evidence; unchanged calculations do not imply identical submission provenance. Current SDK execution continues to submit legal singleton requests through the existing engine. Full batch entrypoints and aggregation are not exposed by the new data models. Upgrade the SDK and services together; preserve completed Runs with their matching readers, and prepare new Runs from complete retained authoring sources.

Advanced Policies 與明確配對

Policy 表示一個 Advanced candidate;PolicySet 是綁定 exact Params type/hash 的本機 model,不需向 Gateway 註冊。先建立完整 Base Params,再呼叫 PolicySet.sweep() 展開 Cartesian product,或用 PolicySet.cases() 保留 correlated/ mixed-direction candidates。省略 policies 表示 baseline-only;完整 authored Definition 始終保留 baseline。Signals 的 managed selection 不因此執行未選取的 baseline。

單組使用 research.experiments.backtest(source=recipe, params=seed, policies=policies, period=period),Member 使用 ExperimentMember(id="alpha", source=recipe, params=seed, policies=policies)。多組使用 ExperimentCase(params=seed, policies=policies) 的明確配對, 交給 ExperimentMember(..., cases=pairs)backtest(source=recipe, cases=pairs, ...)casesparamspolicies 互斥;多個 Params 不接受單一 PolicySet,必須逐 Base 配對。 共用搜尋可對每個 seed 呼叫同一組 sweep 條件;不同搜尋與部分 baseline-only 使用相同 Case。 錯誤 seed/type、空集合、重複 candidate、非法欄位會拒絕,不做隱式 zip 或重新綁定。

Experiment create 固定 source、Params 與具體候選;後續 caller mutation 不改 Preview/Run。 CLI/file/保存設定使用 members[].cases[],每個 Case 包含 params、可選的 policies 及其 policy_seed_hash;Policies 由既有 TradePolicyParameters canonical serialization 保存,包括 Polars Conditions、note/tags。使用 Experiment export 取得完整 JSON/YAML, import/reopen 不再展開搜尋。note/tags 保留 authoring evidence,不替代 behavioral identity。

四個 Base Cases、各兩個 managed Policies、兩個 Periods 為 4 Cases、12 Policies (含 baseline)、4 Workloads、8 remote work;相同值的不同 Case 保留 identity,物理工作可共用。 最新 Gateway admission 仍要求一個 Workload/member/window,SDK 依現行契約拆分提交。 Advanced 使用 Base Data volatility scale,不改 Base cohort;Portfolio sizing 仍由明確 RiskPolicy 負責。

flowchart LR
  Base[完整 Base Params] --> Sweep[PolicySet.sweep 或 PolicySet.cases]
  Base --> Pair[ExperimentCase params 與 policies]
  Sweep --> Pair
  Pair --> Member[ExperimentMember cases]
  Member --> Experiment[Experiment 固定候選與來源]
  Experiment --> Run[Run]
  Run --> Result[verified Result 與 Case evidence]
from tradepose_client import ExperimentCase, ExperimentMember, Policy, PolicySet, Period

# recipe、seed、other_recipe、other_seed 由各自的 typed Recipe 建立。
period = Period.from_year(2024)
policies = PolicySet.sweep(seed, direction="long", stop_losses=(1.0, 1.5), take_profits=(2.0, 3.0))
single = research.experiments.backtest(source=recipe, params=seed, policies=policies, period=period)
base_cases = seed.sweep(rsi_periods=(7, 14), lower_levels=(20.0, 30.0))
shared = [ExperimentCase(params=p, policies=PolicySet.sweep(p, direction="long", stop_losses=(1.0, 1.5))) for p in base_cases]
paired = [
    ExperimentCase(params=base_cases[0], policies=PolicySet.cases(base_cases[0],
        Policy(direction="long", stop_loss=1.0, take_profit=2.0),
        Policy(direction="short", stop_loss=1.5, take_profit=3.0))),
    ExperimentCase(params=base_cases[1]),
]
multi = research.experiments.backtest(source=recipe, cases=shared, period=period)
combined = research.experiments.backtest(members=[
    ExperimentMember(id="alpha", source=recipe, cases=paired),
    ExperimentMember(id="beta", source=other_recipe, params=other_seed,
        policies=PolicySet.cases(other_seed, Policy(direction="long", timeout_bars=3))),
], period=period)
saved = combined.save("advanced_study")
reopened = research.experiments.get("advanced_study")
assert saved.preview() == reopened.preview()
run = reopened.run()
run.wait()
result = run.result()

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.10.0.tar.gz (605.8 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.10.0-py3-none-any.whl (371.0 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for tradepose_client-3.10.0.tar.gz
Algorithm Hash digest
SHA256 dabfa13913e1e8e5f9f0aa209db56cd4accef8d1c6ab1068f308646f1ff02e7c
MD5 994beaed0bded045357d180b7267cbe6
BLAKE2b-256 ce573da4f9861e6d07e63862965b3c4d6a804ed24a262844afb5882a989f2231

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for tradepose_client-3.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 230adc2578a3aec75bfa3f75b8e8696f267d84939b0c2c64709b92dd1eb13fce
MD5 5f016a054f877b5405ed1f373f5772fe
BLAKE2b-256 0ba46e06b25015aa98746ef3c30e250b98b8eba313f1ea10a49e434644be1bd3

See more details on using hashes here.

Release history Release notifications | RSS feed

3.11.1

2 files

3.11.0

2 files

This release

3.10.0 This release

2 files

3.9.0

2 files

3.8.0

2 files

3.7.0

2 files

3.6.1

2 files

3.6.0

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