Fix live option guards, grounding operand evidence, source-bound benchmarks, trade artifacts, attribution, drawdowns, valuation tolerances, and SEC point-in-time factor inputs. Add Brazil research data and market support, 13 fundamental and valuation factors, channel progress forwarding, and opt-in ZimaOS templates. Update seven README News sections with three visible dates. Validation: 17,635 backend tests passed; 1,084 final targeted tests and 103 frontend tests passed. Frontend build, package build, documentation checks, and CI gates passed.
150 lines
5.6 KiB
Python
150 lines
5.6 KiB
Python
"""Mandate data model — the immutable bounded-autonomy contract.
|
|
|
|
Frozen dataclasses (no Pydantic): the mandate is read once at boot and never
|
|
mutated, so plain frozen dataclasses give the strongest immutability guarantee
|
|
with zero validation surface the agent could exploit. See
|
|
the live-trading SPEC, Mandate §1.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from enum import Enum
|
|
|
|
MANDATE_SCHEMA_VERSION = 1
|
|
|
|
|
|
class InstrumentType(str, Enum):
|
|
"""Instrument classes the broker may report or accept.
|
|
|
|
``CFD`` covers margin contracts-for-difference that are not spot forex
|
|
pairs (MT5 metals like XAUUSD, index/energy/crypto CFDs). It has no universe
|
|
asset-class bucket and requires ``"cfd"`` in ``allowed_instruments``.
|
|
``OPTION`` is representable for classification, but order enforcement
|
|
refuses it until an options-specific risk gate is available.
|
|
"""
|
|
|
|
EQUITY = "equity"
|
|
ETF = "etf"
|
|
OPTION = "option"
|
|
CRYPTO = "crypto"
|
|
FOREX = "forex"
|
|
CFD = "cfd"
|
|
|
|
|
|
class AssetClass(str, Enum):
|
|
"""Universe-level asset class buckets the user may permit."""
|
|
|
|
US_EQUITY = "us_equity"
|
|
US_ETF = "us_etf"
|
|
HK_EQUITY = "hk_equity"
|
|
CN_EQUITY = "cn_equity"
|
|
IN_EQUITY = "in_equity"
|
|
CRYPTO = "crypto"
|
|
FOREX = "forex"
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class HardCaps:
|
|
"""Layer (a): user-set quantitative ceilings.
|
|
|
|
Funding is enforced BROKER-SIDE (Robinhood dedicated agentic account
|
|
balance) and is the absolute ceiling the agent physically cannot exceed;
|
|
it is mirrored here only for defense-in-depth pre-trade math, never as the
|
|
primary guarantee. Every other field is enforced VIBE-SIDE in the gate.
|
|
|
|
Attributes:
|
|
account_funding_usd: Ring-fenced balance in the dedicated agentic
|
|
account, USD. BROKER-ENFORCED ceiling; mirrored for local math.
|
|
max_order_notional_usd: Vibe-enforced max single-order notional, USD.
|
|
max_total_exposure_usd: Vibe-enforced cap on aggregate post-trade
|
|
market value of all open positions, USD.
|
|
max_leverage: Vibe-enforced gross leverage multiple. 1.0 == cash-only.
|
|
allowed_instruments: Vibe-enforced whitelist of tradable instrument
|
|
types. Empty == deny all (fail-closed).
|
|
max_trades_per_day: Vibe-enforced count of order placements allowed
|
|
per UTC calendar day. Counter persisted alongside the mandate.
|
|
"""
|
|
|
|
account_funding_usd: float
|
|
max_order_notional_usd: float
|
|
max_total_exposure_usd: float
|
|
max_leverage: float
|
|
allowed_instruments: tuple[InstrumentType, ...]
|
|
max_trades_per_day: int
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class UniverseConstraint:
|
|
"""Layer (b): user-set universe the agent picks symbols WITHIN.
|
|
|
|
Not a ticker whitelist — that would kill agent discovery. The agent selects
|
|
individual symbols freely so long as each clears these structural filters.
|
|
|
|
Attributes:
|
|
asset_classes: Permitted asset-class buckets. Empty == deny all.
|
|
min_market_cap_usd: Market-cap floor, USD. ``None`` == no floor.
|
|
min_avg_daily_volume_usd: Liquidity floor as trailing avg daily dollar
|
|
volume, USD. ``None`` == no floor.
|
|
exclude_symbols: Hard per-symbol denylist (normalized upper-case,
|
|
e.g. ``BTC-USDT`` style for crypto). Takes precedence over every
|
|
other universe rule.
|
|
"""
|
|
|
|
asset_classes: tuple[AssetClass, ...]
|
|
min_market_cap_usd: float | None
|
|
min_avg_daily_volume_usd: float | None
|
|
exclude_symbols: tuple[str, ...]
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ConsentMeta:
|
|
"""Provenance proving the user (not the agent) authored this mandate.
|
|
|
|
Attributes:
|
|
created_at: ISO-8601 UTC timestamp the user committed the mandate.
|
|
consent_token_sha256: Hash of the consent artifact emitted by the
|
|
consent UX section, binding this file to an explicit human approval.
|
|
broker: Broker key, e.g. ``"robinhood"``.
|
|
account_ref: Opaque broker account identifier (NOT credentials).
|
|
expires_at: ISO-8601 UTC timestamp after which the mandate is dead and
|
|
the gate fail-closes until the user re-authorizes. Default lifetime
|
|
30 days from ``created_at`` (configurable per commit). A live
|
|
mandate must not live forever — see §9 decision 2.
|
|
"""
|
|
|
|
created_at: str
|
|
consent_token_sha256: str
|
|
broker: str
|
|
account_ref: str
|
|
expires_at: str
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Mandate:
|
|
"""Immutable bounded-autonomy mandate for one live broker channel.
|
|
|
|
Loaded read-only at session boot from the user-side protected store. The
|
|
agent loop has no constructor or write path to this object (see §2).
|
|
|
|
Attributes:
|
|
schema_version: ``MANDATE_SCHEMA_VERSION`` at write time; gate refuses
|
|
to operate on an unknown future version (fail-closed).
|
|
hard_caps: Layer (a) quantitative ceilings.
|
|
universe: Layer (b) discovery universe.
|
|
consent: Provenance/consent metadata.
|
|
flatten_on_halt: Whether a kill-switch trip should flatten open
|
|
positions (submit closing orders) in addition to cancelling resting
|
|
orders. ``False`` (the default, and the value an old ``mandate.json``
|
|
lacking this field loads as) means cancel-only — the safe default.
|
|
``True`` is an explicit per-mandate opt-in the user makes at commit.
|
|
Read by ``src.live.runtime.flatten`` on a halt trip (SPEC §7.5 #6
|
|
"optionally, per mandate").
|
|
"""
|
|
|
|
schema_version: int
|
|
hard_caps: HardCaps
|
|
universe: UniverseConstraint
|
|
consent: ConsentMeta
|
|
flatten_on_halt: bool = False
|