rpc

package
v2.8.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 7, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package rpc defines the stable method names, envelopes, and typed payloads shared by the daemon and its CLI, MCP, and app adapters.

The daemon protocol is custom newline-delimited JSON, not JSON-RPC 2.0. Each request and response is one JSON object. An id correlates replies, ok selects either result or error, and a streaming response emits frame objects followed by an end marker. Types in this package are transport contracts; runtime and broker authority remain in the daemon.

Index

Constants

View Source
const (
	// AlertCandidateSnapshotVersion identifies a stable wire schema.
	AlertCandidateSnapshotVersion = risk.AlertCandidateSnapshotVersion

	AlertSourceStress         = risk.AlertSourceStress
	AlertSourceRegime         = risk.AlertSourceRegime
	AlertSourceRulebook       = risk.AlertSourceRulebook
	AlertSourceRiskPolicy     = risk.AlertSourceRiskPolicy
	AlertSourceProtection     = risk.AlertSourceProtection
	AlertSourceOrderIntegrity = risk.AlertSourceOrderIntegrity
	AlertSourceReconciliation = risk.AlertSourceReconciliation
	AlertSourceGovernance     = risk.AlertSourceGovernance
	AlertSourceDataHealth     = risk.AlertSourceDataHealth
	AlertSourceDelivery       = risk.AlertSourceDelivery

	AlertKindMarketState             = risk.AlertKindMarketState
	AlertKindPortfolioRisk           = risk.AlertKindPortfolioRisk
	AlertKindMarginSafety            = risk.AlertKindMarginSafety
	AlertKindDrawdown                = risk.AlertKindDrawdown
	AlertKindProtectionGap           = risk.AlertKindProtectionGap
	AlertKindOrderIntegrity          = risk.AlertKindOrderIntegrity
	AlertKindReconciliationException = risk.AlertKindReconciliationException
	AlertKindGovernance              = risk.AlertKindGovernance
	AlertKindPolicyDrift             = risk.AlertKindPolicyDrift
	AlertKindDataHealth              = risk.AlertKindDataHealth
	AlertKindDeliveryHealth          = risk.AlertKindDeliveryHealth

	AlertEpisodeOpen      = risk.AlertEpisodeOpen
	AlertEpisodeEscalated = risk.AlertEpisodeEscalated
	AlertEpisodeRecovered = risk.AlertEpisodeRecovered

	AlertSeverityObserve = risk.AlertSeverityObserve
	AlertSeverityWatch   = risk.AlertSeverityWatch
	AlertSeverityAct     = risk.AlertSeverityAct
	AlertSeverityUrgent  = risk.AlertSeverityUrgent

	AlertPresentationPortfolioStress                  = risk.AlertPresentationPortfolioStress
	AlertPresentationMarginCushion                    = risk.AlertPresentationMarginCushion
	AlertPresentationRegimeMarketStress               = risk.AlertPresentationRegimeMarketStress
	AlertPresentationRulebookSingleNameExposure       = risk.AlertPresentationRulebookSingleNameExposure
	AlertPresentationRulebookOptionLinePremium        = risk.AlertPresentationRulebookOptionLinePremium
	AlertPresentationRulebookCashSellOnly             = risk.AlertPresentationRulebookCashSellOnly
	AlertPresentationRulebookExtrinsicBudget          = risk.AlertPresentationRulebookExtrinsicBudget
	AlertPresentationRulebookExpiryRunway             = risk.AlertPresentationRulebookExpiryRunway
	AlertPresentationRulebookCatalystCoverage         = risk.AlertPresentationRulebookCatalystCoverage
	AlertPresentationRulebookOverwriteEarnings        = risk.AlertPresentationRulebookOverwriteEarnings
	AlertPresentationRulebookEarningsSizeFreeze       = risk.AlertPresentationRulebookEarningsSizeFreeze
	AlertPresentationRulebookRedOnGreen               = risk.AlertPresentationRulebookRedOnGreen
	AlertPresentationRulebookWinnerTrim               = risk.AlertPresentationRulebookWinnerTrim
	AlertPresentationRulebookGreenDayAction           = risk.AlertPresentationRulebookGreenDayAction
	AlertPresentationRulebookHedgeIntegrity           = risk.AlertPresentationRulebookHedgeIntegrity
	AlertPresentationRulebookExitDiscipline           = risk.AlertPresentationRulebookExitDiscipline
	AlertPresentationRulebookFXExposure               = risk.AlertPresentationRulebookFXExposure
	AlertPresentationProtectionOrphanedOrder          = risk.AlertPresentationProtectionOrphanedOrder
	AlertPresentationProtectionReconciliationRequired = risk.AlertPresentationProtectionReconciliationRequired
	AlertPresentationOrderIntegrityMismatch           = risk.AlertPresentationOrderIntegrityMismatch
	AlertPresentationDataHealthGateway                = risk.AlertPresentationDataHealthGateway
	AlertPresentationDataHealthStorage                = risk.AlertPresentationDataHealthStorage
	AlertPresentationDataHealthProposals              = risk.AlertPresentationDataHealthProposals
	AlertPresentationDataHealthOpportunities          = risk.AlertPresentationDataHealthOpportunities
	AlertPresentationDataHealthDataFarms              = risk.AlertPresentationDataHealthDataFarms
	AlertPresentationDataHealthRegime                 = risk.AlertPresentationDataHealthRegime
	AlertPresentationDataHealthGamma                  = risk.AlertPresentationDataHealthGamma
	AlertPresentationDataHealthQuality                = risk.AlertPresentationDataHealthQuality
	AlertPresentationRiskPolicyLimitWouldBlock        = risk.AlertPresentationRiskPolicyLimitWouldBlock
	AlertPresentationRiskPolicyDrawdownLatched        = risk.AlertPresentationRiskPolicyDrawdownLatched
	AlertPresentationRiskPolicyDrift                  = risk.AlertPresentationRiskPolicyDrift
	AlertPresentationReconciliationDue                = risk.AlertPresentationReconciliationDue
	AlertPresentationReconciliationException          = risk.AlertPresentationReconciliationException
	AlertPresentationReconciliationConfirmedFlow      = risk.AlertPresentationReconciliationConfirmedFlow
	AlertPresentationGovernanceMonthlyPulse           = risk.AlertPresentationGovernanceMonthlyPulse
	AlertPresentationDeliveryHealth                   = risk.AlertPresentationDeliveryHealth
	AlertPresentationRulebookLegacyCondition          = risk.AlertPresentationRulebookLegacyCondition
	AlertPresentationRiskPolicyLegacyCondition        = risk.AlertPresentationRiskPolicyLegacyCondition
	AlertPresentationReconciliationLegacyCondition    = risk.AlertPresentationReconciliationLegacyCondition
	AlertPresentationGovernanceLegacyCondition        = risk.AlertPresentationGovernanceLegacyCondition

	AlertEvidenceCurrent     = risk.AlertEvidenceCurrent
	AlertEvidencePartial     = risk.AlertEvidencePartial
	AlertEvidenceStale       = risk.AlertEvidenceStale
	AlertEvidenceUnavailable = risk.AlertEvidenceUnavailable
	AlertEvidenceError       = risk.AlertEvidenceError

	AlertDestinationMonitor = risk.AlertDestinationMonitor
	AlertDestinationAlerts  = risk.AlertDestinationAlerts
	AlertDestinationBrief   = risk.AlertDestinationBrief

	AlertCoverageComplete    = risk.AlertCoverageComplete
	AlertCoveragePartial     = risk.AlertCoveragePartial
	AlertCoverageUnavailable = risk.AlertCoverageUnavailable

	AlertCoverageCurrent = risk.AlertCoverageCurrent
	AlertCoverageStale   = risk.AlertCoverageStale
	AlertCoverageUnknown = risk.AlertCoverageUnknown

	AlertSnapshotClear   = risk.AlertSnapshotClear
	AlertSnapshotActive  = risk.AlertSnapshotActive
	AlertSnapshotUnknown = risk.AlertSnapshotUnknown
)

Alert-candidate constants re-export the pure risk vocabulary unchanged so RPC adapters and risk evaluation share one set of wire values.

View Source
const (
	// MethodBriefSnapshot composes the operator's daily brief. It is a pure
	// read: callers do not supply an origin and the daemon must not stamp,
	// journal, or advance any runtime clock while serving it.
	MethodBriefSnapshot = "brief.snapshot"
	// MethodBriefAck records the human attestation associated with a rendered
	// brief. The daemon accepts human origins only.
	MethodBriefAck = "brief.ack"

	// BriefStatusOK is the normal member of the brief row status vocabulary.
	// Brief row statuses separate risk conditions from data conditions:
	// attention means the underlying VALUES describe a state a trader must
	// look at (latched drawdown, breached tier, active override); degraded
	// and unavailable describe input quality only and must never be used to
	// signal a risk condition, nor vice versa.
	BriefStatusOK          = "ok"
	BriefStatusAttention   = "attention"
	BriefStatusDegraded    = "degraded"
	BriefStatusUnavailable = "unavailable"

	// BriefKindMorning identifies the pre-trade morning brief.
	BriefKindMorning = "morning"
	// BriefKindEOD identifies the end-of-day brief.
	BriefKindEOD = "eod"
	// BriefKindMonthly identifies the monthly governance pulse.
	BriefKindMonthly = "monthly"

	// BriefMonthlyPulseNotDue means the monthly pulse has no current action.
	BriefMonthlyPulseNotDue = "not_due"
	// BriefMonthlyPulseDue means the current pulse awaits completion.
	BriefMonthlyPulseDue = "due"
	// BriefMonthlyPulseCompleted means the current pulse has valid evidence.
	BriefMonthlyPulseCompleted = "completed"
	// BriefMonthlyPulseBlocked means completion prerequisites are unavailable.
	BriefMonthlyPulseBlocked = "blocked"

	// BriefAckEvidenceRender proves only that a paired surface rendered the brief;
	// origin alone must never be treated as stronger proof of human attention.
	BriefAckEvidenceRender = risk.MonthlyPulseEvidenceRender
)

Brief constants define the daemon methods and the bounded status, kind, monthly-pulse, and acknowledgement vocabularies carried on the wire.

View Source
const (
	BriefRunRoleFigure = "figure"
	BriefRunRoleWatch  = "watch"
	BriefRunRoleAct    = "act"
)

Brief narrative run roles. A run carries text plus at most one role, and a role is a claim about the underlying row, not a styling hint: figure marks a first-class served number, watch and act may appear only on clauses whose own row status or served severity is watch- or act-class. Surfaces map the roles to their own register and must never re-derive them.

View Source
const (
	// ViewFull requests the complete result shape.
	ViewFull = "full"
	// ViewAlert requests the compact Stress alert projection.
	ViewAlert = "alert"
	// ViewDetail requests expanded detail from a supporting surface.
	ViewDetail = "detail"
	// ViewMonitor requests the compact regime-monitor projection.
	ViewMonitor = "monitor"
	// ViewRisk requests the compact positions-risk projection.
	ViewRisk = "risk"
)
View Source
const (

	// RegimeFingerprintVersion identifies a semantic fingerprint projection.
	RegimeFingerprintVersion = "regime-fp-v2"
	// AccountFingerprintVersion identifies a semantic fingerprint projection.
	AccountFingerprintVersion = "account-fp-v1"
	// PositionsFingerprintVersion identifies a semantic fingerprint projection.
	PositionsFingerprintVersion = "positions-fp-v1"
	// StressFingerprintVersion identifies a semantic fingerprint projection.
	StressFingerprintVersion = "stress-fp-v2"
)

Fingerprint versions identify the semantic projection used for each source. They are not data-freshness or authority versions.

View Source
const (
	LifecycleQuiet           = "quiet"
	LifecycleEarlyWarning    = "early_warning"
	LifecycleConfirmedStress = "confirmed_stress"
	LifecyclePanic           = "panic"
	LifecycleStabilization   = "stabilization"
	LifecycleOpportunity     = "opportunity"
	LifecycleDataQuality     = "data_quality"

	LifecycleTimingForwardWarning = "forward_warning"
	LifecycleTimingContemporary   = "contemporaneous"
	LifecycleTimingRecovery       = "recovery"
	LifecycleTimingDataQuality    = "data_quality"

	FingerprintStabilitySemanticBuckets = "semantic_buckets_only"
)

Lifecycle stages, timing classes, and fingerprint stability are the stable vocabulary used by regime and Stress monitor projections.

View Source
const (
	SourceStatusOK       = "ok"
	SourceStatusPartial  = "partial"
	SourceStatusStale    = "stale"
	SourceStatusUnknown  = "unknown"
	SourceStatusDegraded = "degraded"
)

Source-health statuses distinguish complete observations from partial, stale, unknown, and degraded evidence.

View Source
const (
	RegimeToneNormal      = "normal"
	RegimeToneWatch       = "watch"
	RegimeToneStress      = "stress"
	RegimeToneRiskOff     = "risk_off"
	RegimeToneDataQuality = "data_quality"
)

Regime tones are presentation classifications derived from lifecycle state.

View Source
const (
	SourceFailureTimeout                = "timeout"
	SourceFailureDNSFailed              = "dns_failed"
	SourceFailureConnectionRefused      = "connection_refused"
	SourceFailureTransportFailed        = "transport_failed"
	SourceFailureProtocolRejected       = "protocol_rejected"
	SourceFailureAuthenticationRejected = "authentication_rejected"
	SourceFailureInvalidPayload         = "invalid_payload"
	SourceFailureAuthorityWriteFailed   = "authority_write_failed"
	SourceFailureNotEntitled            = "not_entitled"
	SourceFailureGatewayUnavailable     = "gateway_unavailable"
	SourceFailureNoData                 = "no_data"
	SourceFailurePacing                 = "pacing"
	SourceFailureContractUnavailable    = "contract_unavailable"

	SourceFailureStageFTPControlConnect    = "ftp_control_connect"
	SourceFailureStageFTPGreeting          = "ftp_greeting"
	SourceFailureStageFTPAuthenticate      = "ftp_authenticate"
	SourceFailureStageFTPPassiveNegotiate  = "ftp_passive_negotiate"
	SourceFailureStageFTPPassiveConnect    = "ftp_passive_connect"
	SourceFailureStageFTPRetrieve          = "ftp_retrieve"
	SourceFailureStageBorrowParse          = "borrow_parse"
	SourceFailureStageNasdaqRequest        = "nasdaq_request"
	SourceFailureStageNasdaqDecode         = "nasdaq_decode"
	SourceFailureStageNasdaqSchema         = "nasdaq_schema"
	SourceFailureStageWSHContractResolve   = "wsh_contract_resolve"
	SourceFailureStageWSHMetadata          = "wsh_metadata"
	SourceFailureStageWSHEvent             = "wsh_event"
	SourceFailureStageWSHDecode            = "wsh_decode"
	SourceFailureStageHistoricalFeeRequest = "historical_fee_request"
	SourceFailureStageHistoricalFeeDecode  = "historical_fee_decode"
	SourceFailureStageAuthorityPersist     = "authority_persist"
)

Source-failure codes and stages are the allowlisted cross-surface vocabulary for redacted transport, parser, provider, and authority failures.

View Source
const (
	SourceRefreshCurrent            = "current"
	SourceRefreshNotDue             = "not_due"
	SourceRefreshPending            = "pending"
	SourceRefreshFetchFailed        = "fetch_failed"
	SourceRefreshFetchFailedBackoff = "fetch_failed_backoff"
)

Source-refresh states describe scheduler progress separately from the observation's evidence quality.

View Source
const (
	QuoteExpectationNone = "none"

	QuoteExpectationReasonTerminal = "terminal_non_reporting"
)

A data-quality signal claims that reality is unobserved. Where reality is observed to be nothing — a cancelled equity, a defunct issuer — that is a fact, not a gap. QuoteExpectationNone carries that distinction across every surface so each consumer does not have to re-derive it from warning codes. Only the broker's terminal non-reporting verdict may mint it; numeric zeros in account rows are a data-quality warning, never expectation authority.

View Source
const (
	MethodMarketEventsSnapshot = "market_events.snapshot"

	MarketEventsKind = "ibkr.market_events"
	// MarketEventsSchemaVersion identifies a stable wire schema.
	MarketEventsSchemaVersion = "market-events-v1"
	// MarketEventsFingerprintVersion identifies a semantic fingerprint projection.
	MarketEventsFingerprintVersion = "market-events-fp-v3"

	MarketEventBorrowInventoryTight = "borrow_inventory_tight"
	MarketEventBorrowFeeExtreme     = "borrow_fee_extreme"
	MarketEventRegSHOThreshold      = "reg_sho_threshold"
	MarketEventLULDPause            = "luld_pause"
	MarketEventLULDRecent           = MarketEventLULDPause
	MarketEventHaltRegulatoryOrNews = "halt_regulatory_or_news"

	MarketEventStatusActive   = "active"
	MarketEventStatusRecent   = "recent"
	MarketEventStatusInactive = "inactive"
	MarketEventStatusUnknown  = "unknown"
	MarketEventStatusStale    = "stale"
	MarketEventStatusDegraded = "degraded"

	MarketEventSeverityContext = "context"
	MarketEventSeverityWatch   = "watch"
	MarketEventSeverityAct     = "act"
	MarketEventSeverityBlock   = "block"

	MarketEventRoleContext          = "context"
	MarketEventRoleProposalModifier = "proposal_modifier"
	MarketEventRoleHardBlocker      = "hard_blocker"

	BorrowFeeCoverageGlobal        = "global"
	BorrowFeeCoveragePortfolioOnly = "portfolio_only"

	BorrowFeeCoverageObserved     = "observed"
	BorrowFeeCoverageMissing      = "missing"
	BorrowFeeCoverageNotEntitled  = "not_entitled"
	BorrowFeeCoverageUnavailable  = "unavailable"
	BorrowFeeCoverageStale        = "stale"
	BorrowFeeCoverageScaleUnknown = "scale_unverified"

	BorrowFeeSourceBulkShortStock = "ibkr_short_stock_availability"
	BorrowFeeSourceTWSHistorical  = "ibkr_tws_historical"
	BorrowFeeDataTypeBulkFeeRate  = "bulk_fee_rate"
	BorrowFeeDataTypeHistorical   = "FEE_RATE"

	BorrowFeeEntitlementObserved    = "observed"
	BorrowFeeEntitlementNotEntitled = "not_entitled"
	BorrowFeeEntitlementUnknown     = "unknown"

	BorrowFeeScalePercentAnnualized = "percent_annualized"
	BorrowFeeScaleUnverified        = "unverified"
)

Market-event method, schema, kind, flag, status, severity, and role constants form the stable allowlisted vocabulary of the market-events wire contract.

View Source
const (
	// MethodNudgesSnapshot returns the current redacted advisory snapshot.
	MethodNudgesSnapshot = "nudges.snapshot"
	// MethodNudgesCutoverReview records authenticated paired-device review
	// evidence; it does not complete a pulse or authorize broker activity.
	MethodNudgesCutoverReview = "nudges.cutover_review"
)
View Source
const (
	NudgeKindReconcileDue       = risk.NudgeKindReconcileDue
	NudgeKindReconcileException = risk.NudgeKindReconcileException
	NudgeKindShadowWouldBlock   = risk.NudgeKindShadowWouldBlock
	NudgeKindDrawdownLatched    = risk.NudgeKindDrawdownLatched
	NudgeKindPolicyDrift        = risk.NudgeKindPolicyDrift
	NudgeKindConfirmedFlow      = risk.NudgeKindConfirmedFlow
	NudgeKindMonthlyPulse       = risk.NudgeKindMonthlyPulse

	NudgeStateDueSoon  = risk.NudgeStateDueSoon
	NudgeStateOverdue  = risk.NudgeStateOverdue
	NudgeStateOpen     = risk.NudgeStateOpen
	NudgeStateObserved = risk.NudgeStateObserved
	NudgeStateDue      = risk.NudgeStateDue

	NudgeSeverityWatch = risk.NudgeSeverityWatch
	NudgeSeverityAct   = risk.NudgeSeverityAct

	NudgeDestinationMonitor = risk.NudgeDestinationMonitor
	NudgeDestinationAlerts  = risk.NudgeDestinationAlerts
	NudgeDestinationBrief   = risk.NudgeDestinationBrief

	NudgeDrawdownTierBlock = risk.CapitalTierBlock
)

Nudge candidate kinds, states, severities, destinations, and the blocking drawdown tier mirror the pure risk contract.

View Source
const (
	NudgeInputStatusOK          = "ok"
	NudgeInputStatusInactive    = "inactive"
	NudgeInputStatusUnapproved  = "unapproved"
	NudgeInputStatusStale       = "stale"
	NudgeInputStatusUnavailable = "unavailable"
	NudgeInputStatusError       = "error"

	NudgeAggregateReady      = "ready"
	NudgeAggregateSuppressed = "suppressed"
	NudgeAggregateDegraded   = "degraded"
)

Nudge input and aggregate health values distinguish ready evidence from inactive, suppressed, stale, unavailable, and erroneous inputs.

View Source
const (
	NudgeHealthReasonNone                       = ""
	NudgeHealthReasonPolicyUnapproved           = "policy_unapproved"
	NudgeHealthReasonCadenceUnapproved          = "cadence_unapproved"
	NudgeHealthReasonEvidenceStale              = "evidence_stale"
	NudgeHealthReasonSourceUnavailable          = "source_unavailable"
	NudgeHealthReasonEvaluationError            = "evaluation_error"
	NudgeHealthReasonCoverageUnavailable        = "coverage_unavailable"
	NudgeHealthReasonCutoverReviewRequired      = "cutover_review_required"
	NudgeHealthReasonProcessRemindersNotEnabled = "process_reminders_not_enabled"
	NudgeHealthReasonInvalid                    = "invalid_health"
)

Nudge source-health reasons are allowlisted tokens. Raw errors, paths, upstream fingerprints, and broker text do not belong on this contract.

View Source
const (
	MethodOpportunitiesStatus          = "opportunities.status"
	MethodOpportunitiesSnapshot        = "opportunities.snapshot"
	MethodOpportunitiesRefresh         = "opportunities.refresh"
	MethodOpportunitiesPreviewExercise = "opportunities.preview_exercise"
	MethodOpportunitiesSubmitExercise  = "opportunities.submit_exercise"
	MethodOpportunitiesIgnore          = "opportunities.ignore"

	// OpportunityPolicyFingerprintVersion identifies a semantic fingerprint projection.
	OpportunityPolicyFingerprintVersion = "opportunity-policy-fp-v1"

	OpportunityPolicyStatusActive   = "active"
	OpportunityPolicyStatusDefault  = "default"
	OpportunityPolicyStatusDrift    = "drift"
	OpportunityPolicyStatusError    = "error"
	OpportunityPolicyStatusDisabled = "disabled"

	OpportunitySnapshotKind = "ibkr.opportunity_snapshot"
	// OpportunitySnapshotSchemaVersion identifies a stable wire schema.
	OpportunitySnapshotSchemaVersion = "opportunity-snapshot-v1"
	OpportunityStatusKind            = "ibkr.opportunity_status"

	OpportunityBucketOptionExercise = "option_exercise"

	OpportunityStateGenerated = "generated"
	OpportunityStateBlocked   = "blocked"

	OpportunityActionExercise = "EXERCISE"

	ExerciseActionExercise = 1
	ExerciseActionLapse    = 2

	ExercisePositionEffectClose    = "close"
	ExercisePositionEffectReduce   = "reduce"
	ExercisePositionEffectOpen     = "open"
	ExercisePositionEffectIncrease = "increase"
	ExercisePositionEffectFlip     = "flip"
	ExercisePositionEffectUnknown  = "unknown"

	ExerciseRiskChangeClosed    = "closed"
	ExerciseRiskChangeReduced   = "reduced"
	ExerciseRiskChangeOpened    = "opened"
	ExerciseRiskChangeIncreased = "increased"
	ExerciseRiskChangeFlipped   = "flipped"
	ExerciseRiskChangeUnknown   = "unknown"
)

Opportunity method names and allowlisted policy, snapshot, action, state, position-effect, and risk-change values form a stable wire vocabulary.

View Source
const (
	ProtectionCoverageStateCovered           = "covered"
	ProtectionCoverageStatePartial           = "partial"
	ProtectionCoverageStateUnprotected       = "unprotected"
	ProtectionCoverageStateOrphanedOrder     = "orphaned_order"
	ProtectionCoverageStateReconcileRequired = "reconcile_required"
	ProtectionCoverageStateUnknown           = "unknown"
	// ProtectionCoverageStateNotProtectable marks a defunct or unquoted
	// holding: it has no mark to stop out against, so the proposal engine
	// already declines to propose for it. Counting such a row as unprotected
	// raises an alarm the protection panel cannot answer.
	ProtectionCoverageStateNotProtectable = "not_protectable"
)

Protection-coverage states distinguish reconciled coverage from partial, absent, orphaned, uncertain, reconciliation-required, and unprotectable observations.

View Source
const (
	// MethodReconSnapshot regenerates and returns the reconciliation
	// report from retained Flex statements and the declared capital-event
	// ledger. Params may request a background statement fetch.
	MethodReconSnapshot = "recon.snapshot"
	// MethodReconCheck requests one broker-report check and returns an
	// immediate, typed receipt. It is broker-read-only and never signs off,
	// dismisses an exception, or changes trading controls.
	MethodReconCheck = "recon.check"
	// MethodReconStatus returns only the redacted daily automation state. It
	// deliberately omits report rows, amounts, account data, and identifiers.
	MethodReconStatus = "recon.status"
	// MethodReconBacktest builds the full-window backtest report: every
	// statement flow labeled for the operator's flow-list review, plus the
	// capital-ladder replay over the statement equity series
	// (internal-docs/design/operator-ergonomics.md, accelerated R3 gate).
	// Measurement only — it changes no matching, sign-off, or enforcement.
	MethodReconBacktest = "recon.backtest"
	// MethodReconDismiss records a human resolution for one exception
	// line: reviewed, explained, deliberately not a ledger event.
	MethodReconDismiss = "recon.dismiss"
)
View Source
const (
	// ReconCheckOutcomeStarted means a new asynchronous check was accepted.
	ReconCheckOutcomeStarted = "started"
	// ReconCheckOutcomeAlreadyChecking means an existing check remains active.
	ReconCheckOutcomeAlreadyChecking = "already_checking"
	// ReconCheckOutcomeCooldown means retry is deferred by daemon cadence.
	ReconCheckOutcomeCooldown = "cooldown"
	// ReconCheckOutcomeActionRequired means automation cannot proceed without
	// resolving the redacted status reason.
	ReconCheckOutcomeActionRequired = "action_required"
)
View Source
const (
	ReconReportStateWaiting        = "waiting"
	ReconReportStateDue            = "due"
	ReconReportStateChecking       = "checking"
	ReconReportStateCurrent        = "current"
	ReconReportStateRetryScheduled = "retry_scheduled"
	ReconReportStateActionRequired = "action_required"
	ReconReportStateUnavailable    = "unavailable"

	ReconReportReasonNone                 = ""
	ReconReportReasonBeforeDailyWindow    = "before_daily_window"
	ReconReportReasonCoveragePending      = "coverage_pending"
	ReconReportReasonReportNotReady       = "report_not_ready"
	ReconReportReasonServiceBusy          = "service_busy"
	ReconReportReasonRateLimited          = "rate_limited"
	ReconReportReasonNetworkUnavailable   = "network_unavailable"
	ReconReportReasonFlexDisabled         = "flex_disabled"
	ReconReportReasonQueryMissing         = "query_missing"
	ReconReportReasonTokenMissing         = "token_missing"
	ReconReportReasonTokenInvalid         = "token_invalid"
	ReconReportReasonTokenExpired         = "token_expired"
	ReconReportReasonQueryInvalid         = "query_invalid"
	ReconReportReasonIPRestricted         = "ip_restricted"
	ReconReportReasonServiceInactive      = "service_inactive"
	ReconReportReasonResponseInvalid      = "response_invalid"
	ReconReportReasonReportInvalid        = "report_invalid"
	ReconReportReasonStorageFailed        = "storage_failed"
	ReconReportReasonProjectionFailed     = "projection_failed"
	ReconReportReasonAuthorityUnavailable = "authority_unavailable"

	ReconEvaluationStateWaiting           = "waiting"
	ReconEvaluationStateChecking          = "checking"
	ReconEvaluationStateComplete          = "complete"
	ReconEvaluationStateAttentionRequired = "attention_required"
	ReconEvaluationStateFailed            = "failed"

	ReconEvaluationReasonNone                 = ""
	ReconEvaluationReasonReportPending        = "report_pending"
	ReconEvaluationReasonAccountValuePending  = "account_value_pending"
	ReconEvaluationReasonExceptionsNeedReview = "exceptions_need_review"
	ReconEvaluationReasonAccountValueMismatch = "account_value_mismatch"
	ReconEvaluationReasonEvaluationFailed     = "evaluation_failed"
	ReconEvaluationReasonPolicyUnapproved     = "policy_unapproved"
)

Daily broker-report automation states. These values are deliberately narrow and prose-free so paired surfaces can render their own plain copy without exposing broker responses, local paths, or statement contents.

View Source
const (
	ReconStatusActive      = "active"      // report produced under approved recon keys
	ReconStatusUnapproved  = "unapproved"  // [recon] policy keys missing; no matching possible
	ReconStatusUnavailable = "unavailable" // no retained statements yet
	ReconStatusDegraded    = "degraded"    // report produced but some retained files failed to parse
)

Recon report statuses.

View Source
const (
	ReconMissingFromLedger = "missing_from_ledger"
	ReconLedgerOnly        = "ledger_only"
	ReconAmountMismatch    = "amount_mismatch"
	ReconDateMismatch      = "date_mismatch"
	ReconAmbiguous         = "ambiguous"
	ReconUncategorized     = "uncategorized"
)

Recon exception categories.

View Source
const (
	RegimeCurrencyGradeNone    = "none"
	RegimeCurrencyGradeDegrade = "degrade"
	RegimeCurrencyGradeFatal   = "fatal"
)

Currency grades separate what a defect does to the read: a fatal-grade unit is a data-quality defect, a degrade-grade unit degrades readiness and caps confidence, and the scheduled classes cost nothing.

View Source
const (
	RegimeIndicatorVIXTerm   = "vix_term"
	RegimeIndicatorVolOfVol  = "vol_of_vol"
	RegimeIndicatorHYGSPY    = "hyg_spy"
	RegimeIndicatorCredit    = "credit_spreads"
	RegimeIndicatorFunding   = "funding_stress"
	RegimeIndicatorUSDJPY    = "usdjpy"
	RegimeIndicatorGammaZero = "gamma_zero"
	RegimeIndicatorBreadth   = "breadth"
)

Indicator keys, shared with the daemon streak store and the eligibility gates table. Stable strings — they key persisted state.

View Source
const (
	RegimeClusterEquityVol = iota
	RegimeClusterCredit
	RegimeClusterFunding
	RegimeClusterFX
	RegimeClusterGamma
	RegimeClusterBreadth
)

Cluster indexes for the six-cluster combination. Order is part of the contract (lifecycle evidence and source-health rows iterate it).

View Source
const (
	// MethodRiskPolicySnapshot returns the effective constitution, capital
	// state, drawdown tier, overrides, cadence records, and sibling-policy
	// pin drift. Works without gateway connectivity (state/config-only;
	// the equity observation degrades to the persisted last reading).
	MethodRiskPolicySnapshot = "policy.snapshot"
	// MethodRiskPolicyCapitalEvent declares a capital fact: deposit,
	// withdrawal, or reconcile attestation. Human-only.
	MethodRiskPolicyCapitalEvent = "policy.capital_event"
	// MethodRiskPolicyOverride grants a one-shot, expiring, single-control
	// override. Human-only.
	MethodRiskPolicyOverride = "policy.override"
	// MethodRiskPolicyResetDrawdown clears a latched drawdown block and
	// re-bases the adjusted peak. Human-only.
	MethodRiskPolicyResetDrawdown = "policy.reset_drawdown"
	// MethodRiskPolicyCorrectPeak lowers a corrupted adjusted peak to an
	// evidence-anchored value without touching the drawdown latch.
	// Corrections may only lower the peak; higher peaks are what the
	// observation path is for. Human-only.
	MethodRiskPolicyCorrectPeak = "policy.correct_peak"
	// MethodRiskPolicyArtefact records completion of a declared cadence
	// artefact. Human-only.
	MethodRiskPolicyArtefact = "policy.artefact"
)
View Source
const (
	CapitalFlowSourceDeclared  = "declared"
	CapitalFlowSourceStatement = "statement"
	ReconcileSourceHuman       = "human"
	ReconcileSourceAutomatic   = "automatic"
)

Capital-flow and reconciliation source values distinguish declared facts, broker-statement evidence, and human or automated reconciliation.

View Source
const (
	RiskPolicyStatusActive = "active"
	RiskPolicyStatusAbsent = "absent"
	RiskPolicyStatusDrift  = "drift"
	RiskPolicyStatusError  = "error"
)

Risk-policy statuses include absent because the constitution has no embedded default; a missing file is disclosed rather than silently substituted.

View Source
const (
	MethodAccountSummary      = "account.summary"
	MethodPositionsList       = "positions.list"
	MethodQuoteSnapshot       = "quote.snapshot"
	MethodQuoteSubscribe      = "quote.subscribe"
	MethodChainFetch          = "chain.fetch"
	MethodChainExpiries       = "chain.expiries"
	MethodScanRun             = "scan.run"
	MethodScanList            = "scan.list"
	MethodScanParams          = "scan.params"
	MethodHistoryDaily        = "history.daily"
	MethodTechnical           = "technical.snapshot"
	MethodMarketCalendar      = "market.calendar"
	MethodStatusHealth        = "status.health"
	MethodTradingStatus       = "trading.status"
	MethodTradingPaperSmoke   = "trading.paper_smoke"
	MethodSettingsGet         = "settings.get"
	MethodSettingsUpdate      = "settings.update"
	MethodOrdersOpen          = "orders.open"
	MethodOrdersHistory       = "orders.history"
	MethodOrderStatus         = "order.status"
	MethodOrderPreview        = "order.preview"
	MethodBreadthSPX          = "breadth.spx"
	MethodGammaZeroSPX        = "gamma.zero_spx"
	MethodRegimeSnapshot      = "regime.snapshot"
	MethodCancel              = "cancel"
	MethodOrderPlace          = "order.place"
	MethodOrderModify         = "order.modify"
	MethodOrderCancel         = "order.cancel"
	MethodPurgeStatus         = "purge.status"
	MethodPurgeExecute        = "purge.execute"
	MethodPurgeRestorePreview = "purge.restore.preview"
	MethodPurgeRestoreExecute = "purge.restore.execute"
)

Daemon method names are stable wire identifiers shared by every adapter.

View Source
const (
	CodeUnknownMethod      = "unknown_method"
	CodeBadRequest         = "bad_request"
	CodeDaemonUnavailable  = "daemon_unavailable"
	CodeGatewayUnavailable = "gateway_unavailable"
	CodeSymbolInactive     = "symbol_inactive"
	CodeTimeout            = "timeout"
	CodeTradingDisabled    = "trading_disabled"
	CodeInternal           = "internal"
)

Error codes classify terminal request failures carried by Error.Code.

View Source
const (
	MarketDataLive          = "live"
	MarketDataFrozen        = "frozen"
	MarketDataDelayed       = "delayed"
	MarketDataDelayedFrozen = "delayed-frozen"
	MarketDataPrevClose     = "prev_close"
	MarketDataClosed        = "closed"
)

MarketDataType values carried on Quote.DataType, Frame.DataType, and ChainResult.DataType. IBKR's tickMarketDataType message (58) maps gateway feed state into one of these strings; adapters render a badge based on the value. HealthResult.DataType remains on the wire shape (omitempty) for renderer-fallback compatibility but is no longer written by the daemon: status has no per-request data type to report.

Empty string means "the gateway hasn't sent a notice yet" — typically a few hundred ms after a fresh subscription. Treated as live for rendering purposes (see IsLiveDataType).

View Source
const (
	FrameErrGatewayLost          = "gateway_lost"
	FrameErrEntitlementLost      = "entitlement_lost"
	FrameErrSubscriptionRejected = "subscription_rejected"
	FrameErrDaemonShutdown       = "daemon_shutdown"
)

Frame-level error codes used in FrameError.Code. These are terminal: a frame carrying any of these is the last frame the consumer will receive on its subscription. Distinct from the request-envelope error codes because the wire shape (frame, not Error) and lifecycle (mid-stream vs synchronous) are different concerns.

View Source
const (
	SecTypeStock  = "STOCK"
	SecTypeOption = "OPTION"
	SecTypeFuture = "FUTURE"
	SecTypeIndex  = "INDEX"
)

SecType values carried on PositionView.SecType. The daemon maps IBKR's raw three-letter SecType codes ("STK", "OPT") onto the canonical wire values below in positionSecType — full words, not the short forms IBKR accepts on ContractParams (a different path; see the doc-comment there).

Compare against these constants in renderers and filters rather than literal strings. The constants prevent adapters from drifting between broker and canonical spellings.

View Source
const (
	// GammaZeroStatusCold — no usable last-good exists and no compute is in
	// flight. This can persist off-hours because automatic refresh is not due.
	// Distinct from Computing, which will resolve without another kick.
	GammaZeroStatusCold = "cold"
	// GammaZeroStatusComputing — a background compute is in flight and no
	// usable last-good can be served; the EtaSeconds / Progress fields carry
	// refresh hints. Callers who can wait may set GammaZeroSPXParams.WaitMs >
	// 0 on the request to block up to that budget for the result.
	GammaZeroStatusComputing = "computing"
	// GammaZeroStatusReady — Result is the served successful last-good. During
	// RTH a newer calculation may refresh behind it; off-hours it can be
	// retained as typed closed-session context.
	GammaZeroStatusReady = "ready"
	// GammaZeroStatusError — the last compute failed; Error carries the
	// classified reason. Callers retry by re-invoking the method.
	GammaZeroStatusError = "error"
)

GammaZeroSPXStatus values are returned on GammaZeroSPXResult.Status and drive the dashboard generator's "render the number" vs "render a loading state" choice. The compute is heavy (several minutes against hundreds of option legs) and runs on a daemon-internal goroutine, so the wire shape always carries a state. The daemon normally prewarms after gateway startup. Successful last-good data is served while a newer compute refreshes behind it after the 15-minute RTH soft TTL; outside regular option hours automatic refresh is not due.

The four states mirror BreadthState's cold/computing/ready/error semantics so consumers can branch on Status uniformly across the two state-machine engines.

View Source
const (
	GammaZeroScopeSPY      = "spy"
	GammaZeroScopeSPX      = "spx"
	GammaZeroScopeCombined = "spy+spx"
)

Scope values for GammaZeroSPXParams.Scope. Empty Scope defaults to "spy+spx". The combined scope prefers fresh SPY+SPX; when a fresh SPX slice is unavailable it may compose fresh/cached SPY with the last successful SPX slice and mark the result degraded. If no usable SPX slice exists, combined degrades to SPY-only with a structured warning.

View Source
const (
	GammaRankabilityRankable    = "rankable"
	GammaRankabilityContextOnly = "context_only"
	GammaRankabilityBlocked     = "blocked"
	GammaRankabilityUnavailable = "unavailable"

	GammaQualityGatePass    = "pass"
	GammaQualityGateContext = "context"
	GammaQualityGateBlock   = "block"

	// GammaQualityGateFreshness, GammaQualityGateSPXCoverage, and
	// GammaFreshnessSessionMismatch cross the package boundary: the regime
	// input-currency model asks whether a non-rankable gamma result is blocked
	// on its publication cadence alone.
	GammaQualityGateFreshness     = "freshness"
	GammaQualityGateSPXCoverage   = "spx_coverage"
	GammaFreshnessSessionMismatch = "session_mismatch"
)

Gamma rankability and quality-gate values keep displayable context separate from evidence that may participate in downstream regime decisions.

View Source
const (
	RegimeStatusOK          = "ok"
	RegimeStatusStale       = "stale"
	RegimeStatusComputing   = "computing"
	RegimeStatusUnavailable = "unavailable"
	RegimeStatusError       = "error"
)

RegimeIndicatorStatus is the high-level availability/freshness state for one row of the regime snapshot. Renderers branch on it; the daemon never derives green/yellow/red status from raw values (the spec calls those thresholds user-tunable). Specific values:

  • "ok" — the indicator carries a real, fresh measurement
  • "stale" — measurement returned but the gateway labeled it delayed/frozen; renderer should dim
  • "computing" — a heavy compute is in-flight with no usable served value yet; the daemon normally prewarms gamma after startup
  • "unavailable" — IBKR doesn't carry the feed on this account; the `notes` field explains why and what to do
  • "error" — fetch failed; `error_message` carries the reason
View Source
const (
	FreshnessLive     = "live"
	FreshnessFrozen   = "frozen"
	FreshnessDerived  = "derived"
	FreshnessModelled = "modelled"

	ConfidenceFirm     = "firm"
	ConfidenceEstimate = "estimate"
	ConfidenceProxy    = "proxy"
)

Quality vocabulary separates observation provenance from confidence; these values are descriptive and do not independently establish authority.

View Source
const (
	RegimeFreshnessFresh   = "fresh"
	RegimeFreshnessNotDue  = "not_due"
	RegimeFreshnessPending = "pending"
	RegimeFreshnessStale   = "stale"
	RegimeFreshnessOverdue = "overdue"
)

Regime freshness values compare a row with its native publication cadence. Only fresh is confirmation-eligible; the rest are context or defect (internal-docs/design/regime-input-currency.md).

  • fresh — a current observation under the row's own cadence.
  • not_due — the source's publication window is closed, so no newer observation can exist yet.
  • pending — the current period's refresh is in flight, evidenced by a typed marker, inside a bounded window anchored to the period start.
  • stale — a known value older than its window, or a due refresh that failed, inside an explicit tolerance.
  • overdue — a newer observation should exist and no bounded excuse applies; also the fail-closed class for missing or untyped evidence.
View Source
const (
	VIX3MSourceGateway  = "gateway"
	VIX3MSourceOfficial = "cboe_official_close"
)

Provenance of the served VIX3M leg.

View Source
const (
	VIX3MCrossCheckAgree              = "agree"
	VIX3MCrossCheckOfficialOnly       = "official_only"
	VIX3MCrossCheckPendingPublication = "pending_publication"
	VIX3MCrossCheckDisagree           = "disagree"
	VIX3MCrossCheckUnverified         = "unverified"
)

VIX3M cross-source verdicts. In frozen mode the broker re-sends its last known value on request, so arrival time says nothing about a value's age and an index carries no trade timestamp. Cboe's dated close is therefore the only thing that establishes an off-window leg's vintage, and these name what that comparison found:

  • agree: both sources described the last completed publication window and matched.
  • official_only: Cboe covered that window and the broker produced no VIX3M at all, so the official close IS the leg and nothing was compared.
  • pending_publication: Cboe has not published the last completed window's close yet — it lands after the session ends. The broker leg stands in, bounded to one session.
  • disagree: both described the same window and differed. The broker leg is not the close it claims to be: a stuck subscription, a lapsed market-data entitlement, or a contract id that no longer resolves to VIX3M.
  • unverified: no usable official close within one session of the last completed window, so nothing corroborates the broker leg.
View Source
const (
	DataCadenceCurrent       = "current"
	DataCadenceNotDue        = "not_due"
	DataCadenceMissedSession = "missed_session"
	DataCadenceNoLastGood    = "no_last_good"
	DataCadenceUnknown       = "unknown"
)

Data cadence values summarize whether a decision surface has current, expected-but-not-due, missed, absent, or unclassified evidence.

View Source
const (
	GatewayPhaseConnecting      = "connecting"
	GatewayPhasePortDown        = "port_down"
	GatewayPhaseAPINotReady     = "api_not_ready"
	GatewayPhaseBackendLinkDown = "backend_link_down"
	GatewayPhaseReady           = "ready"
)

Gateway phases distinguish the local TWS/Gateway API socket from the gateway's own upstream broker link. Connected remains the compatibility readiness bit used by existing consumers; GatewayPhase is the diagnostic authority and must not be inferred from LastError prose.

View Source
const (
	MarketDataAccessNotSubscribed = "not_subscribed"
	MarketDataAccessRejected      = "rejected"
)

Market-data access reasons classify a rejection by IBKR code alone.

View Source
const (
	AccountModeUnknown = "unknown"
	AccountModePaper   = "paper"
	AccountModeLive    = "live"
)

Account modes classify the connected broker account; they do not describe market-data freshness or grant broker-write authority.

View Source
const (
	TradingMCPDisabled = "disabled"

	TradingLiveOverrideBlocked = "blocked"
	TradingLiveOverrideReady   = "ready"
)

Trading status values describe MCP exposure and live-override readiness; readiness is local evidence, not broker permission or submit authority.

View Source
const (
	OrderActionBuy  = "BUY"
	OrderActionSell = "SELL"

	OrderTypeLMT        = "LMT"
	OrderTypeTRAIL      = "TRAIL"
	OrderTypeTRAILLIMIT = "TRAIL LIMIT"

	OrderTIFDay = "DAY"
	// OrderTIFGTC persists until filled or cancelled. Accepted for broker
	// trail orders only: a protective stop that dies at the session close
	// is absent exactly when the overnight gap it covers opens up.
	OrderTIFGTC = "GTC"

	OrderStrategyPatientLimit  = "patient-limit"
	OrderStrategyExplicitLimit = "explicit-limit"
	OrderStrategyBrokerTrail   = "broker-trail"

	OrderTrailBasisInstrumentPrice = "instrument_price"
	OrderTrailOffsetPercent        = "percent"
	OrderTrailOffsetAmount         = "amount"

	// OrderTriggerMethodDefault is an allowlisted broker trigger method.
	OrderTriggerMethodDefault = 0
	// OrderTriggerMethodDoubleBidAsk is an allowlisted broker trigger method.
	OrderTriggerMethodDoubleBidAsk = 1
	// OrderTriggerMethodLast is an allowlisted broker trigger method.
	OrderTriggerMethodLast = 2
	// OrderTriggerMethodDoubleLast is an allowlisted broker trigger method.
	OrderTriggerMethodDoubleLast = 3
	// OrderTriggerMethodBidAsk is an allowlisted broker trigger method.
	OrderTriggerMethodBidAsk = 4
	// OrderTriggerMethodLastOrBidAsk is an allowlisted broker trigger method.
	OrderTriggerMethodLastOrBidAsk = 7
	// OrderTriggerMethodMidpoint is an allowlisted broker trigger method.
	OrderTriggerMethodMidpoint = 8

	// OrderOriginAgent identifies an audited request origin; it does not grant authority by itself.
	// Request origins for broker writes. Adapters stamp every write request;
	// the daemon journals origin for audit and may apply origin-specific
	// policy. A missing or unknown origin is treated as OrderOriginAgent, so
	// new adapters must opt in to a human origin.
	OrderOriginAgent = "agent"
	// OrderOriginHumanTTY identifies an audited request origin; it does not grant authority by itself.
	OrderOriginHumanTTY = "human-tty"
	// OrderOriginPairedDevice identifies an audited request origin; it does not grant authority by itself.
	OrderOriginPairedDevice = "human-paired-device"

	OrderPositionEffectOpen      = "open"
	OrderPositionEffectIncrease  = "increase"
	OrderPositionEffectReduce    = "reduce"
	OrderPositionEffectClose     = "close"
	OrderPositionEffectFlip      = "flip"
	OrderPositionEffectOpenShort = "open_short"

	// OrderWhatIfStatusUnavailable classifies broker WhatIf evidence.
	OrderWhatIfStatusUnavailable = "unavailable"
	// OrderWhatIfStatusAccepted classifies broker WhatIf evidence.
	OrderWhatIfStatusAccepted = "accepted"
	// OrderWhatIfStatusRejected classifies broker WhatIf evidence.
	OrderWhatIfStatusRejected = "rejected"

	// OrderTokenScopePlace binds a preview token to one order operation.
	OrderTokenScopePlace = "place"
	// OrderTokenScopeModify binds a preview token to one order operation.
	OrderTokenScopeModify = "modify"

	// OrderLifecyclePreviewed is a durable order-lifecycle classification.
	OrderLifecyclePreviewed = "previewed"
	// OrderLifecyclePendingSubmit is a durable order-lifecycle classification.
	OrderLifecyclePendingSubmit = "pending_submit"
	// OrderLifecyclePreSubmitted is a durable order-lifecycle classification.
	OrderLifecyclePreSubmitted = "pre_submitted"
	// OrderLifecycleSubmitted is a durable order-lifecycle classification.
	OrderLifecycleSubmitted = "submitted"
	// OrderLifecyclePartiallyFilled is a durable order-lifecycle classification.
	OrderLifecyclePartiallyFilled = "partially_filled"
	// OrderLifecycleFilled is a durable order-lifecycle classification.
	OrderLifecycleFilled = "filled"
	// OrderLifecyclePendingCancel is a durable order-lifecycle classification.
	OrderLifecyclePendingCancel = "pending_cancel"
	// OrderLifecycleCancelled is a durable order-lifecycle classification.
	OrderLifecycleCancelled = "cancelled"
	// OrderLifecycleRejected is a durable order-lifecycle classification.
	OrderLifecycleRejected = "rejected"
	// OrderLifecycleInactive is a durable order-lifecycle classification.
	OrderLifecycleInactive = "inactive"
	// OrderLifecycleUnknownReconcileRequired is a durable order-lifecycle classification.
	OrderLifecycleUnknownReconcileRequired = "unknown_reconcile_required"
	// OrderLifecycleExpiredInferred marks a DAY order whose effective session
	// closed without a terminal broker callback. It is local calendar
	// inference — never broker-confirmed — and such rows stay cancel- and
	// modify-ineligible. (GTC rows instead heal via the open-order snapshot
	// reconcile, see OrderLifecycleClosedReconciled.)
	OrderLifecycleExpiredInferred = "expired_inferred"
	// OrderLifecycleClosedReconciled marks a journal row that a complete
	// broker open-order snapshot no longer reported: the terminal callback
	// (fill, cancel, broker-side expiry) was missed while the daemon was not
	// listening. The final broker state is unknown — cancelled or filled
	// outside the daemon's view — so broker statements stay authoritative;
	// this status only closes the local row.
	OrderLifecycleClosedReconciled = "closed_reconciled"

	OrderReconciliationKindShortEntryFull   = "short_entry_full"
	OrderReconciliationKindShortEntryExcess = "short_entry_excess"
	OrderReconciliationSeverityCritical     = "critical"
)

Order constants are the allowlisted action, order-type, time-in-force, strategy, and trailing-offset vocabulary accepted by daemon order requests.

View Source
const (
	EarningsStatusDate                    = "date"
	EarningsStatusNoDatePublished         = "no_date_published"
	EarningsStatusUnsupportedSecurity     = "unsupported_security"
	EarningsStatusFormatChange            = "format_change"
	EarningsStatusTransportFailure        = "transport_failure"
	EarningsStatusConflictingSources      = "conflicting_sources"
	EarningsStatusNotApplicable           = "not_applicable"
	EarningsStatusTerminalNonReporting    = "terminal_non_reporting"
	EarningsStatusTerminalEvidenceExpired = "terminal_evidence_expired"
)

Earnings statuses are the closed aggregate/provider outcome vocabulary.

View Source
const (
	SettingsAccessRead  = "read"
	SettingsAccessWrite = "write"

	SettingsSourceRuntime  = "runtime"
	SettingsSourceConfig   = "config"
	SettingsSourceBuild    = "build"
	SettingsSourceObserved = "observed"
)

Settings access and source values state whether a field is mutable and which authority supplied it.

View Source
const (
	// SettingsClassRuntime keys are runtime-owned. Individual keys may add a
	// stricter origin policy; trading.freeze is human-terminal-only in every mode.
	SettingsClassRuntime = "runtime"
	// SettingsClassTradingLimit keys are writable only while trading limits
	// are writable (experimental trading build with paper/live mode), and every
	// write requires a human-terminal origin in every mode.
	SettingsClassTradingLimit = "trading-limit"
)

Writability classes the daemon enforces beyond per-kind parsing.

View Source
const (
	// TapeSessionTradingDate means the calendar date has an official session.
	TapeSessionTradingDate = "trading_date"
	// TapeSessionClosedDate means direct tape changes are frozen context only.
	TapeSessionClosedDate = "closed_date"
)

TapeSessionState values shared by StressMarketSummary and RegimeSnapshotResult. Trading dates keep full direct-tape severity at any hour (pre/post/overnight moves are live prints the tape-shock row exists to catch); closed dates demote frozen tape shocks to observe and bar them from entering or holding tape-driven lifecycle stages until the next open re-evaluates them from live prints.

View Source
const (
	MethodAutoTradeStatus        = "auto_trade.status"
	MethodTradeProposalsSnapshot = "trade_proposals.snapshot"
	MethodTradeProposalsRefresh  = "trade_proposals.refresh"
	MethodTradeProposalsPreview  = "trade_proposals.preview"
	MethodTradeProposalsSubmit   = "trade_proposals.submit"
	MethodTradeProposalsIgnore   = "trade_proposals.ignore"
	// MethodTradeProposalsReducePreview starts a discretionary, user-initiated
	// partial close of an existing
	// holding by a chosen percentage. Unlike the daemon-generated proposals
	// above (keyed by key+revision), it acts directly on a live position, so
	// it carries no proposal key. It reuses the gated order preview/place
	// path and is always close/reduce-only.
	MethodTradeProposalsReducePreview = "trade_proposals.reduce_preview"
	MethodTradeProposalsReduceSubmit  = "trade_proposals.reduce_submit"
	// MethodTradeProposalsReducePortfolioPreview starts the one-tap risk-off
	// sweep: a proportional trim of the
	// whole book by a chosen percentage. It enumerates every eligible position
	// and drives each leg through the same gated order path as the single-position
	// reduce, best-effort. Protective hedges are excluded unless opted in.
	MethodTradeProposalsReducePortfolioPreview = "trade_proposals.reduce_portfolio_preview"
	MethodTradeProposalsReducePortfolioSubmit  = "trade_proposals.reduce_portfolio_submit"

	// ProtectionPolicyFingerprintVersion identifies a semantic fingerprint projection.
	ProtectionPolicyFingerprintVersion = "protection-policy-fp-v1"

	ProtectionPolicyStatusActive   = "active"
	ProtectionPolicyStatusDefault  = "default"
	ProtectionPolicyStatusDrift    = "drift"
	ProtectionPolicyStatusError    = "error"
	ProtectionPolicyStatusDisabled = "disabled"

	TradeProposalSnapshotKind = "ibkr.trade_proposal_snapshot"
	// TradeProposalSnapshotSchemaVersion identifies the account-and-mode-scoped
	// snapshot schema. Persisted snapshots without concrete scope fail closed.
	TradeProposalSnapshotSchemaVersion = "trade-proposal-snapshot-v2"

	TradeProposalBucketThetaHygiene  = "theta_hygiene"
	TradeProposalBucketRiskReduction = "risk_reduction"
	TradeProposalBucketTrailingStop  = "trailing_stop"

	TradeProposalStateGenerated = "generated"
	TradeProposalStateBlocked   = "blocked"
)

Trade-proposal method names and allowlisted policy, snapshot, bucket, and proposal-state values form a stable daemon wire vocabulary.

View Source
const CodeRegimeUnavailable = "regime_unavailable"

CodeRegimeUnavailable means the daemon has no complete, validated last-good regime snapshot to serve. It is deliberately distinct from gateway_unavailable: a disconnected gateway does not make a persisted last-good snapshot disappear, while a cold authority cannot return a partial dashboard as if it were current state.

View Source
const EstablishedAlertProjectionSchemaVersion = "stress-established-alert-v1"

EstablishedAlertProjectionSchemaVersion identifies the strict compatibility projection schema consumed by the established Stress monitor.

View Source
const EstablishedStressFingerprintVersion = "stress-fp-v1"

EstablishedStressFingerprintVersion identifies the Stress-labelled wrapper carried by EstablishedAlertProjection. Its key retains the exact pre-rename semantic projection even when the current Stress result and its public labels advance.

View Source
const GammaTransitionGapPct = 2.0

GammaTransitionGapPct is the ± band, in percent of the zero-gamma level, inside which dealer positioning reads as transitional rather than long or short gamma. Single copy: the daemon gamma rows and every CLI renderer classify through GammaRegimeFromGap, and prose that names the band derives its number from this constant.

View Source
const MethodAlertCandidates = "alerts.candidates"

MethodAlertCandidates exposes the daemon-authored, source-neutral alert candidate snapshot. The method is observational: it has no delivery target, acknowledgement, policy-change, or broker-write authority.

View Source
const MethodAlertStatus = "alerts.status"

MethodAlertStatus exposes redacted coverage and lifecycle measurements. It deliberately carries no candidate, account, order, or delivery-target identity.

View Source
const MethodReconEquity = "recon.equity"

MethodReconEquity serves the daemon.db statement-derived daily equity series joined with authoritative capital events. Read-only: retained Flex XML stays the original broker evidence, while SQLite holds its transactionally refreshed typed projection.

View Source
const MethodRegimeHistory = "regime.history"

MethodRegimeHistory serves the post-cutover regime-decision timeline from the daemon's authoritative daemon.db event store. Read-only: these results never feed policy or broker-write authority.

View Source
const MethodRulesHistory = "rules.history"

MethodRulesHistory serves the rulebook transition timeline from the same daemon.db authority. Advisory/read-only end to end — nothing in these results touches submit eligibility or any broker-write path.

View Source
const MethodRulesSnapshot = "rules.snapshot"

MethodRulesSnapshot returns the daily trading-rulebook checklist evaluated against the current book. Advisory-only: nothing in this result may alter submit eligibility or any gated broker-write path.

View Source
const MethodStressHistory = "stress.history"

MethodStressHistory serves the post-cutover stress-decision timeline from daemon.db. Read-only event evidence — nothing here touches submit eligibility or any broker-write path.

View Source
const ReconBaseline = "baseline"

ReconBaseline is not an exception category. It identifies pre-genesis statement flows whose one valid treatment is inclusion in the seeded baseline.

View Source
const ReconConfirmed = "confirmed"

ReconConfirmed is a normal v3 statement-authoritative flow. It is disclosed and report-id-pinned, but is not an exception or a signature target because declarations are optional after the authority flip.

View Source
const RegimeCurrencyBlankFloor = 2

RegimeCurrencyBlankFloor is how many clusters may be defective or impaired before the whole market state blanks to data_quality instead of standing with degraded readiness. One dead or stale feed degrades and is named; two independent ones mean the read no longer describes the market. Operator decision, 2026-07-31: the tolerance was set for defects, and applies to the impaired grade too because two clusters that cannot supply current evidence leave the same hole whichever grade got them there.

View Source
const RegimeCurrencyPolicyVersion = "regime-currency-v1"

RegimeCurrencyPolicyVersion identifies the input-currency policy a decision event was produced under (internal-docs/design/regime-input-currency.md). Behaviour changes in how inputs report currency alter the daily fingerprint sequence, so the calibration corpus has to be partitionable: a backtest must never blend days either side of a cutover. Bump on every change to how a class is assigned or consumed.

View Source
const RegimeVerdictFloor = 3

RegimeVerdictFloor is the minimum ranked-cluster count required to claim a verdict above "insufficient signal".

View Source
const RiskConstitutionFingerprintVersion = "risk-constitution-fp-v1"

RiskConstitutionFingerprintVersion labels the constitution fingerprint. Distinct from the stress threshold policy's StressPolicyFingerprintVersion so the two identities can never be conflated in journals. RiskConstitutionFingerprintVersion identifies a semantic fingerprint projection.

View Source
const RulebookPolicyFingerprintVersion = "rulebook-fp-v3"

RulebookPolicyFingerprintVersion labels the advisory rulebook policy fingerprint's JSON projection. Sibling-policy pins compare policy ID and version rather than fingerprint keys, and journals remain point-in-time records.

Variables

View Source
var RegimeClusterNames = []string{"vol", "credit", "funding", "fx", "gamma", "breadth"}

RegimeClusterNames are the wire names for the six clusters, indexed by the RegimeCluster* constants.

Functions

func AggregateNudgeSourceHealth

func AggregateNudgeSourceHealth(health NudgeSourceHealth, candidateCount int) string

AggregateNudgeSourceHealth makes an empty result reassuring only when every relevant authority is ready. Partial coverage with safe candidates is degraded; the same coverage gap with no candidates is suppressed.

func ApplyRegimeClusterTallies

func ApplyRegimeClusterTallies(c *RegimeComposite, cb RegimeClusterBands)

ApplyRegimeClusterTallies fills the cluster-level counts on a composite from the shared combination — the daemon, the backtest builder, and tests all populate composites through this one function. Row-level counts (GreenCount etc.) remain the caller's concern; Verdict is set afterwards via RegimeHeadline once the lifecycle stage is known.

func BuildAlertAuthorityScope

func BuildAlertAuthorityScope(account, mode string) (string, error)

BuildAlertAuthorityScope returns the opaque account/mode authority carried by private candidate snapshots. Raw account and mode values do not cross the RPC boundary.

func BuildAlertEpisodeKey

func BuildAlertEpisodeKey(source AlertSource, kind AlertKind, identityParts ...string) (string, error)

BuildAlertEpisodeKey delegates opaque identity construction to the pure contract; RPC adapters never reinterpret its semantic inputs.

func BuildAlertOccurrenceKey

func BuildAlertOccurrenceKey(episodeKey string, identityParts ...string) (string, error)

BuildAlertOccurrenceKey delegates daemon-authored opening, reopen, and qualifying-escalation identity to the pure contract. Apps consume the opaque result; they do not mint it or decide when it rotates.

func BuildEarningsIdentityAuthorityBinding

func BuildEarningsIdentityAuthorityBinding(symbol string, identity EarningsIdentityInfo) string

BuildEarningsIdentityAuthorityBinding binds one public earnings projection to the exact symbol and opaque proof receipt it describes. The digest exposes neither the raw database receipt ID nor broker identity fields; consumers can recompute it to reject cross-symbol or cross-proof substitution.

func BuildEarningsTerminalAuthorityBinding

func BuildEarningsTerminalAuthorityBinding(symbol string, terminal EarningsTerminalInfo) string

BuildEarningsTerminalAuthorityBinding binds one public terminal projection to the exact symbol and contract authority it describes. The digest excludes issuer text and evidence prose while retaining every typed field needed to reject cross-symbol or cross-contract substitution.

func CompactRegimeSnapshot

func CompactRegimeSnapshot(r *RegimeSnapshotResult)

CompactRegimeSnapshot removes methodology prose and chart/history payloads from a regime response while preserving the current measurements, summary, composite counts, streaks, quality provenance, scoped warnings, and gamma headline diagnostics. CLI --json and MCP use this default shape so agent consumers get the decision surface without multi-kilobyte notes blocks.

func ExpectsMarketData

func ExpectsMarketData(p PositionView) bool

ExpectsMarketData reports whether a quote, mark, or market-event flag should exist for this position. Absence is a defect only when this returns true.

func ExpectsMarketDataGroup

func ExpectsMarketDataGroup(g PositionGroup) bool

ExpectsMarketDataGroup reports whether an underlying group should be subscribed for market data. Only a stock-only group whose stock expects no data is skipped: an option leg on a defunct underlying still needs its own quote, and the group's other rows are unaffected.

func GammaBucketRegime

func GammaBucketRegime(spot float64, zero *float64, sign string) string

GammaBucketRegime classifies one horizon bucket (0DTE / 1-7 / term) from its zero-gamma level and profile sign. With a usable crossing the gap classifies through GammaRegimeFromGap; without one the swept profile's sign decides, and an unknown sign yields "" (bucket unavailable).

func GammaCombinedGapPct added in v2.8.0

func GammaCombinedGapPct(c *GammaZeroComputed) *float64

GammaCombinedGapPct is the gamma-weighted mean of the per-index gaps on a combined-scope result. nil when the result is not combined scope or no index reports a crossing.

func GammaIndexWeight added in v2.8.0

func GammaIndexWeight(key string, c *GammaZeroComputed) float64

GammaIndexWeight is the weight one index carries in the combined SPY+SPX row: its gross gamma exposure, or a scale-ratio stand-in when a leg reports none. Single copy, because the band vote and the eligibility depth have to weigh the two indexes the same way — weighing them differently lets a red banded on the dominant index be refused for depth the other index diluted (internal-docs/design/regime-calibration.md, gamma path (c)).

func GammaRegimeFromGap

func GammaRegimeFromGap(gapPct *float64) string

GammaRegimeFromGap maps the signed spot-vs-zero-gamma gap (percent of the zero-gamma level, positive = spot above) to its wire regime label. A nil gap — no measurable crossing — is transitional: without a gap the classifier must not claim direction.

func IsLiveDataType

func IsLiveDataType(dt string) bool

IsLiveDataType reports whether the gateway's per-reqID feed state is "live ticks", treating empty-string the same as live (no notice yet). Used by renderers to decide whether to dim a row or show a phase badge.

func IsOptionRTH

func IsOptionRTH(now time.Time) bool

IsOptionRTH reports whether the given instant falls within U.S. listed- equity-option regular trading hours: weekdays 09:30–16:00 ET.

Used in preference to IsLiveDataType for option-context renderers (chain, option quotes) because the underlying ETF can stay "live" via extended- hours quoting on SMART/ARCA while the option markets themselves are closed — IsLiveDataType won't fire in that window, but the chain has no bid/ask and IVs come from IBKR's model-computation engine off prior-session prices. The clock-gated check captures that state.

Holidays are NOT modeled. The fall-through is "open" on those days; the existing model-tick → BS-IV fallback chain keeps results usable, and a missed disclosure on a holiday is preferable to mis-flagging a regular session.

Display cadence only — never use this for policy blockers or eligibility gates. Those must go through a marketcal-backed authority (the daemon's optionSessionOpen), which models holidays, early closes, and the 16:15 options close, and reports unknown coverage instead of guessing.

Fail-open: if the America/New_York zone can't be loaded (e.g. tzdata missing in a minimal container), returns true so the banner stays suppressed rather than firing during RTH.

func MarketDataAccessReason added in v2.8.0

func MarketDataAccessReason(code int) string

MarketDataAccessReason maps an IBKR rejection code to its typed reason. Unknown codes classify as MarketDataAccessRejected rather than guessing.

func PositionQuotesAsStock added in v2.7.0

func PositionQuotesAsStock(row PositionView) bool

PositionQuotesAsStock reports whether a non-option position row is an equity — the only secType for which a stock quote on the bare symbol describes the holding. The non-option slice of PositionsResult carries every secType that is not OPT (BOND, BILL, FUND, FUT, CASH); those rows share the slice because they are not options, not because they are stocks, and joining one to an equity surface by symbol decorates a treasury symbolled "T" with AT&T's quote. This is the one shared classification for that join — daemon, CLI, and MCP must all use it rather than re-deriving it from the slice name. Unknown and absent secTypes classify false: absence of a type is not stock authority.

func RegimeClusterCurrency added in v2.7.0

func RegimeClusterCurrency(r RegimeSnapshotResult, name string) string

RegimeClusterCurrency rolls a cluster's rows up to their worst currency. A cluster with no known rows is overdue.

The scheduled classes carry a bound: not_due and pending both claim that no newer observation exists yet, which stops being credible once the served max age for the cluster has passed. Without this a dead subscription still serving its last value off-hours reads healthy indefinitely.

func RegimeClusterExpectedNotDue

func RegimeClusterExpectedNotDue(r RegimeSnapshotResult, name string) bool

RegimeClusterExpectedNotDue reports the closed-window half of the scheduled pair. Prefer RegimeClusterScheduledContext unless the caller genuinely means "the window is closed" rather than "no newer observation is being served".

func RegimeClusterScheduledContext added in v2.7.0

func RegimeClusterScheduledContext(r RegimeSnapshotResult, name string) (string, bool)

RegimeClusterScheduledContext reports a cluster whose non-fresh currency is a scheduled publication state rather than a defect, and which state it is:

  • not_due — the source's publication window is closed, so no newer observation can exist yet.
  • pending — the current period's refresh is in flight, evidenced by a typed marker, inside a bounded window anchored to the period start.

It is the single exact-cluster exemption used by source health, data-quality projection, warnings, and lifecycle readiness. Every caller must consult the pair through this function rather than one class alone: the two states carry identical authority (visible context, never confirmation) and differ only in why no newer observation is being served. Malformed, partial, stale, and overdue clusters still fail closed, and the currency roll-up has already applied the served max-age bound, so a dead subscription cannot hold a scheduled state open indefinitely.

func RegimeCurrencyGrade added in v2.7.0

func RegimeCurrencyGrade(class string) string

RegimeCurrencyGrade maps a currency class to what it costs the read.

func RegimeCurrencyMayConfirm added in v2.7.0

func RegimeCurrencyMayConfirm(class string) bool

RegimeCurrencyMayConfirm reports whether evidence at this currency may CONFIRM stress or take the day-one fast path. Deliberately an allowlist on fresh rather than a denylist of known-bad classes: a class added later must fail closed until its authority is decided, not inherit confirmation.

func RegimeCurrencyMayContext added in v2.7.0

func RegimeCurrencyMayContext(class string) bool

RegimeCurrencyMayContext reports whether evidence at this currency may stay visible, band, and warn. It never implies confirmation.

func RegimeCurrencyScheduled added in v2.7.0

func RegimeCurrencyScheduled(class string) bool

RegimeCurrencyScheduled reports the two classes that explain an absent newer observation by the source's own schedule rather than by a defect: the window is closed, or its refresh is in flight inside a bounded window. They carry identical authority and callers must treat them alike.

func RegimeFingerprintMatchesSnapshot

func RegimeFingerprintMatchesSnapshot(r *RegimeSnapshotResult) bool

RegimeFingerprintMatchesSnapshot recomputes the semantic identity embedded in r. It accepts the current projection and the sole persisted predecessor, whose source-health projection predates typed failure code/stage fields. Unknown versions and mismatched keys fail closed.

func RegimeGammaDepth

func RegimeGammaDepth(c *GammaZeroComputed) *float64

RegimeGammaDepth extracts gamma's eligibility depth in percent below gamma-zero (−gap). Combined scope weighs the per-index depths the way the band vote weighed the per-index bands, so the index that sets the colour is the index that decides whether the red is deep enough to confirm.

func RegimeHeadline

func RegimeHeadline(c RegimeComposite, stage string) string

RegimeHeadline is the single wording table for the regime headline. Both composite.verdict and posture.label render this string; the CLI, MCP, SPA, and backtest all show the served value. First match wins.

func RegimeIndicatorCluster

func RegimeIndicatorCluster(indicator string) string

RegimeIndicatorCluster maps an indicator key to its cluster wire name.

func RegimeRowCurrency added in v2.7.0

func RegimeRowCurrency(status string, freshness *RegimeFreshness) string

RegimeRowCurrency is one row's currency: its served cadence class, reconciled with the row status. A class that claims more than the status supports is demoted rather than trusted, and a row with no typed freshness is overdue.

func RegimeSourceMaxAgeSeconds

func RegimeSourceMaxAgeSeconds(source string) int64

RegimeSourceMaxAgeSeconds is the served per-cluster staleness policy for the cluster's weakest-leg as_of: older than this is unambiguously overdue. Wall-clock documentation values sized to each cluster's slowest native cadence (VVIX daily close over a weekend, FRED publication lag, a Friday gamma compute read on Monday pre-open); the binding eligibility gate uses trading-date logic daemon-side. Served so renderers derive their stale badges from the wire instead of hardcoding twins.

func RegimeVIXTapeCurrency added in v2.7.0

func RegimeVIXTapeCurrency(r RegimeSnapshotResult) string

RegimeVIXTapeCurrency is the currency of the VIX day-change leg on its own. The tape arms read that leg; the VIX3M leg they do not read is the thin index that times out, and losing it must not demote a live VIX print. A live tick is the only current state for a leg that publishes continuously on weekdays.

func StripGammaProfiles

func StripGammaProfiles(r *GammaZeroSPXResult)

StripGammaProfiles removes chart-sized sweep arrays from a gamma result while preserving headline levels, summaries, warning details, counts, and top strikes. CLI JSON and MCP use this by default so agents do not receive tens of kilobytes of points unless they explicitly ask for profiles.

func StripRegimeGammaProfiles

func StripRegimeGammaProfiles(r *RegimeSnapshotResult)

StripRegimeGammaProfiles removes large gamma profiles from every regime projection while preserving its summary and quality evidence.

func TapeSessionFor

func TapeSessionFor(now time.Time) (state, reason string, nextOpen *time.Time)

TapeSessionFor classifies the official US cash-equity calendar date at now for direct-tape severity — the single policy copy behind both the Stress tape row and the regime lifecycle tape terms. Trading dates (regular and early-close) keep full severity at any hour: pre/post/overnight prints are live (VIX prints overnight on weekdays). Closed dates (weekend/holiday) freeze the SPY/VIX day-change anchors at last-session values — which can even reset independently while closed — so frozen shocks carry evidence but confirm nothing until the next open. Outside embedded calendar coverage the state stays empty and consumers fail open to full severity.

func VIX3MCrossCheckVouches added in v2.6.0

func VIX3MCrossCheckVouches(verdict string) bool

VIX3MCrossCheckVouches reports whether the verdict established the served off-window leg's vintage. Only a vouched leg may read not_due, because not_due exempts a row from every age bound; everything else fails closed.

func ValidSourceFailure

func ValidSourceFailure(f *SourceFailure) bool

ValidSourceFailure enforces the shared allowlist. Persistence and adapters call this before accepting a failure so upstream prose cannot masquerade as a typed code or stage.

func ValidateAlertAuthorityScope

func ValidateAlertAuthorityScope(value string) error

ValidateAlertAuthorityScope rejects malformed or noncanonical scope values.

func ValidateAlertCandidate

func ValidateAlertCandidate(candidate AlertCandidate) error

ValidateAlertCandidate validates a candidate against the shared risk contract.

func ValidateAlertCandidateSnapshot

func ValidateAlertCandidateSnapshot(snapshot AlertCandidateSnapshot) error

ValidateAlertCandidateSnapshot validates coverage, candidates, and snapshot coherence against the shared risk contract.

func ValidateEstablishedAlertProjection

func ValidateEstablishedAlertProjection(projection EstablishedAlertProjection) error

ValidateEstablishedAlertProjection rejects missing, unknown, or internally inconsistent compatibility data. Eligibility is checked against the frozen v1 schema semantics; adapters must not re-derive or extend those semantics.

func ValidateReconAutomationStatus

func ValidateReconAutomationStatus(status ReconAutomationStatus) error

ValidateReconAutomationStatus rejects unknown or incoherent values before an adapter can publish them. The contract is intentionally exact: callers must map new internal failures to an existing safe reason or revise every consumer deliberately.

func ValidateReconCheckResult

func ValidateReconCheckResult(result ReconCheckResult) error

ValidateReconCheckResult rejects unknown outcomes and incoherent status.

func ValidateRegimeAuthorityHealth

func ValidateRegimeAuthorityHealth(health RegimeAuthorityHealth) error

ValidateRegimeAuthorityHealth rejects ambiguous or internally inconsistent projections before they cross an adapter boundary.

Types

type AccountDataAuthority added in v2.8.0

type AccountDataAuthority struct {
	Scope        AccountDataScope          `json:"scope"`
	Source       AccountDataSource         `json:"source"`
	Availability AccountDataAvailability   `json:"availability"`
	Freshness    AccountDataFreshness      `json:"freshness"`
	Reason       AccountDataReason         `json:"reason,omitempty"`
	AsOf         time.Time                 `json:"as_of,omitzero"`
	Fields       *AccountFieldAvailability `json:"fields,omitempty"`
}

AccountDataAuthority is the shared truth envelope for account-scoped reads. Scope names the one account and paper/live mode the values belong to. Source describes the producer, Availability says whether the payload can stand as account truth, and Freshness says whether its receipt is current. A payload may retain stale or incomplete rows as context while Availability is unavailable; consumers must not turn those rows into a clean-book claim.

Fields is present on AccountResult. Its booleans preserve the distinction between an observed zero and a legacy float64 zero produced because IBKR did not send the field. PositionsResult leaves Fields nil because the portfolio stream's completeness is described by Availability, Freshness, and Reason.

type AccountDataAvailability added in v2.8.0

type AccountDataAvailability string

AccountDataAvailability says whether the payload may stand as account truth. Unavailable payloads may still carry context, but cannot prove a genuine zero, an empty book, or any other negative.

const (
	AccountDataAvailable   AccountDataAvailability = "available"
	AccountDataUnavailable AccountDataAvailability = "unavailable"
)

Account data availability values say whether a result can stand as truth.

type AccountDataFreshness added in v2.8.0

type AccountDataFreshness string

AccountDataFreshness separates a current receipt from stale retained context and from data with no trustworthy observation time.

const (
	AccountDataFreshnessCurrent AccountDataFreshness = "current"
	AccountDataFreshnessStale   AccountDataFreshness = "stale"
	AccountDataFreshnessUnknown AccountDataFreshness = "unknown"
)

Account data freshness values describe the age of the observed result.

type AccountDataReason added in v2.8.0

type AccountDataReason string

AccountDataReason is a stable, redacted explanation of why an account-scoped payload is stale or unavailable. Raw broker and transport errors stay out of this public contract.

const (
	AccountDataReasonUnstampedCache  AccountDataReason = "unstamped_cache"
	AccountDataReasonScopeUnresolved AccountDataReason = "scope_unresolved"
	AccountDataReasonScopeConflict   AccountDataReason = "scope_conflict"
	AccountDataReasonAccountUnbound  AccountDataReason = "account_unbound"
	AccountDataReasonAccountMismatch AccountDataReason = "account_mismatch"
	AccountDataReasonUnprimed        AccountDataReason = "unprimed"
	AccountDataReasonInvalidPayload  AccountDataReason = "invalid_payload"
	AccountDataReasonClockInvalid    AccountDataReason = "clock_invalid"
	AccountDataReasonReceiptStale    AccountDataReason = "receipt_stale"
	AccountDataReasonSessionChanged  AccountDataReason = "session_changed"
)

Account data reasons are the closed public explanations for unavailable data.

type AccountDataScope added in v2.8.0

type AccountDataScope struct {
	AccountID   string `json:"account_id"`
	AccountMode string `json:"account_mode"`
}

AccountDataScope names one concrete broker account and its paper/live mode. An aggregate managedAccounts inventory and the literal "All" are not valid account IDs and must never be published here as a selected account.

type AccountDataSource added in v2.8.0

type AccountDataSource string

AccountDataSource is the closed producer vocabulary for account-scoped account and positions results.

const (
	AccountDataSourceAccountSummaryRequest AccountDataSource = "account_summary_request"
	AccountDataSourceAccountUpdatesCache   AccountDataSource = "account_updates_cache"
	AccountDataSourcePortfolioStream       AccountDataSource = "portfolio_stream"
)

Account data sources identify the producer behind an account-scoped result.

type AccountFieldAvailability added in v2.8.0

type AccountFieldAvailability struct {
	AccountType          bool `json:"account_type"`
	BaseCurrency         bool `json:"base_currency"`
	NetLiquidation       bool `json:"net_liquidation"`
	BuyingPower          bool `json:"buying_power"`
	AvailableFunds       bool `json:"available_funds"`
	ExcessLiquidity      bool `json:"excess_liquidity"`
	TotalCash            bool `json:"total_cash"`
	MaintenanceMargin    bool `json:"maintenance_margin"`
	InitialMargin        bool `json:"initial_margin"`
	GrossPositionValue   bool `json:"gross_position_value"`
	UnrealizedPnL        bool `json:"unrealized_pnl"`
	RealizedPnL          bool `json:"realized_pnl"`
	Cushion              bool `json:"cushion"`
	LookAheadInitMargin  bool `json:"look_ahead_init_margin"`
	LookAheadMaintMargin bool `json:"look_ahead_maint_margin"`
	LookAheadAvailable   bool `json:"look_ahead_available_funds"`
	LookAheadExcess      bool `json:"look_ahead_excess_liquidity"`
	DailyPnL             bool `json:"daily_pnl"`
	PnLUnrealizedTotal   bool `json:"pnl_unrealized_total"`
	PnLRealizedTotal     bool `json:"pnl_realized_total"`
	CurrencyExposure     bool `json:"currency_exposure"`
}

AccountFieldAvailability mirrors AccountResult's account-summary fields. Every key is emitted when Fields is present: false is evidence that the producer did not supply that field, not a default a consumer may ignore.

type AccountResult

type AccountResult struct {
	AccountID            string               `json:"account_id"`
	AccountType          string               `json:"account_type,omitempty"`
	BaseCurrency         string               `json:"base_currency"`
	NetLiquidation       float64              `json:"net_liquidation"`
	BuyingPower          float64              `json:"buying_power"`
	AvailableFunds       float64              `json:"available_funds"`
	ExcessLiquidity      float64              `json:"excess_liquidity"`
	TotalCash            float64              `json:"total_cash"`
	MaintenanceMargin    float64              `json:"maintenance_margin"`
	InitialMargin        float64              `json:"initial_margin"`
	GrossPositionValue   float64              `json:"gross_position_value"`
	UnrealizedPnL        float64              `json:"unrealized_pnl"`
	RealizedPnL          float64              `json:"realized_pnl"`
	Cushion              float64              `json:"cushion"`
	LookAheadInitMargin  float64              `json:"look_ahead_init_margin"`
	LookAheadMaintMargin float64              `json:"look_ahead_maint_margin"`
	LookAheadAvailable   float64              `json:"look_ahead_available_funds"`
	LookAheadExcess      float64              `json:"look_ahead_excess_liquidity"`
	DailyPnL             *float64             `json:"daily_pnl,omitempty"`
	DailyPnLObservation  *DailyPnLObservation `json:"daily_pnl_observation,omitempty"`
	PnLUnrealizedTotal   *float64             `json:"pnl_unrealized_total,omitempty"`
	PnLRealizedTotal     *float64             `json:"pnl_realized_total,omitempty"`
	CurrencyExposure     []CurrencyExposure   `json:"currency_exposure,omitempty"`
	// DataType is reserved for account-feed state; the account-summary
	// path is gateway-direct with no live/delayed dimension and the field
	// is currently left empty (omitted). Kept for shape parity with the
	// market-data surfaces.
	DataType string    `json:"data_type,omitempty"`
	AsOf     time.Time `json:"as_of"`
	// Authority carries the concrete account/mode, producer, freshness, and
	// per-field availability. Current daemon responses always populate it.
	Authority *AccountDataAuthority `json:"authority,omitempty"`
}

AccountResult is the wire shape of MethodAccountSummary.

CurrencyExposure decomposes the portfolio by contract currency: one row per non-base currency the gateway reported via $LEDGER:ALL. Rows reconcile within ~0.5%: NetLiquidationCcy × ExchangeRate ≈ contribution to base NetLiquidation. Empty array on a same-currency account.

UnrealizedPnL / RealizedPnL are the gateway-reported base-currency session totals. Cushion is ExcessLiquidity / NetLiquidation as reported by the gateway (not derived locally) — a ratio, unitless. AccountType is one of IBKR's account-type strings ("INDIVIDUAL", "IB-MARGIN", "REG-T-MARGIN", "PORTFOLIO", "CASH", …); empty when the gateway didn't deliver it (older server versions or non-margin accounts). LookAhead* fields project the post-overnight-margin-cycle state — useful to spot "fine now, blown by tonight" cases on portfolio-margin books. Legacy scalar fields remain float64 for wire compatibility. Authority.Fields is the source of truth for whether each one was observed: an available field with value zero is a genuine zero, while an unavailable field's numeric zero is only the Go zero value and must render as missing.

DailyPnL / PnLUnrealizedTotal / PnLRealizedTotal are populated from the gateway's reqPnL stream (TWS msg 94). DailyPnL is start-of- trading-day to now — the figure TWS shows in the portfolio header. PnLUnrealizedTotal / PnLRealizedTotal come from the same msg 94 frame (fields 3 & 4) but are the account's TOTAL unrealized / realized P&L (inception to now), NOT a decomposition of DailyPnL — they do not sum to it. They measure the same quantity as the session-running UnrealizedPnL / RealizedPnL above but arrive on a different feed (reqPnL vs account-updates), so the two can legitimately differ. All three are *float64 — nil means "no data yet" (pre-handshake, before the first stream frame), "no entitlement" (the gateway doesn't emit PnL for unentitled accounts), or "DBL_MAX sentinel" (gateway hasn't computed the slice). Never zero-substituted. PnLUnrealizedTotal / PnLRealizedTotal stay nil on older server versions that emit only the bare dailyPnL field. DailyPnLObservation carries the redacted source state so a regular-session failure cannot become healthy merely because the market closed.

type AlertAuthorityUniverse

type AlertAuthorityUniverse string

AlertAuthorityUniverse names the exact evidence population over which a source may claim coverage. An empty value means the source does not expose a narrower population than its source contract.

const (
	// AlertAuthorityUniverseJournaledAPIOrders limits Protection coverage to
	// daemon-journaled API orders checked against the all-client broker
	// inventory. It does not claim coverage over manual or unjournaled orders.
	AlertAuthorityUniverseJournaledAPIOrders AlertAuthorityUniverse = "daemon_journaled_api_orders_checked_against_all_client_inventory"
)

type AlertCandidate

type AlertCandidate = risk.AlertCandidate

AlertCandidate is the shared pure-risk candidate contract.

type AlertCandidateSnapshot

type AlertCandidateSnapshot = risk.AlertCandidateSnapshot

AlertCandidateSnapshot is the shared validated source-neutral snapshot.

type AlertCandidatesParams

type AlertCandidatesParams struct{}

AlertCandidatesParams is intentionally empty. Producers and their coverage universe are daemon-owned; callers cannot select sources or weaken evidence requirements through request parameters.

type AlertCoverage

type AlertCoverage = risk.AlertCoverage

AlertCoverage is the shared pure-risk coverage contract.

type AlertCoverageFreshness

type AlertCoverageFreshness = risk.AlertCoverageFreshness

AlertCoverageFreshness reports whether coverage evidence is current.

type AlertCoverageState

type AlertCoverageState = risk.AlertCoverageState

AlertCoverageState reports whether the producer evaluated its full universe.

type AlertDestination

type AlertDestination = risk.AlertDestination

AlertDestination identifies an allowed presentation surface.

type AlertEpisodeState

type AlertEpisodeState = risk.AlertEpisodeState

AlertEpisodeState describes whether an episode opened, escalated, or recovered.

type AlertEvidenceHealth

type AlertEvidenceHealth = risk.AlertEvidenceHealth

AlertEvidenceHealth reports the quality of evidence behind a candidate.

type AlertKind

type AlertKind = risk.AlertKind

AlertKind classifies the condition represented by a candidate.

type AlertMeasurements

type AlertMeasurements struct {
	Evaluations              uint64  `json:"evaluations"`
	CoveredEvaluations       uint64  `json:"covered_evaluations"`
	ActiveEvaluations        uint64  `json:"active_evaluations"`
	ActiveObservations       uint64  `json:"active_observations"`
	EpisodesOpened           uint64  `json:"episodes_opened"`
	EpisodesEscalated        uint64  `json:"episodes_escalated"`
	EpisodesRecovered        uint64  `json:"episodes_recovered"`
	EpisodesReopened         uint64  `json:"episodes_reopened"`
	DuplicateInputs          uint64  `json:"duplicate_inputs"`
	DuplicateCandidates      uint64  `json:"duplicate_candidates"`
	RepeatedActive           uint64  `json:"repeated_active_observations"`
	ActiveEvidenceChurn      uint64  `json:"active_evidence_revisions"`
	Equivocations            uint64  `json:"equivocations"`
	StaleSuppressions        uint64  `json:"stale_suppressions"`
	CoverageFailures         uint64  `json:"coverage_failures"`
	TimeToObserveSamples     uint64  `json:"time_to_observe_samples"`
	TimeToObserveTotalSecond float64 `json:"time_to_observe_total_seconds"`
	TimeToObserveMaxSecond   float64 `json:"time_to_observe_max_seconds"`
}

AlertMeasurements contains cumulative, redacted lifecycle counts. Zero values mean no recorded observation, not successful coverage.

type AlertPresentationCode

type AlertPresentationCode = risk.AlertPresentationCode

AlertPresentationCode is the closed redacted copy key for a candidate.

type AlertSeverity

type AlertSeverity = risk.AlertSeverity

AlertSeverity is the stable urgency classification of a candidate.

type AlertSnapshotState

type AlertSnapshotState = risk.AlertSnapshotState

AlertSnapshotState distinguishes conclusively clear, active, and unknown snapshots.

type AlertSource

type AlertSource = risk.AlertSource

AlertSource identifies an allowlisted alert producer.

type AlertSourceCoverage

type AlertSourceCoverage = risk.AlertSourceCoverage

AlertSourceCoverage reports one expected producer's current evidence state.

type AlertSourceStatus

type AlertSourceStatus struct {
	Source            AlertSource            `json:"source"`
	Status            string                 `json:"status"`
	Reason            string                 `json:"reason"`
	AuthorityUniverse AlertAuthorityUniverse `json:"authority_universe,omitempty"`
	InputAsOf         time.Time              `json:"input_as_of,omitzero"`
	ObservedAt        time.Time              `json:"observed_at,omitzero"`
	Covered           bool                   `json:"covered"`
	// UncoveredRules lists canonical rule IDs whose per-rule coverage failed in
	// the source's latest evaluation while the source itself stayed covered.
	// Rule IDs are policy vocabulary — never candidate or account identity.
	UncoveredRules []string          `json:"uncovered_rules,omitempty"`
	Active         int               `json:"active_candidates"`
	Measurements   AlertMeasurements `json:"measurements"`
}

AlertSourceStatus reports coverage and lifecycle health for one allowlisted source without exposing candidate or account identities.

type AlertStatusParams

type AlertStatusParams struct{}

AlertStatusParams is intentionally empty because scope and source coverage are daemon-owned.

type AlertStatusResult

type AlertStatusResult struct {
	AsOf                  time.Time           `json:"as_of,omitzero"`
	ExpectedSources       []AlertSource       `json:"expected_sources"`
	Evaluations           uint64              `json:"evaluations"`
	RegistryApplyFailures uint64              `json:"registry_apply_failures"`
	Equivocations         uint64              `json:"equivocations"`
	LastErrorCode         string              `json:"last_error_code,omitempty"`
	Sources               []AlertSourceStatus `json:"sources"`
}

AlertStatusResult is the redacted, read-only operational view of the daemon alert registry. Measurements describe lifecycle behavior, not send policy.

type ArtefactParams

type ArtefactParams struct {
	// Artefact is morning | eod | weekly.
	Artefact string `json:"artefact"`
	Note     string `json:"note,omitempty"`
	Origin   string `json:"origin,omitempty"`
	// BriefFingerprint is set only by brief.ack. The existing policy
	// artefact verb leaves it empty and remains wire-compatible.
	BriefFingerprint string `json:"brief_fingerprint,omitempty"`
}

ArtefactParams records one completed cadence artefact.

type ArtefactRecord

type ArtefactRecord struct {
	Artefact         string    `json:"artefact"`
	Class            string    `json:"class,omitempty"`
	CompletedAt      time.Time `json:"completed_at,omitzero"`
	Note             string    `json:"note,omitempty"`
	Origin           string    `json:"origin,omitempty"`
	BriefFingerprint string    `json:"brief_fingerprint,omitempty"`
	// PolicyFingerprint is daemon-authored by later monthly brief.ack handling.
	// A monthly completion applies only to this policy identity; a changed
	// policy reopens the local month. The generic policy artefact verb does not
	// populate monthly metadata.
	PolicyFingerprint string `json:"policy_fingerprint,omitempty"`
	// Evidence is render-only monthly metadata populated by later brief.ack
	// handling. Origin alone is never stronger attention proof.
	Evidence string `json:"evidence,omitempty"`
}

ArtefactRecord is the latest journaled completion of one cadence artefact.

type AutoTradeStatus

type AutoTradeStatus struct {
	Kind             string                 `json:"kind,omitempty"`
	AsOf             time.Time              `json:"as_of,omitzero"`
	Trading          TradingStatus          `json:"trading"`
	ProposalsEnabled bool                   `json:"proposals_enabled"`
	FastPathEnabled  bool                   `json:"fast_path_enabled"`
	HotReload        bool                   `json:"hot_reload"`
	ReloadInterval   string                 `json:"reload_interval,omitempty"`
	ProposalCadence  string                 `json:"proposal_cadence,omitempty"`
	Policy           ProtectionPolicyStatus `json:"policy"`
	Blocked          bool                   `json:"blocked"`
	Blockers         []TradingBlocker       `json:"blockers,omitempty"`
}

AutoTradeStatus combines proposal generation and trading readiness. It is observational and does not itself authorize a broker write.

type BackgroundTaskStatus

type BackgroundTaskStatus struct {
	// Name is a stable token identifying the task. Stable across
	// daemon versions; one of the documented values above.
	Name       string    `json:"name"`
	Status     string    `json:"status,omitempty"`
	Scope      string    `json:"scope,omitempty"`
	StartedAt  time.Time `json:"started_at,omitzero"`
	EtaSeconds int       `json:"eta_seconds,omitempty"`
	Progress   int       `json:"progress,omitempty"`
}

BackgroundTaskStatus names a daemon-internal long-running task that is currently executing or waiting for a scheduled retry. Used by `canary status` to surface activity that would otherwise be invisible — a fresh autospawned daemon mid-bootstrap looks identical to an idle one from outside. The surface deliberately carries no required state enum: presence in the HealthResult.BackgroundTasks list IS the state ("this task is still active"). Tasks that are idle/ready/cold are omitted entirely, keeping the wire payload bounded and the user-facing rendering compact.

Current task names:

  • "breadth-spx" — the SPX 50-DMA breadth engine is running a refresh or waiting for a below-threshold bootstrap retry.
  • "gamma-zero" — the SPX zero-gamma compute is fanning out across option legs.

Renderers should treat unknown names as informational rather than errors; new background tasks added in future versions are forward-compatible by design.

type BreadthDailyValue

type BreadthDailyValue struct {
	Date           string  `json:"date"` // YYYY-MM-DD
	PctAbove50DMA  float64 `json:"pct_above_50dma"`
	PctAbove200DMA float64 `json:"pct_above_200dma,omitempty"`
	NewHighs       int     `json:"new_highs,omitempty"`
	NewLows        int     `json:"new_lows,omitempty"`
}

BreadthDailyValue is one trailing daily breadth reading. The two SMA readings (50-day and 200-day) plus the constituent counts for new 52-week highs/lows are carried per session so a renderer can chart all four series in one history call. Units: percentages in [0, 100] for the SMA readings; raw counts for the highs/lows.

type BreadthRefreshFailure

type BreadthRefreshFailure string

BreadthRefreshFailure is a redacted allowlisted reason for the latest breadth refresh problem. Raw per-symbol broker errors remain daemon-local.

const (
	BreadthRefreshFailureFetch     BreadthRefreshFailure = "fetch_failed"
	BreadthRefreshFailurePersist   BreadthRefreshFailure = "persist_failed"
	BreadthRefreshFailureCancelled BreadthRefreshFailure = "cancelled"
)

Breadth refresh failure values are the allowlisted wire vocabulary.

type BreadthRefreshProgress

type BreadthRefreshProgress struct {
	SessionKey  string                `json:"session_key"`
	StartedAt   time.Time             `json:"started_at"`
	Processed   int                   `json:"processed"`
	Total       int                   `json:"total"`
	Deadline    time.Time             `json:"deadline,omitzero"`
	LastFailure BreadthRefreshFailure `json:"last_failure,omitempty"`
}

BreadthRefreshProgress makes the long IBKR-paced fan-out observable without exposing symbols or broker text. Processed includes successful and failed fetches; Deadline is the calendar-based publication SLA, not an ETA.

type BreadthSPXParams

type BreadthSPXParams struct {
	// HistoryDays bounds the trailing daily series. Default 30 when
	// zero or negative; capped at 90 to keep the wire payload bounded.
	HistoryDays int `json:"history_days,omitempty"`
	// TimeoutMs bounds the wait when the engine has a fresh value but
	// the wire envelope is still being assembled. Default 5000 ms when
	// zero. Does not affect the multi-minute cold-start fan-out; that
	// path returns immediately with State="computing".
	TimeoutMs int `json:"timeout_ms,omitempty"`
}

BreadthSPXParams is the input for MethodBreadthSPX. All fields are optional with sensible defaults — the dashboard generator calls this with empty params for the canonical view.

type BreadthSPXResult

type BreadthSPXResult struct {
	// State classifies the engine pipeline at the moment this envelope
	// was assembled (cold / computing / ready / degraded). Consumers
	// should branch on this, not on (value==0 && history==[]) heuristics.
	// See BreadthState docs for semantics.
	State BreadthState `json:"state"`
	// Refreshing is true when a newer breadth run is in flight or waiting to
	// retry while this envelope serves the last good snapshot.
	Refreshing bool `json:"refreshing,omitempty"`
	// Refresh is the current or most recently completed paced-pass progress.
	// It remains available after completion so operators can distinguish a
	// slow advancing run, a stopped run, and the last classified failure.
	Refresh *BreadthRefreshProgress `json:"refresh,omitempty"`
	// PctAbove50DMA is the current fast-window reading: percentage of
	// S&P 500 constituents trading above their own 50-day SMA. 0-100;
	// 50 is the symmetric midpoint. Spec rule of thumb: > 55 healthy,
	// 40-55 watch, < 40 with SPX at highs is the classic late-cycle
	// divergence. Zero is meaningful only when State == "ready" (a
	// State other than "ready" can carry the field at 0 as the "no
	// data yet" sentinel).
	PctAbove50DMA float64 `json:"pct_above_50dma"`
	// PctAbove200DMA is the slow-window reading: percentage above the
	// 200-day SMA. Caught the 1999 and 2021 cyclical tops cleanly.
	// Bands per locked plan: below 40% = red / 40-60% = yellow / above
	// 60% = green (calibrated to the post-Mag-7 era).
	PctAbove200DMA float64 `json:"pct_above_200dma"`
	// NewHighsToday is the count of constituents whose latest close
	// strictly exceeded their trailing 252-bar max (~1 year of
	// trading sessions ≈ "52-week high"). Names with < 252 sessions
	// of cached history are skipped.
	NewHighsToday int `json:"new_highs_today"`
	// NewLowsToday is the symmetric count for new 252-bar lows.
	NewLowsToday int `json:"new_lows_today"`
	// NetNewHighsPct is (NewHighsToday - NewLowsToday) / coverage × 100
	// where coverage is the count of names with enough history to
	// contribute. The classic "narrow rally" pattern is SPX near
	// highs with NetNewHighsPct near zero or negative — a small
	// number of mega-caps carrying the index while the median name
	// is rolling over.
	NetNewHighsPct float64 `json:"net_new_highs_pct"`
	// History is the trailing daily series, oldest first. Length is
	// bounded by BreadthSPXParams.HistoryDays. Each point carries
	// both SMA readings plus the new-highs/lows counts.
	History []BreadthDailyValue `json:"history,omitempty"`
	// Source identifies the data provenance for the headline value.
	// Free-form; renderers display verbatim.
	Source string `json:"source"`
	// Method is a short token naming the computation path so renderers
	// can disclose methodology. Current token:
	// "constituent-fanout-50/200dma+nh-v2"
	// (50-DMA + 200-DMA + new highs/lows over 252-bar rolling
	// max/min — all computed locally from constituent daily closes
	// pulled via IBKR's historical-bar feed, since IBKR doesn't
	// redistribute the underlying S&P DJI / NYSE breadth indices on
	// retail subscriptions).
	Method string `json:"method"`
	// AsOf is the daemon's wall-clock when the result was assembled.
	AsOf time.Time `json:"as_of"`
	// SessionKey is the US-equity session date represented by the
	// computed daily bars. It may differ from AsOf on weekends,
	// holidays, and before the current session's close is settled.
	SessionKey string `json:"session_key,omitempty"`
	// Stale reports that SessionKey is not the latest completed US-equity
	// session — the reading is a real past close, not the current one.
	// The engine withholds a below-coverage refresh and keeps serving the
	// previous snapshot, so a lane that stops producing serves plausible
	// numbers indefinitely; this is the field that dates them. It is
	// deliberately separate from State, which stays "ready" for a stale
	// snapshot: State gates whether regime, composite, and the brief
	// consume breadth at all, and a stale close is still evidence there.
	Stale bool `json:"stale,omitempty"`
	// SpotAt is the gateway-observation timestamp for the headline,
	// distinct from AsOf which covers history + headline.
	SpotAt time.Time `json:"spot_at,omitzero"`
	// DataType reflects the gateway's feed state when the headline
	// was captured — "live", "delayed", "frozen", "delayed-frozen",
	// or "" when no notice has arrived yet. Renderers use this to
	// dim the headline.
	DataType string `json:"data_type,omitempty"`
}

BreadthSPXResult is the payload for MethodBreadthSPX. The two SMA percentages plus the new-highs/lows count are surfaced as separate fields so consumers can read each independently; History carries the trailing daily series for sparkline rendering. Threshold derivation (green / yellow / red) is left to the renderer — the spec itself says thresholds should be tunable, so the daemon stays out of that policy choice.

The Source / Method strings name the data provenance and computation path so renderers can disclose how the number was derived. Method is a short token; longer methodology disclosure lives in the spec doc.

type BreadthState

type BreadthState string

BreadthState classifies the engine's compute-pipeline state at the moment a result envelope was assembled. Distinct from a generic "status" because the consumer's branching logic depends on which state the engine is in, not just whether the value is present:

  • cold: no snapshot has ever been computed AND no refresh is in flight. The engine exists but hasn't been kicked yet. Treat as "indicator not yet available" — typically only seen during the ~few-second window between daemon start and postConnectSetup launching the scheduler.
  • computing: no snapshot exists yet and a refresh is in flight. Renderers show a loading state.
  • ready: a snapshot exists. Value/History are authoritative enough to rank; Refreshing says whether a newer snapshot is being computed.
  • degraded: a snapshot exists but its coverage is below the engine's threshold (e.g. partial fan-out completed). Value is present but should be rendered with a warning — the underlying constituent coverage is insufficient.

Codified on the wire (rather than left as a side-channel via engine.IsRefreshing) so every consumer reads the same state without remembering to call a sibling method or infer readiness from zero values.

const (
	BreadthStateCold      BreadthState = "cold"
	BreadthStateComputing BreadthState = "computing"
	BreadthStateReady     BreadthState = "ready"
	BreadthStateDegraded  BreadthState = "degraded"
)

Breadth states distinguish startup and computation progress from usable and coverage-degraded snapshots.

type BriefAccountRow

type BriefAccountRow struct {
	BriefRowState
	EquityBase   *float64  `json:"equity_base,omitempty"`
	DailyPnLBase *float64  `json:"daily_pnl_base,omitempty"`
	BaseCurrency string    `json:"base_currency,omitempty"`
	AsOf         time.Time `json:"as_of,omitzero"`
}

BriefAccountRow reports base-currency equity and P&L. Nil amounts mean the observation is unavailable.

type BriefAckParams

type BriefAckParams struct {
	Kind             string `json:"kind"`
	BriefFingerprint string `json:"brief_fingerprint"`
	Month            string `json:"month,omitempty"`
	Evidence         string `json:"evidence,omitempty"`
	Origin           string `json:"origin,omitempty"`
}

BriefAckParams identifies the exact rendered brief being attested.

type BriefAckResult

type BriefAckResult struct {
	OK               bool      `json:"ok"`
	Kind             string    `json:"kind"`
	Day              string    `json:"day"`
	At               time.Time `json:"at"`
	AlreadyStamped   bool      `json:"already_stamped,omitempty"`
	BriefFingerprint string    `json:"brief_fingerprint,omitempty"`
	Month            string    `json:"month,omitempty"`
	Evidence         string    `json:"evidence,omitempty"`
	Message          string    `json:"message,omitempty"`
}

BriefAckResult reports a new stamp or an idempotent already-complete no-op.

type BriefArtefact

type BriefArtefact struct {
	BriefRowState
	Kind        string    `json:"kind"`
	Cadence     string    `json:"cadence"` // daily | weekly
	Declared    bool      `json:"declared"`
	Completed   bool      `json:"completed"`
	CompletedAt time.Time `json:"completed_at,omitzero"`
}

BriefArtefact reports declared cadence evidence and completion time.

type BriefArtefactsRow

type BriefArtefactsRow struct {
	BriefRowState
	Rows []BriefArtefact `json:"rows"`
}

BriefArtefactsRow lists cadence artefacts and rolls up their row state.

type BriefAutoExtendRow

type BriefAutoExtendRow struct {
	BriefRowState
	ReportID string    `json:"report_id,omitempty"`
	At       time.Time `json:"at,omitzero"`
}

BriefAutoExtendRow reports clean-report automatic extension evidence.

type BriefBreadthRow

type BriefBreadthRow struct {
	BriefRowState
	PctAbove50DMA  *float64  `json:"pct_above_50dma,omitempty"`
	PctAbove200DMA *float64  `json:"pct_above_200dma,omitempty"`
	NetNewHighsPct *float64  `json:"net_new_highs_pct,omitempty"`
	AsOf           time.Time `json:"as_of,omitzero"`
	DataType       string    `json:"data_type,omitempty"`
}

BriefBreadthRow summarizes breadth values and their observation time. Nil metrics mean unavailable, not zero.

type BriefCalendarSection

type BriefCalendarSection struct {
	BriefRowState
	Session      BriefSessionRow       `json:"session"`
	MarketEvents []BriefMarketEventRow `json:"market_events"`
}

BriefCalendarSection groups session and held-name event context.

type BriefCapitalEventsRow

type BriefCapitalEventsRow struct {
	BriefRowState
	Latched            bool      `json:"latched"`
	LatchedAt          time.Time `json:"latched_at,omitzero"`
	LatchAgeDays       *int      `json:"latch_age_days,omitempty"`
	ConsumedPctAtLatch *float64  `json:"consumed_pct_at_latch,omitempty"`
	AdjustedPeakBase   *float64  `json:"adjusted_peak_base,omitempty"`
	PeakAsOf           time.Time `json:"peak_as_of,omitzero"`
	BaseCurrency       string    `json:"base_currency,omitempty"`
}

BriefCapitalEventsRow frames the drawdown latch and adjusted-peak provenance as post-trade capital events for the Review movement. The fields mirror the existing latch/peak facts; nothing new is invented.

type BriefCapitalRow

type BriefCapitalRow struct {
	BriefRowState
	Tier             string   `json:"tier,omitempty"`
	Enforcement      string   `json:"enforcement,omitempty"`
	ConsumedPct      *float64 `json:"consumed_pct,omitempty"`
	DrawdownBase     *float64 `json:"drawdown_base,omitempty"`
	AdjustedPeakBase *float64 `json:"adjusted_peak_base,omitempty"`
	// PeakAsOf is when the current adjusted peak was observed. Provenance,
	// not decoration: a peak stamped during a closed session or a reconnect
	// window is the tell that exposes a poisoned observation.
	PeakAsOf     time.Time `json:"peak_as_of,omitzero"`
	BaseCurrency string    `json:"base_currency,omitempty"`
}

BriefCapitalRow reports drawdown capacity and peak provenance. Pointer amounts remain nil when unavailable.

type BriefCountRow

type BriefCountRow struct {
	BriefRowState
	Count *int `json:"count,omitempty"`
}

BriefCountRow reports an optional count; nil means unavailable, not zero.

type BriefGammaRow

type BriefGammaRow struct {
	BriefRowState
	Spot      *float64  `json:"spot,omitempty"`
	ZeroGamma *float64  `json:"zero_gamma,omitempty"`
	GapPct    *float64  `json:"gap_pct,omitempty"`
	GammaSign string    `json:"gamma_sign,omitempty"`
	AsOf      time.Time `json:"as_of,omitzero"`
}

BriefGammaRow summarizes the current zero-gamma relationship. Nil values mean unavailable, not zero.

type BriefLastSessionRow added in v2.7.0

type BriefLastSessionRow struct {
	BriefRowState
	SessionDate  string    `json:"session_date,omitempty"`
	DailyPnLBase *float64  `json:"daily_pnl_base,omitempty"`
	BaseCurrency string    `json:"base_currency,omitempty"`
	SessionClose time.Time `json:"session_close,omitzero"`
	CapturedAt   time.Time `json:"captured_at,omitzero"`
}

BriefLastSessionRow is the daemon's close capture of the last completed session's account Daily P&L: the reqPnL account frame observed at (or on the first frame after) that session's official close, keyed by session date. Unlike SessionPnL it never moves on off-session marks. Nil DailyPnLBase with a populated SessionDate means that close was not captured — the daemon was not running and connected inside the capture window — and surfaces must say so rather than substitute a drifted running value.

type BriefLatchRow

type BriefLatchRow struct {
	BriefRowState
	Latched bool      `json:"latched"`
	At      time.Time `json:"latched_at,omitzero"`
	AgeDays *int      `json:"age_days,omitempty"`
	// ConsumedPctAtLatch is the consumed share recorded when the latch
	// engaged, so later data glitches cannot rewrite why it fired.
	ConsumedPctAtLatch *float64 `json:"consumed_pct_at_latch,omitempty"`
}

BriefLatchRow reports durable drawdown-latch state and its original trigger.

type BriefMarketEventRow

type BriefMarketEventRow struct {
	BriefRowState
	Kind    string   `json:"kind"` // earnings | halt | ssr | borrow
	Count   int      `json:"count"`
	Symbols []string `json:"symbols,omitempty"`
}

BriefMarketEventRow summarizes one approved held-name event family.

type BriefMarketSection

type BriefMarketSection struct {
	BriefRowState
	Regime  BriefRegimeRow  `json:"regime"`
	Breadth BriefBreadthRow `json:"breadth"`
	Gamma   BriefGammaRow   `json:"gamma"`
	Stress  BriefStressRow  `json:"stress"`
}

BriefMarketSection groups broad-market and Stress rows.

type BriefMoneyCoverageRow

type BriefMoneyCoverageRow struct {
	BriefRowState
	AmountBase   *float64 `json:"amount_base,omitempty"`
	BaseCurrency string   `json:"base_currency,omitempty"`
	IncludedLegs int      `json:"included_legs"`
	ExcludedLegs int      `json:"excluded_legs"`
}

BriefMoneyCoverageRow reports a base-currency aggregate and explicit leg coverage. AmountBase is nil when complete conversion is unavailable.

type BriefMonthlyPulseRow

type BriefMonthlyPulseRow struct {
	Status      string    `json:"status"` // not_due | due | completed | blocked
	Month       string    `json:"month,omitempty"`
	DueAt       time.Time `json:"due_at,omitzero"`
	CompletedAt time.Time `json:"completed_at,omitzero"`
}

BriefMonthlyPulseRow has its own status vocabulary rather than embedding BriefRowState (whose status is ok|degraded|unavailable). It remains optional until the later daemon composition lands, preserving current brief identity.

type BriefMover

type BriefMover struct {
	Symbol       string  `json:"symbol"`
	DailyPnLBase float64 `json:"daily_pnl_base"`
}

BriefMover is one underlying's base-currency daily P&L contribution.

type BriefMoversRow

type BriefMoversRow struct {
	BriefRowState
	Rows         []BriefMover `json:"rows"`
	OtherPnLBase *float64     `json:"other_daily_pnl_base,omitempty"`
	OtherCount   int          `json:"other_count,omitempty"`
}

BriefMoversRow aggregates daily P&L by underlying (stock plus option legs per name — the same basis as the Underlyings panel) so the two surfaces reconcile. OtherPnLBase/OtherCount carry the residual beyond the top rows so the row's implied total matches the account daily P&L attribution.

type BriefNarrative added in v2.6.0

type BriefNarrative struct {
	Lead   []BriefRun       `json:"lead,omitempty"`
	Review []BriefParagraph `json:"review,omitempty"`
	Ready  []BriefParagraph `json:"ready,omitempty"`
	Coda   []BriefRun       `json:"coda,omitempty"`
}

BriefNarrative is the daemon-composed prose reading of the same two movements BriefResult already carries. It states served facts and their served statuses in fixed template language and adds no fact of its own, so it stays outside the brief content identity: BriefFingerprint hashes Review and Ready only, and a prose revision can never invalidate a stamped brief. Absent when an older daemon serves the brief; surfaces fall back to the row render.

type BriefOneTapRow

type BriefOneTapRow struct {
	BriefRowState
	ReportID string   `json:"report_id,omitempty"`
	Signable bool     `json:"signable"`
	Blockers []string `json:"blockers,omitempty"`
}

BriefOneTapRow reports whether the referenced reconciliation report can be signed and, if not, its stable blockers.

type BriefOverride

type BriefOverride struct {
	Control   string    `json:"control"`
	ExpiresAt time.Time `json:"expires_at"`
}

BriefOverride identifies one active control override and expiry.

type BriefOverridesRow

type BriefOverridesRow struct {
	BriefRowState
	Rows []BriefOverride `json:"rows"`
}

BriefOverridesRow lists active overrides; an empty list is conclusive only when the embedded row state is OK.

type BriefParagraph added in v2.6.0

type BriefParagraph struct {
	Runs []BriefRun `json:"runs,omitempty"`
}

BriefParagraph is one composed paragraph as an ordered run sequence.

type BriefPolicyDriftRow

type BriefPolicyDriftRow struct {
	BriefRowState
	Rows []PolicyPinStatus `json:"rows"`
}

BriefPolicyDriftRow lists sibling-policy pin status.

type BriefPortfolioSection

type BriefPortfolioSection struct {
	BriefRowState
	Account       BriefAccountRow       `json:"account"`
	Movers        BriefMoversRow        `json:"movers"`
	PremiumAtRisk BriefMoneyCoverageRow `json:"premium_at_risk"`
	HedgeCost     BriefMoneyCoverageRow `json:"hedge_cost"`
	WorkingOrders BriefCountRow         `json:"working_orders"`
}

BriefPortfolioSection groups account, attribution, option-money, and order observations.

type BriefProcessSection

type BriefProcessSection struct {
	BriefRowState
	Reconcile    BriefReconcileRow     `json:"reconcile"`
	AutoExtend   BriefAutoExtendRow    `json:"auto_extend"`
	OneTap       BriefOneTapRow        `json:"one_tap"`
	RulesDelta   BriefRulesDeltaRow    `json:"rules_delta"`
	Artefacts    BriefArtefactsRow     `json:"artefacts"`
	MonthlyPulse *BriefMonthlyPulseRow `json:"monthly_pulse,omitempty"`
}

BriefProcessSection groups reconciliation and recurring process evidence.

type BriefProposalsRow

type BriefProposalsRow struct {
	BriefRowState
	Day     string `json:"day,omitempty"`
	Offered int    `json:"offered"`
	Acted   int    `json:"acted"`
}

BriefProposalsRow reports how many protection proposals were offered versus acted on over the most recent recorded session, derived read-only from the trade-proposal-outcomes journal. It carries counts and the covered day only: no proposal keys, symbols, order references, or tokens reach the wire.

type BriefReadyProposalsRow added in v2.6.0

type BriefReadyProposalsRow struct {
	BriefRowState
	// Actionable is the served count of proposals with no blockers; Blocked
	// is the remainder of Total. Zero is a measured zero only when the
	// embedded row state is OK.
	Actionable int `json:"actionable"`
	Blocked    int `json:"blocked"`
	Total      int `json:"total"`
}

BriefReadyProposalsRow reports how many protection proposals the daemon currently ranks as actionable for the session ahead, read-only from the live proposal snapshot. It is the pre-trade twin of BriefProposalsRow's post-trade journal counts, and it carries counts only: no proposal keys, symbols, contracts, order references, or preview tokens reach the wire. Stating that work is staged is not authority to place it — every submit keeps its own gating.

type BriefReadySection

type BriefReadySection struct {
	BriefRowState
	Regime        BriefRegimeRow         `json:"regime"`
	Breadth       BriefBreadthRow        `json:"breadth"`
	Gamma         BriefGammaRow          `json:"gamma"`
	Stress        BriefStressRow         `json:"stress"`
	Session       BriefSessionRow        `json:"session"`
	MarketEvents  []BriefMarketEventRow  `json:"market_events"`
	Capital       BriefCapitalRow        `json:"capital"`
	Latch         BriefLatchRow          `json:"latch"`
	PremiumAtRisk BriefMoneyCoverageRow  `json:"premium_at_risk"`
	HedgeCost     BriefMoneyCoverageRow  `json:"hedge_cost"`
	Proposals     BriefReadyProposalsRow `json:"proposals"`
	PolicyDrift   BriefPolicyDriftRow    `json:"policy_drift"`
	Artefacts     BriefArtefactsRow      `json:"artefacts"`
	MonthlyPulse  *BriefMonthlyPulseRow  `json:"monthly_pulse,omitempty"`
}

BriefReadySection is the pre-trade movement for today. Its rows regroup the existing market, calendar, risk-capacity, and desk-readiness facts.

type BriefReconcileRow

type BriefReconcileRow struct {
	BriefRowState
	LastReconciledAt time.Time `json:"last_reconciled_at,omitzero"`
	Source           string    `json:"source,omitempty"`
	Deadline         time.Time `json:"deadline,omitzero"`
	DaysRemaining    *int      `json:"days_remaining,omitempty"`
}

BriefReconcileRow reports the latest reconciliation and its next deadline.

type BriefRegimeRow

type BriefRegimeRow struct {
	BriefRowState
	Stage   string `json:"stage,omitempty"`
	Verdict string `json:"verdict,omitempty"`
}

BriefRegimeRow summarizes the current regime lifecycle and verdict.

type BriefResult

type BriefResult struct {
	AsOf              time.Time          `json:"as_of"`
	BriefFingerprint  string             `json:"brief_fingerprint"`
	StampTarget       string             `json:"stamp_target,omitempty"`
	StampTargetReason string             `json:"stamp_target_reason,omitempty"`
	Review            BriefReviewSection `json:"review"`
	Ready             BriefReadySection  `json:"ready"`
	Narrative         *BriefNarrative    `json:"narrative,omitempty"`
}

BriefResult is the complete typed daily brief, composed as two process movements: Review (post-trade since the last regular close) and Ready (pre-trade for today). BriefFingerprint hashes the two composed movements only; AsOf, Narrative, and stamp-target state are deliberately outside the content identity. The daemon composes both movements; surfaces render them verbatim.

type BriefReviewSection

type BriefReviewSection struct {
	BriefRowState
	SessionPnL    BriefAccountRow       `json:"session_pnl"`
	LastSession   BriefLastSessionRow   `json:"last_session"`
	Attribution   BriefMoversRow        `json:"attribution"`
	RulesDelta    BriefRulesDeltaRow    `json:"rules_delta"`
	Proposals     BriefProposalsRow     `json:"proposals"`
	Overrides     BriefOverridesRow     `json:"overrides"`
	CapitalEvents BriefCapitalEventsRow `json:"capital_events"`
	Reconcile     BriefReconcileRow     `json:"reconcile"`
	AutoExtend    BriefAutoExtendRow    `json:"auto_extend"`
	OneTap        BriefOneTapRow        `json:"one_tap"`
	WorkingOrders BriefCountRow         `json:"working_orders"`
}

BriefReviewSection is the post-trade movement since the last regular close. Its rows are a regrouping of existing brief facts (plus the read-only proposals-offered-vs-acted derivation and the last-session close capture); the section rolls up its worst child exactly like every other brief section.

type BriefRiskSection

type BriefRiskSection struct {
	BriefRowState
	Capital     BriefCapitalRow     `json:"capital"`
	Latch       BriefLatchRow       `json:"latch"`
	Overrides   BriefOverridesRow   `json:"overrides"`
	PolicyDrift BriefPolicyDriftRow `json:"policy_drift"`
}

BriefRiskSection groups capital, latch, override, and policy-drift evidence.

type BriefRowState

type BriefRowState struct {
	Status string `json:"status"`
	Detail string `json:"detail"`
}

BriefRowState is embedded by every brief row and section. Detail is human-facing disclosure; Status is one of ok, attention, degraded, or unavailable. Sections roll up their worst child (attention outranks degraded) and state completeness in Detail.

type BriefRuleTransition

type BriefRuleTransition struct {
	RuleID string `json:"rule_id"`
	From   string `json:"from"`
	To     string `json:"to"`
}

BriefRuleTransition records one rule's state change.

type BriefRulesDeltaRow

type BriefRulesDeltaRow struct {
	BriefRowState
	BaselineAt                 time.Time             `json:"baseline_at,omitzero"`
	Transitions                []BriefRuleTransition `json:"transitions,omitempty"`
	Added                      []string              `json:"added,omitempty"`
	Removed                    []string              `json:"removed,omitempty"`
	RulebookFingerprintChanged bool                  `json:"rulebook_fingerprint_changed"`
	BaselineFingerprint        string                `json:"baseline_fingerprint,omitempty"`
	CurrentFingerprint         string                `json:"current_fingerprint,omitempty"`
}

BriefRulesDeltaRow compares the current rulebook with its retained baseline.

type BriefRun added in v2.6.0

type BriefRun struct {
	Text string `json:"text"`
	Role string `json:"role,omitempty"`
}

BriefRun is one typed span of composed narrative text. Runs are text, never markup: the daemon emits the spans and each surface decides how a role renders.

type BriefSessionRow

type BriefSessionRow struct {
	BriefRowState
	Market   string    `json:"market,omitempty"`
	State    string    `json:"state,omitempty"`
	IsOpen   bool      `json:"is_open"`
	Open     time.Time `json:"open,omitzero"`
	Close    time.Time `json:"close,omitzero"`
	NextOpen time.Time `json:"next_open,omitzero"`
}

BriefSessionRow reports the official market session and next opening time.

type BriefSnapshotParams

type BriefSnapshotParams struct{}

BriefSnapshotParams is deliberately empty. In particular it carries no origin: reads never gain write authority from their caller.

type BriefStressRow

type BriefStressRow struct {
	BriefRowState
	Action   string `json:"action,omitempty"`
	Severity string `json:"severity,omitempty"`
	Summary  string `json:"summary,omitempty"`
}

BriefStressRow summarizes the current advisory action and severity.

type CancelParams

type CancelParams struct {
	ID string `json:"id"`
}

CancelParams cancels an in-flight stream by id.

type CapitalEventEntry

type CapitalEventEntry struct {
	At          time.Time `json:"at"`
	Type        string    `json:"type"`
	AmountBase  float64   `json:"amount_base,omitempty"`
	EffectiveAt time.Time `json:"effective_at,omitzero"`
	Note        string    `json:"note,omitempty"`
	Origin      string    `json:"origin,omitempty"`
	ReportID    string    `json:"report_id,omitempty"`
}

CapitalEventEntry is one authoritative declared-capital event rendered alongside the equity series.

type CapitalEventParams

type CapitalEventParams struct {
	// Type is deposit | withdrawal | reconcile.
	Type string `json:"type"`
	// AmountBase is required for deposit/withdrawal (positive), ignored
	// for reconcile.
	AmountBase float64 `json:"amount_base,omitempty"`
	// EffectiveAt is when the flow hit the account; zero means now. A
	// deposit declared after the peak already reflected it corrects the
	// peak downward (never-inflate discipline).
	EffectiveAt time.Time `json:"effective_at,omitzero"`
	Note        string    `json:"note,omitempty"`
	// Report is required for type reconcile since phase 3a: the recon
	// report id being signed off. The daemon refuses a reconcile whose
	// report is missing, stale, superseded, or carries unresolved
	// exceptions (internal-docs/design/post-trade-truth.md).
	Report string `json:"report,omitempty"`
	// Origin is the write-origin claim; the daemon rejects non-human
	// origins for every risk-policy write.
	Origin string `json:"origin,omitempty"`
}

CapitalEventParams declares one capital fact in base currency.

type CapitalStateReport

type CapitalStateReport struct {
	Tier string `json:"tier"` // ok | warn | block | unknown | unapproved
	// Enforcement echoes the block tier's class so a "block" tier is
	// legible as shadow/advisory until promotion.
	Enforcement string `json:"enforcement"`
	// BoundAccount is the broker account this capital document adopted at its
	// first live observation. The drawdown ladder follows this account, not
	// the session pin: a session connected to a different account or mode
	// reads Tier "unknown" with this field naming the binding, rather than a
	// drawdown computed from one account's equity against another account's
	// peak. Empty until first adoption.
	BoundAccount             string    `json:"bound_account,omitempty"`
	EquityBase               *float64  `json:"equity_base,omitempty"`
	EquityAsOf               time.Time `json:"equity_as_of,omitzero"`
	EquityStale              bool      `json:"equity_stale,omitempty"`
	EffectiveRiskCapitalBase *float64  `json:"effective_risk_capital_base,omitempty"`
	AdjustedPeakBase         *float64  `json:"adjusted_peak_base,omitempty"`
	PeakAsOf                 time.Time `json:"peak_as_of,omitzero"`
	CumExternalFlowsBase     *float64  `json:"cum_external_flows_base,omitempty"`
	DeclaredCumFlowsBase     *float64  `json:"declared_cum_flows_base,omitempty"`
	StatementCumFlowsBase    *float64  `json:"statement_cum_flows_base,omitempty"`
	FlowSource               string    `json:"flow_source,omitempty"` // declared | statement
	DrawdownBase             *float64  `json:"drawdown_base,omitempty"`
	ConsumedPct              *float64  `json:"consumed_pct,omitempty"`
	BlockLatched             bool      `json:"block_latched"`
	LatchedAt                time.Time `json:"latched_at,omitzero"`
	// LatchConsumedPct is the consumed share at the moment the latch engaged.
	// Disclosed so a later data glitch inflating the live ConsumedPct cannot
	// retroactively misrepresent why the latch fired.
	LatchConsumedPct      *float64  `json:"latch_consumed_pct,omitempty"`
	LastReconciledAt      time.Time `json:"last_reconciled_at,omitzero"`
	LastReconcileReportID string    `json:"last_reconcile_report_id,omitempty"`
	LastReconcileSource   string    `json:"last_reconcile_source,omitempty"` // human | automatic
	ReconcileStale        bool      `json:"reconcile_stale,omitempty"`
	Reasons               []string  `json:"reasons,omitempty"`
	BaseCurrency          string    `json:"base_currency,omitempty"`
}

CapitalStateReport is the runtime capital state, evaluated.

type ChainExpiriesParams

type ChainExpiriesParams struct {
	Symbol        string `json:"symbol"`
	WithIV        bool   `json:"with_iv,omitempty"`
	AllExpiries   bool   `json:"all_expiries,omitempty"`
	RequireLiveIV bool   `json:"require_live_iv,omitempty"`
	MinDTE        int    `json:"min_dte,omitempty"`
	MaxDTE        int    `json:"max_dte,omitempty"`
	TargetDTE     int    `json:"target_dte,omitempty"`
}

ChainExpiriesParams is the input for MethodChainExpiries.

WithIV asks the daemon to fetch ATM implied volatility per expiry. The daemon caches results, picks the ATM strike per expiry, and runs the per-expiry subscribes through a bounded worker pool — first call costs a few seconds for a typical name, subsequent calls within the cache TTL are instant.

AllExpiries lifts the default cap (the 12 nearest expiries). Off by default because the back-half LEAPS are rarely consulted and pay the IV-fetch cost for no decision value.

MinDTE/MaxDTE/TargetDTE narrow expiry-list mode before any IV fan-out. TargetDTE returns the single listed expiry closest to the requested day count, after MinDTE/MaxDTE filtering when those are also set. This lets agents ask for "roughly 120 DTE" without fetching IV for every weekly.

Empty Symbol → bad_request.

type ChainExpiriesResult

type ChainExpiriesResult struct {
	Symbol         string        `json:"symbol"`
	Spot           float64       `json:"spot,omitempty"`
	SpotSource     string        `json:"spot_source,omitempty"`
	SpotAsOf       time.Time     `json:"spot_as_of,omitzero"`
	Expiries       []ChainExpiry `json:"expiries"`
	WarningDetails []DataWarning `json:"warning_details,omitempty"`
	AsOf           time.Time     `json:"as_of"`
}

ChainExpiriesResult is MethodChainExpiries' payload. Expiries are sorted ascending and deduped across exchanges by the daemon.

Spot is the underlying mid the daemon used to pick the per-expiry ATM strike and to compute ImpliedMove. Zero when the spot probe failed or WithIV wasn't requested. SpotSource names the selected-price source ("last", "mid", "prev_close", "historical_close", ...); SpotAsOf is the best timestamp known for that selected price.

type ChainExpiry

type ChainExpiry struct {
	Date           string    `json:"date"` // YYYY-MM-DD
	DTE            int       `json:"dte,omitempty"`
	IV             *float64  `json:"iv,omitempty"`
	IVStatus       string    `json:"iv_status,omitempty"`
	IVSource       string    `json:"iv_source,omitempty"`
	IVQuality      string    `json:"iv_quality,omitempty"`
	IVAsOf         time.Time `json:"iv_as_of,omitzero"`
	ImpliedMove    *float64  `json:"implied_move,omitempty"`
	ImpliedMovePct *float64  `json:"implied_move_pct,omitempty"`
}

ChainExpiry is one row in MethodChainExpiries' response. IV is nil when --with-iv wasn't requested or when the per-strike IV fetch timed out; IVStatus disambiguates ("ok" | "unavailable" | "timeout"). IVSource names how the value was obtained ("live_model" | "cached" | "unavailable"); IVQuality tells consumers whether to trust it for term-structure decisions ("live_model" | "cached" | "reused_fallback" | "unavailable").

DTE is the integer day count from "today (local)" to the expiry date, inclusive of the expiry day (so a same-day expiry has DTE=0, next-day has DTE=1). Surfaced separately from ImpliedMove so consumers can derive their own term-structure math.

ImpliedMove is the 1-σ expected dollar move by expiration, computed as spot × IV × √(DTE/365). Populated only when IV and spot are both available; otherwise nil. The matching ImpliedMovePct is the same value expressed as a fraction of spot (so `0.042` means 4.2%).

type ChainFetchParams

type ChainFetchParams struct {
	Symbol       string `json:"symbol"`
	Expiry       string `json:"expiry"`                  // YYYY-MM-DD
	Width        int    `json:"width"`                   // ATM ± width
	Side         string `json:"side"`                    // calls | puts | both
	TradingClass string `json:"trading_class,omitempty"` // SPX | SPXW for multi-class index chains; empty = auto
}

ChainFetchParams selects strikes around the spot price for an expiry.

type ChainLegSummary

type ChainLegSummary struct {
	Right     string   `json:"right"` // C | P
	Strike    float64  `json:"strike"`
	Bid       float64  `json:"bid,omitempty"`
	Ask       float64  `json:"ask,omitempty"`
	Mid       float64  `json:"mid,omitempty"`
	Spread    float64  `json:"spread,omitempty"`
	SpreadPct float64  `json:"spread_pct,omitempty"`
	OI        *int64   `json:"oi,omitempty"`
	Delta     *float64 `json:"delta,omitempty"`
}

ChainLegSummary is a compact executable-leg descriptor used by chain liquidity summaries. It duplicates a subset of ChainStrike side fields so a consumer can answer "which leg should I inspect first?" without walking the whole grid.

type ChainLiquiditySummary

type ChainLiquiditySummary struct {
	LiquidityGrade           string           `json:"liquidity_grade"` // good | fair | poor | untradable
	ATMSpreadPct             *float64         `json:"atm_spread_pct,omitempty"`
	NearestLiveCall          *ChainLegSummary `json:"nearest_live_call,omitempty"`
	NearestLivePut           *ChainLegSummary `json:"nearest_live_put,omitempty"`
	MinSpreadLiveStrike      *ChainLegSummary `json:"min_spread_live_strike,omitempty"`
	OICoveragePct            float64          `json:"oi_coverage_pct"`
	RecommendedStructureHint string           `json:"recommended_structure_hint"` // stock_only | shares_or_spreads | calls_ok | untradable_chain
}

ChainLiquiditySummary surfaces the decision-grade option-liquidity facts before the raw grid. Spread percentages are fractions (0.10 = 10%).

type ChainResult

type ChainResult struct {
	Symbol           string                 `json:"symbol"`
	TradingClass     string                 `json:"trading_class,omitempty"`
	Spot             float64                `json:"spot"`
	SpotSource       string                 `json:"spot_source,omitempty"`
	SpotAsOf         time.Time              `json:"spot_as_of,omitzero"`
	Expiry           string                 `json:"expiry"`
	DTE              int                    `json:"dte"`
	DataType         string                 `json:"data_type"`
	FeedType         string                 `json:"feed_type,omitempty"`
	SessionState     string                 `json:"session_state,omitempty"`
	TradableSummary  *ChainTradableSummary  `json:"tradable_summary,omitempty"`
	LiquiditySummary *ChainLiquiditySummary `json:"liquidity_summary,omitempty"`
	Strikes          []ChainStrike          `json:"strikes"`
	WarningDetails   []DataWarning          `json:"warning_details,omitempty"`
	AsOf             time.Time              `json:"as_of"`
}

ChainResult is MethodChainFetch's payload. SpotSource names the selected underlying price source used to anchor ATM ("last", "mid", "prev_close", "historical_close", ...); SpotAsOf is the best timestamp known for that selected price.

type ChainStrike

type ChainStrike struct {
	Strike float64 `json:"strike"`
	IsATM  bool    `json:"is_atm,omitempty"`

	CallBid        *float64  `json:"call_bid"`
	CallAsk        *float64  `json:"call_ask"`
	CallLast       *float64  `json:"call_last"`
	CallPrevClose  *float64  `json:"call_prev_close,omitempty"`
	CallIV         *float64  `json:"call_iv"`
	CallDelta      *float64  `json:"call_delta"`
	CallOI         *int64    `json:"call_oi"`
	CallAsOf       time.Time `json:"call_as_of,omitzero"`
	CallDataStatus string    `json:"call_data_status,omitempty"`
	CallIVStatus   string    `json:"call_iv_status,omitempty"`
	CallOIStatus   string    `json:"call_oi_status,omitempty"`

	PutBid        *float64  `json:"put_bid"`
	PutAsk        *float64  `json:"put_ask"`
	PutLast       *float64  `json:"put_last"`
	PutPrevClose  *float64  `json:"put_prev_close,omitempty"`
	PutIV         *float64  `json:"put_iv"`
	PutDelta      *float64  `json:"put_delta"`
	PutOI         *int64    `json:"put_oi"`
	PutAsOf       time.Time `json:"put_as_of,omitzero"`
	PutDataStatus string    `json:"put_data_status,omitempty"`
	PutIVStatus   string    `json:"put_iv_status,omitempty"`
	PutOIStatus   string    `json:"put_oi_status,omitempty"`
}

ChainStrike is one strike row in a chain.

type ChainTradableSummary

type ChainTradableSummary struct {
	TotalLegs          int     `json:"total_legs"`
	LiveBidAskLegs     int     `json:"live_bid_ask_legs"`
	OneSidedLiveLegs   int     `json:"one_sided_live_legs"`
	StaleLegs          int     `json:"stale_legs"`
	ModelOnlyLegs      int     `json:"model_only_legs"`
	SubscribeErrorLegs int     `json:"subscribe_error_legs"`
	NoQuoteLegs        int     `json:"no_quote_legs"`
	OICoveredLegs      int     `json:"oi_covered_legs"`
	OICoveragePct      float64 `json:"oi_coverage_pct"`
	OptionsTradable    bool    `json:"options_tradable"`
	FeedGap            string  `json:"feed_gap,omitempty"` // stale_close_only | thin_contract | unknown_feed_gap
}

ChainTradableSummary is the top-level option-chain census a trader needs before reading strike rows. LiveBidAskLegs is the executable count; stale, model-only, subscribe-error, and no-quote counts explain why the rest are not immediately tradable.

type CompactSourceHealth

type CompactSourceHealth struct {
	Source       string         `json:"source"`
	Status       string         `json:"status"`
	AsOf         time.Time      `json:"as_of,omitzero"`
	Confidence   string         `json:"confidence,omitempty"`
	RefreshState string         `json:"refresh_state,omitempty"`
	NextAttempt  *time.Time     `json:"next_attempt,omitempty"`
	LastFailure  *SourceFailure `json:"last_failure,omitempty"`
	Notes        []string       `json:"notes,omitempty"`
}

CompactSourceHealth retains the status, reason, and freshness needed to interpret a compact result without raw upstream detail.

type ContractParams

type ContractParams struct {
	ConID        int     `json:"con_id,omitempty"`
	Symbol       string  `json:"symbol"`
	SecType      string  `json:"sec_type,omitempty"` // STK | OPT | FUT | IND (request-side; see asymmetry note)
	Market       string  `json:"market,omitempty"`   // us | de
	Exchange     string  `json:"exchange,omitempty"` // SMART, IBIS, ...
	PrimaryExch  string  `json:"primary_exchange,omitempty"`
	Currency     string  `json:"currency,omitempty"`
	LocalSymbol  string  `json:"local_symbol,omitempty"`
	TradingClass string  `json:"trading_class,omitempty"`
	Expiry       string  `json:"expiry,omitempty"` // YYYYMMDD
	Strike       float64 `json:"strike,omitempty"`
	Right        string  `json:"right,omitempty"` // C | P
	Multiplier   int     `json:"multiplier,omitempty"`
	// MinTick is the venue minimum price increment, enriched daemon-side from
	// broker contract details when known. Zero means unresolved: price
	// rounding falls back to a static grid (US 0.01 / EUR MiFID band).
	MinTick float64 `json:"min_tick,omitempty"`
}

ContractParams names a tradeable instrument on the REQUEST side.

Asymmetry to watch for: SecType here uses the IBKR API's three-letter short form ("STK", "OPT", "FUT", "IND") because that's what the gateway accepts in reqMktData / reqContractDetails. The RESPONSE side (PositionView.SecType) uses the full word ("STOCK", "OPTION", ...) — see the SecType* constants above. The two shapes flow on different paths and the gateway uses different vocabularies at each end; this type uses the request vocabulary.

Market is an optional shorthand for stock routing defaults. Empty / "us" preserves the legacy US SMART/USD path; "de" selects the German/Xetra EUR route used by IBKR's IBIS listing codes. Exchange/Currency/PrimaryExch override the shorthand when supplied.

SecType "STK" for stocks/ETFs; "OPT" for options (Expiry, Strike, Right required).

type CorrectPeakParams

type CorrectPeakParams struct {
	FromStatements bool    `json:"from_statements,omitempty"`
	PeakBase       float64 `json:"peak_base,omitempty"`
	Reason         string  `json:"reason"`
	Origin         string  `json:"origin,omitempty"`
}

CorrectPeakParams repairs a poisoned adjusted peak. Exactly one anchor must be chosen: FromStatements re-derives the peak from the retained-statement replay (evidence-based), or PeakBase supplies an explicit value. The latch is deliberately untouched — clearing it stays reset_drawdown's job.

type CurrencyExposure

type CurrencyExposure struct {
	Currency             string  `json:"currency"`
	NetLiquidationCcy    float64 `json:"net_liquidation_ccy"`
	CashCcy              float64 `json:"cash_ccy"`
	StockMarketValueCcy  float64 `json:"stock_market_value_ccy"`
	OptionMarketValueCcy float64 `json:"option_market_value_ccy"`
	UnrealizedPnLCcy     float64 `json:"unrealized_pnl_ccy"`
	RealizedPnLCcy       float64 `json:"realized_pnl_ccy"`
	ExchangeRate         float64 `json:"exchange_rate"`
	NetLiquidationBase   float64 `json:"net_liquidation_base"`
}

CurrencyExposure is one row in AccountResult.CurrencyExposure. Values are reported in the named currency (the "Ccy" suffix); the ExchangeRate field is BASE per CCY (i.e. "how many base-currency units 1 unit of the named currency converts to" — matches IBKR's $LEDGER semantics so reconciliation works without inversion). Fields are populated only when the gateway delivered them; absent fields are 0, never fabricated.

type DailyPnLObservation

type DailyPnLObservation struct {
	Status     DailyPnLObservationStatus `json:"status"`
	SessionKey string                    `json:"session_key,omitempty"`
	AsOf       time.Time                 `json:"as_of"`
}

DailyPnLObservation is the value-free health record for the account Daily P&L feed. SessionKey is the official US-equity session the state belongs to.

type DailyPnLObservationStatus

type DailyPnLObservationStatus string

DailyPnLObservationStatus is the closed set of Daily P&L feed states.

const (
	DailyPnLObservationOK      DailyPnLObservationStatus = "ok"
	DailyPnLObservationMissing DailyPnLObservationStatus = "missing"
	DailyPnLObservationInvalid DailyPnLObservationStatus = "invalid"
	DailyPnLObservationStale   DailyPnLObservationStatus = "stale"
	DailyPnLObservationNotDue  DailyPnLObservationStatus = "not_due"
)

Daily P&L observation statuses exposed across daemon surfaces.

type DataFarmHealth

type DataFarmHealth struct {
	Name    string    `json:"name"`
	Type    string    `json:"type,omitempty"`
	Status  string    `json:"status"`
	Code    int       `json:"code,omitempty"`
	Message string    `json:"message,omitempty"`
	AsOf    time.Time `json:"as_of,omitzero"`
}

DataFarmHealth is emitted on status.health only for data farms that currently need operator attention. Healthy farms are intentionally omitted to keep the normal status surface quiet.

type DataQualityHealth

type DataQualityHealth struct {
	Surface          string    `json:"surface"`
	Status           string    `json:"status"`
	CadenceState     string    `json:"cadence_state,omitempty"`
	Summary          string    `json:"summary,omitempty"`
	StaleClusters    []string  `json:"stale_clusters,omitempty"`
	PartialClusters  []string  `json:"partial_clusters,omitempty"`
	DegradedClusters []string  `json:"degraded_clusters,omitempty"`
	AsOf             time.Time `json:"as_of,omitzero"`
}

DataQualityHealth is a compact status.health diagnostic for decision surfaces that can serve a snapshot while carrying degraded or stale inputs. It is intentionally higher-level than regime.warning_details or gamma.warning_details: status answers whether downstream reads need extra caution, not every low-level row that caused it.

type DataWarning

type DataWarning struct {
	Code     string `json:"code"`
	Scope    string `json:"scope,omitempty"`
	Severity string `json:"severity,omitempty"`
	Message  string `json:"message"`
	Impact   string `json:"impact,omitempty"`
	Action   string `json:"action,omitempty"`
}

DataWarning is the common structured warning shape used by price-level tools. It deliberately matches RegimeWarning / GammaWarningDetail's JSON contract so agents can handle freshness and provenance uniformly.

type EarningsEvidenceReference

type EarningsEvidenceReference struct {
	Authority string `json:"authority"`
	Document  string `json:"document"`
	URL       string `json:"url"`
}

EarningsEvidenceReference is one allowlisted primary-source document used by the terminal classification. These strings are compiled authority, not instructions parsed from live provider content.

type EarningsIdentityInfo

type EarningsIdentityInfo struct {
	Outcome              string         `json:"outcome"`
	NotApplicable        bool           `json:"not_applicable,omitempty"`
	AttemptedAt          time.Time      `json:"attempted_at,omitzero"`
	ProofObservedAt      time.Time      `json:"proof_observed_at,omitzero"`
	ProofOutcome         string         `json:"proof_outcome,omitempty"`
	AuthorityRevision    int64          `json:"authority_revision,omitempty"`
	AuthorityFingerprint string         `json:"authority_fingerprint,omitempty"`
	ObservationID        string         `json:"observation_id,omitempty"`
	AuthorityBinding     string         `json:"authority_binding,omitempty"`
	NextAttempt          *time.Time     `json:"next_attempt,omitempty"`
	LastFailure          *SourceFailure `json:"last_failure,omitempty"`
}

EarningsIdentityInfo discloses the independent broker applicability read without exposing the held contract ID or raw broker StockType.

type EarningsInfo

type EarningsInfo struct {
	Symbol string `json:"symbol"`
	// Date is the next earnings date in ET (YYYY-MM-DD), empty when unknown.
	Date string `json:"date,omitempty"`
	// TimeOfDay is "amc", "bmo", or "" when unspecified.
	TimeOfDay string `json:"time_of_day,omitempty"`
	// Estimated marks provider-flagged estimated (unconfirmed) dates.
	Estimated bool `json:"estimated,omitempty"`
	// Source is fetched | override | broker_identity | security_type |
	// verified_terminal | unknown. Provider-level provenance lives in Providers;
	// Terminal carries the exact-contract evidence when no future issuer earnings
	// event applies.
	Source string `json:"source"`
	// SecurityType names the held security type when Source is security_type —
	// the canonical spelling of a type that has no issuer earnings at all. It is
	// the whole authority behind that classification, so consumers re-derive the
	// exemption from this field rather than trusting Source alone.
	SecurityType string `json:"security_type,omitempty"`
	// Status is date or a typed unresolved outcome. Conflicting provider
	// dates never populate Date.
	Status string `json:"status,omitempty"`
	// Reason is a stable aggregate explanation such as single_source or
	// conflicting_sources; it never contains provider free text.
	Reason string `json:"reason,omitempty"`
	// ObservedAt is when the fetched value was last confirmed from the
	// provider; zero for overrides and unknowns.
	ObservedAt time.Time              `json:"observed_at,omitzero"`
	Stale      bool                   `json:"stale,omitempty"`
	Providers  []EarningsProviderInfo `json:"providers,omitempty"`
	Identity   *EarningsIdentityInfo  `json:"identity,omitempty"`
	Terminal   *EarningsTerminalInfo  `json:"terminal,omitempty"`
}

EarningsInfo is the per-name earnings context the rules consumed, so surfaces can show where each date came from.

type EarningsProviderInfo

type EarningsProviderInfo struct {
	Provider     string         `json:"provider"`
	Status       string         `json:"status"`
	Date         string         `json:"date,omitempty"`
	TimeOfDay    string         `json:"time_of_day,omitempty"`
	Estimated    bool           `json:"estimated,omitempty"`
	ObservedAt   time.Time      `json:"observed_at,omitzero"`
	AttemptedAt  time.Time      `json:"attempted_at,omitzero"`
	NextAttempt  *time.Time     `json:"next_attempt,omitempty"`
	LastGoodDate string         `json:"last_good_date,omitempty"`
	LastFailure  *SourceFailure `json:"last_failure,omitempty"`
}

EarningsProviderInfo is one provider's latest typed outcome. A transport failure may coexist with a retained LastGoodDate, but Date is populated only when the latest attempt itself returned a usable date.

type EarningsTerminalInfo

type EarningsTerminalInfo struct {
	ContractConID        int                         `json:"contract_con_id"`
	Issuer               string                      `json:"issuer"`
	CIK                  string                      `json:"cik,omitempty"`
	Classification       string                      `json:"classification"`
	EffectiveDate        string                      `json:"effective_date"`
	VerifiedAt           time.Time                   `json:"verified_at"`
	RevalidateAfter      time.Time                   `json:"revalidate_after"`
	AuthorityRevision    int64                       `json:"authority_revision"`
	AuthorityReviewedAt  time.Time                   `json:"authority_reviewed_at"`
	AuthorityFingerprint string                      `json:"authority_fingerprint"`
	AuthorityBinding     string                      `json:"authority_binding,omitempty"`
	Evidence             []EarningsEvidenceReference `json:"evidence"`
}

EarningsTerminalInfo is compiled, reviewed evidence that one exact broker contract no longer has a future issuer earnings cycle. It is deliberately contract-bound rather than symbol-wide: ticker reuse or a different listing must fall back to ordinary provider resolution. RevalidateAfter is a hard fail-closed boundary; expired evidence becomes unknown until the catalog is reviewed and updated. AuthorityReviewedAt is the monotonic catalog watermark that also survives explicit record revocation.

type EquityDayEntry

type EquityDayEntry struct {
	Day           string    `json:"day"`
	AccountID     string    `json:"account_id"`
	EquityBase    float64   `json:"equity_base"`
	SourceStmt    string    `json:"source_stmt"`
	WhenGenerated time.Time `json:"when_generated,omitzero"`
}

EquityDayEntry is one derived statement-equity day. SourceStmt names the retained statement file the value came from; WhenGenerated is the restatement authority (newest statement wins per day).

type Error

type Error struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

Error is the structured error payload for a failed request.

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface so callers can return *Error.

type EstablishedAlertProjection

type EstablishedAlertProjection struct {
	SchemaVersion        string              `json:"schema_version"`
	CanonicalFingerprint Fingerprint         `json:"canonical_fingerprint"`
	OccurrenceEligible   bool                `json:"occurrence_eligible"`
	ActOnlyEligible      bool                `json:"act_only_eligible"`
	Action               string              `json:"action"`
	MarketConfirmation   string              `json:"market_confirmation"`
	Severity             risk.SignalSeverity `json:"severity"`
	PortfolioRelevant    bool                `json:"portfolio_relevant"`
}

EstablishedAlertProjection atomically carries every producer-owned field the pre-shadow Stress monitor used for occurrence identity and delivery-mode eligibility. CanonicalFingerprint carries the established key under the Stress-labelled compatibility version; it is not a new alert authority or a transport authorization.

func (EstablishedAlertProjection) MarshalJSON

func (projection EstablishedAlertProjection) MarshalJSON() ([]byte, error)

MarshalJSON validates the projection before encoding it.

func (*EstablishedAlertProjection) UnmarshalJSON

func (projection *EstablishedAlertProjection) UnmarshalJSON(data []byte) error

UnmarshalJSON rejects unknown, missing, null, trailing, or inconsistent data.

type Fingerprint

type Fingerprint struct {
	Version string `json:"version"`
	Key     string `json:"key"`
}

Fingerprint is a semantic identity for alert/dedupe surfaces. The Key is a stable sha256 over classified state, not raw prices, timestamps, or rendered prose. Monitors should use it to suppress duplicate alerts.

func BuildAccountFingerprint

func BuildAccountFingerprint(a *AccountResult) Fingerprint

BuildAccountFingerprint hashes only Stress-relevant account buckets. It is stable across tiny NLV, cushion, or P&L movement until a risk bucket changes.

func BuildLifecycleFingerprint

func BuildLifecycleFingerprint(state LifecycleState) Fingerprint

BuildLifecycleFingerprint returns a semantic identity that ignores continuous values and wall-clock churn while retaining classified changes.

func BuildMarketEventsFingerprint

func BuildMarketEventsFingerprint(r *MarketEventsResult) Fingerprint

BuildMarketEventsFingerprint returns the semantic identity of current market-event flags. It deliberately ignores timestamps, source prose, and exact numeric values except their classified flag status.

func BuildPositionsFingerprint

func BuildPositionsFingerprint(p *PositionsResult, netLiquidation float64) Fingerprint

BuildPositionsFingerprint hashes portfolio exposure buckets, not raw marks.

func BuildRegimeFingerprint

func BuildRegimeFingerprint(r *RegimeSnapshotResult) Fingerprint

BuildRegimeFingerprint returns the semantic identity of a regime snapshot. It hashes classified state only: bands, statuses, composite counts, warning codes/scopes/severities, and high-level data quality. It deliberately ignores timestamps, raw measurements, and prose.

func BuildStressFingerprint

func BuildStressFingerprint(r *StressResult) Fingerprint

BuildStressFingerprint returns the semantic alert identity of a Stress result. It hashes the classified alert state and source fingerprints, not timestamps, exact observed values, evidence strings, or render text.

type Frame

type Frame struct {
	T        time.Time   `json:"t"`
	Bid      *float64    `json:"bid,omitempty"`
	Ask      *float64    `json:"ask,omitempty"`
	Last     *float64    `json:"last,omitempty"`
	BidSize  *int        `json:"bid_size,omitempty"`
	AskSize  *int        `json:"ask_size,omitempty"`
	DataType string      `json:"data_type,omitempty"`
	Error    *FrameError `json:"error,omitempty"`
}

Frame is a single streaming tick. DataType carries the gateway's per-reqID market-data-type notice (live / frozen / delayed / delayed-frozen) so adapters can render a badge — important after hours, where frozen mode delivers a single snapshot and then goes silent. Empty string means "unknown" (the gateway hasn't sent the notice yet); the CLI treats that the same as "live" for rendering.

Error is the terminal-error variant: when populated, the price/size fields are nil and this is the last frame the consumer will receive on the subscription. Codes are the FrameErr* constants. Backward- compatible because of omitempty — older consumers parsing tick frames see no Error field and continue to work.

type FrameError

type FrameError struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

FrameError is the terminal error payload carried in Frame.Error. Code is one of the FrameErr* constants; Message is a single-sentence human description suitable for surfacing in CLI/MCP client output.

type GammaCollectionDiagnostic

type GammaCollectionDiagnostic struct {
	Underlying               string `json:"underlying"`
	TradingClass             string `json:"trading_class,omitempty"`
	Expiry                   string `json:"expiry,omitempty"` // YYYY-MM-DD
	QualifiedContracts       int    `json:"qualified_contracts"`
	RequestedLegs            int    `json:"requested_legs"`
	PricedLegs               int    `json:"priced_legs"`
	ModelTickLegs            int    `json:"model_tick_legs,omitempty"`
	DerivedLiveMidLegs       int    `json:"derived_live_mid_legs,omitempty"`
	DerivedPrevCloseLegs     int    `json:"derived_prev_close_legs,omitempty"`
	MarketDataGenericTicks   string `json:"market_data_generic_ticks,omitempty"`
	OIGenericTickRequested   bool   `json:"oi_generic_tick_101_requested,omitempty"`
	OILiveObservedLegs       int    `json:"oi_live_observed_legs,omitempty"`
	OICarriedForwardLegs     int    `json:"oi_carried_forward_legs,omitempty"`
	OIPositiveLegs           int    `json:"oi_positive_legs,omitempty"`
	OIMissingLegs            int    `json:"oi_missing_legs,omitempty"`
	ContractMissingLegs      int    `json:"contract_missing_legs,omitempty"`
	Timeouts                 int    `json:"timeouts,omitempty"`
	PacingErrors             int    `json:"pacing_errors,omitempty"`
	FarmErrors               int    `json:"farm_errors,omitempty"`
	EntitlementErrors        int    `json:"entitlement_errors,omitempty"`
	SubscriptionRejects      int    `json:"subscription_rejects,omitempty"`
	StrikeCandidates         int    `json:"strike_candidates,omitempty"`
	StrikeSelected           int    `json:"strike_selected,omitempty"`
	StrikeCap                int    `json:"strike_cap,omitempty"`
	StrikeCapTruncated       bool   `json:"strike_cap_truncated,omitempty"`
	ExpiryCapTruncated       bool   `json:"expiry_cap_truncated,omitempty"`
	CollectionDurationMS     int64  `json:"collection_duration_ms,omitempty"`
	OISourceStatus           string `json:"oi_source_status,omitempty"` // live_observed | carried_forward | mixed | missing
	CarriedForwardSource     string `json:"carried_forward_source,omitempty"`
	CarriedForwardObservedAt string `json:"carried_forward_observed_at,omitempty"`
}

GammaCollectionDiagnostic exposes the source-level option-chain funnel for one (underlying, trading class, expiry) slice. It separates contract discovery/prewarm from option market-data and OI capture so a blocked gamma result can name the source failure rather than only reporting a rankability gate.

type GammaIndexSummary

type GammaIndexSummary struct {
	Underlying      string   `json:"underlying,omitempty"`
	SpotUnderlying  float64  `json:"spot_underlying,omitempty"`
	DataType        string   `json:"data_type,omitempty"`
	ZeroGamma       *float64 `json:"zero_gamma,omitempty"`
	ZeroGammaStatus string   `json:"zero_gamma_status,omitempty"`
	Regime          string   `json:"regime,omitempty"`
	SweepLowAbs     float64  `json:"sweep_low_abs,omitempty"`
	SweepHighAbs    float64  `json:"sweep_high_abs,omitempty"`
	LegCount        int      `json:"leg_count,omitempty"`
	PricedLegCount  int      `json:"priced_leg_count,omitempty"`
	GammaTotalAbs   float64  `json:"gamma_total_abs,omitempty"`
	Confidence      string   `json:"confidence,omitempty"`
	Interpretation  string   `json:"interpretation,omitempty"`
}

GammaIndexSummary is a compact interpretation of one per-underlying gamma compute. It gives agents and text renderers the answer they usually need without walking profile arrays or knowing the raw sign-convention details.

type GammaLegDiagnosticCounts

type GammaLegDiagnosticCounts struct {
	PricedLegs               int `json:"priced_legs"`
	ModelTickLegs            int `json:"model_tick_legs,omitempty"`
	DerivedLiveMidLegs       int `json:"derived_live_mid_legs,omitempty"`
	DerivedPrevCloseLegs     int `json:"derived_prev_close_legs,omitempty"`
	OpenInterestObservedLegs int `json:"oi_observed_legs,omitempty"`
	OILiveObservedLegs       int `json:"oi_live_observed_legs,omitempty"`
	OICarriedForwardLegs     int `json:"oi_carried_forward_legs,omitempty"`
	OpenInterestLegs         int `json:"oi_positive_legs"`
	GammaPositiveLegs        int `json:"gamma_positive_legs"`
	AbsGEXLegs               int `json:"abs_gex_positive_legs"`
}

GammaLegDiagnosticCounts splits the priced-leg funnel into the conditions required for dealer GEX contribution. A leg can price and still fail to contribute when open interest is missing/zero, gamma is degenerate, or the resulting OI-weighted absolute GEX is zero. Missing OI is unknown, not zero; OpenInterestObservedLegs keeps that distinct from an observed zero-OI tick.

type GammaLegDiagnostics

type GammaLegDiagnostics struct {
	Total          GammaLegDiagnosticCounts            `json:"total"`
	ByUnderlying   map[string]GammaLegDiagnosticCounts `json:"by_underlying,omitempty"`
	ByTradingClass map[string]GammaLegDiagnosticCounts `json:"by_trading_class,omitempty"`
}

GammaLegDiagnostics carries the leg-quality funnel for the whole result plus splits that identify whether the drop happened at the underlying or trading-class level (for example SPX vs SPXW).

type GammaProfilePoint

type GammaProfilePoint struct {
	Spot float64 `json:"spot"`
	GEX  float64 `json:"gex"`
}

GammaProfilePoint is one (spot, dealer_gex) sample from the sweep. GEX is signed under the Perfiliev convention (call gamma positive, put gamma negative); a sign flip across two adjacent points is what the renderer reads as a "zero crossing."

type GammaQualityCoverage

type GammaQualityCoverage struct {
	PricedLegs           int     `json:"priced_legs"`
	RequestedLegs        int     `json:"requested_legs,omitempty"`
	FanoutCompletePct    float64 `json:"fanout_complete_pct,omitempty"`
	ModelTickLegs        int     `json:"model_tick_legs,omitempty"`
	DerivedLiveMidLegs   int     `json:"derived_live_mid_legs,omitempty"`
	DerivedPrevCloseLegs int     `json:"derived_prev_close_legs,omitempty"`
	OIObservedLegs       int     `json:"oi_observed_legs"`
	OILiveObservedLegs   int     `json:"oi_live_observed_legs,omitempty"`
	OICarriedForwardLegs int     `json:"oi_carried_forward_legs,omitempty"`
	OIPositiveLegs       int     `json:"oi_positive_legs"`
	GEXLegs              int     `json:"gex_legs"`
	OIObservedPct        float64 `json:"oi_observed_pct,omitempty"`
	OILiveObservedPct    float64 `json:"oi_live_observed_pct,omitempty"`
	OICarriedForwardPct  float64 `json:"oi_carried_forward_pct,omitempty"`
	OIPositivePct        float64 `json:"oi_positive_pct,omitempty"`
	DerivedIVPct         float64 `json:"derived_iv_pct,omitempty"`
	TopConcentrationPct  float64 `json:"top_concentration_pct,omitempty"`
	ExpirationCount      int     `json:"expiration_count,omitempty"`
	Has0DTE              bool    `json:"has_0dte"`
	Has1To7DTE           bool    `json:"has_1to7_dte"`
	HasTerm              bool    `json:"has_term"`
	SkewFitExpiries      int     `json:"skew_fit_expiries,omitempty"`
	MedianSkewRSquared   float64 `json:"median_skew_r_squared,omitempty"`
	MinSkewRSquared      float64 `json:"min_skew_r_squared,omitempty"`
}

GammaQualityCoverage carries the numeric diagnostics used by the quality gates. Ratios are percentages in human units (95.0 means 95%).

type GammaQualityGate

type GammaQualityGate struct {
	Name   string `json:"name"`
	Status string `json:"status"`
	Reason string `json:"reason,omitempty"`
}

GammaQualityGate is one explicit quality decision. Status is "pass", "context", or "block"; block gates prevent rankability, context gates preserve the payload as context only.

type GammaSignalQuality

type GammaSignalQuality struct {
	Rankability       string                        `json:"rankability"`
	RankabilityReason string                        `json:"rankability_reason,omitempty"`
	Freshness         string                        `json:"freshness,omitempty"`
	Session           string                        `json:"session,omitempty"`
	SessionKey        string                        `json:"session_key,omitempty"`
	CurrentSessionKey string                        `json:"current_session_key,omitempty"`
	AsOf              time.Time                     `json:"as_of,omitzero"`
	AgeSeconds        int64                         `json:"age_seconds,omitempty"`
	MaxAgeSeconds     int64                         `json:"max_age_seconds,omitempty"`
	Coverage          GammaQualityCoverage          `json:"coverage"`
	Gates             []GammaQualityGate            `json:"gates,omitempty"`
	Blockers          []string                      `json:"blockers,omitempty"`
	Context           []string                      `json:"context,omitempty"`
	ByUnderlying      map[string]GammaSignalQuality `json:"by_underlying,omitempty"`
}

GammaSignalQuality is the trading-grade gate for the gamma payload. The signed regime and sign-agnostic magnitude can be displayed whenever Result is present, but downstream regime/Stress consumers must only count the gamma band as market evidence when Rankability == "rankable".

type GammaWarningDetail

type GammaWarningDetail struct {
	// Code is the stable warning token, without lossy prose parsing.
	// Examples: "throttled", "0dte_no_legs",
	// "spx_unavailable:354", "oi_missing".
	Code string `json:"code"`
	// Scope names the affected slice: "SPY", "SPX", "SPY+SPX", or a
	// narrower trading class / expiry when the condition is that local.
	Scope string `json:"scope,omitempty"`
	// Severity is one of "info", "data_quality", or "methodology".
	// Renderers can show data_quality prominently and tuck info under
	// an expanded view.
	Severity string `json:"severity,omitempty"`
	// Message is a short user-facing explanation of the condition.
	Message string `json:"message"`
	// Impact explains how to read the gamma result in light of the
	// warning. Empty when the message is self-contained.
	Impact string `json:"impact,omitempty"`
	// Action is an optional non-advisory operational next step, such as
	// retrying during RTH or suppressing a known SPX entitlement banner.
	Action string `json:"action,omitempty"`
}

GammaWarningDetail is the human/agent-facing warning surface. The daemon may use compact codes internally, but the wire carries this scoped explanation so renderers do not have to decode raw tokens.

type GammaZeroComputed

type GammaZeroComputed struct {
	// SpotUnderlying is the price of the underlying instrument
	// (currently SPY — see Source) at which the aggregation was
	// anchored. Field was renamed from SpotSPX when the compute moved
	// from SPX to the more liquid SPY chain (SPY has continuous
	// extended-hours quoting and a single trading class, which keeps
	// the compute robust off-hours).
	SpotUnderlying float64 `json:"spot_underlying,omitempty"`
	// SpotAt is the gateway-observation timestamp for SpotUnderlying.
	// Distinct from AsOf which covers the whole computation.
	SpotAt time.Time `json:"spot_at,omitzero"`
	// DataType is the gateway feed state shared by the underlying spot and
	// option-model inputs. Delayed results are accepted only when the option
	// fan-out used IBKR's delayed model-computation tick 83 throughout.
	DataType string `json:"data_type,omitempty"`

	// ZeroGamma is the dealer γ-zero level under the Perfiliev convention
	// (the spot where dealer net gamma crosses zero). nil when no
	// crossing exists within the sweep window — inspect GammaSign in
	// that case to learn whether the whole sweep is long-γ or short-γ.
	ZeroGamma *float64 `json:"zero_gamma,omitempty"`
	// GapPct is (SpotUnderlying − ZeroGamma) / ZeroGamma × 100. nil iff
	// ZeroGamma is nil. Sign convention: positive = spot above γ-zero
	// (dampening regime); negative = below γ-zero (amplifying regime).
	GapPct *float64 `json:"gap_pct,omitempty"`
	// GammaSign is "positive" or "negative" and is meaningful only when
	// ZeroGamma is nil — it tells the renderer which side of zero the
	// whole sweep landed on so the UI can say "all long-gamma" or "all
	// short-gamma in window."
	GammaSign string `json:"gamma_sign,omitempty"`
	// Profile is the full (spot, gex) sweep, oldest first. 60 points
	// over [0.85, 1.15] × SpotUnderlying. Renderers chart this as the
	// gamma-exposure curve and visually confirm the zero crossing.
	Profile []GammaProfilePoint `json:"profile,omitempty"`

	// GammaTotalAbs is the sign-agnostic magnitude signal at
	// SpotUnderlying: Σ |Γ| × OI × 100 × SpotUnderlying² × 0.01. In
	// dollar gamma terms — the total notional dealer hedging flow for
	// a 1% underlying move, independent of any positioning assumption.
	// Larger = market is more sensitive to dealer rebalancing.
	GammaTotalAbs float64 `json:"gamma_total_abs"`
	// GammaTotalAbsConvention names the sign-handling for GammaTotalAbs
	// so downstream renderers can label it without re-deriving
	// methodology. Today's value is "sign-agnostic" — every leg's
	// magnitude |Γ|·OI·100·spot²·0.01 is summed unconditionally. This
	// is the convention-free read the M2 methodology refresh promotes
	// to co-primary alongside the signed γ-zero level.
	GammaTotalAbsConvention string `json:"gamma_total_abs_convention,omitempty"`
	// TopStrikes is the top-N strikes ranked by absolute gamma notional.
	// Concentration here is more reliable than the signed ZeroGamma in
	// regimes where the dealer-sign assumption may invert.
	TopStrikes []StrikeConcentration `json:"top_strikes"`
	// TopConcentrationPct is TopStrikes[0].AbsGEX / GammaTotalAbs × 100 —
	// what share of the sign-agnostic |Γ|·OI sum is parked at the single
	// largest strike. Renderers surface it as a one-line "this strike
	// dominates" cue alongside the table. Zero when TopStrikes is empty
	// or GammaTotalAbs is zero.
	TopConcentrationPct float64 `json:"top_concentration_pct,omitempty"`

	// SweepLowAbs / SweepHighAbs are the absolute spot bounds of the
	// sweep window in dollars: SpotUnderlying × (1 ± Params.SweepRangePct).
	// Surfaced for renderers that want to print "γ-zero outside swept
	// range $A.AA-$C.CC" without re-deriving the multiplication.
	SweepLowAbs  float64 `json:"sweep_low_abs,omitempty"`
	SweepHighAbs float64 `json:"sweep_high_abs,omitempty"`

	// Expirations is the YYYY-MM-DD list of expirations actually
	// included in the aggregation (after 0DTE-post-settlement filtering
	// and SPXW/SPX merging).
	Expirations []string `json:"expirations"`
	// LegCount is the number of option legs that contributed non-zero
	// open-interest-weighted gamma exposure to the profile. It excludes
	// priced legs whose IV landed but whose OI was missing/zero. Missing
	// OI is unknown, not zero, so those legs are omitted from dealer GEX
	// rather than zero-substituted.
	LegCount int `json:"leg_count"`
	// PricedLegCount is the number of option legs that delivered IV (or
	// a BS-IV fallback) and were usable for skew fitting. It can exceed
	// LegCount when IBKR supplied prices/IV but not open interest.
	PricedLegCount int `json:"priced_leg_count,omitempty"`
	// DerivedIVLegs counts how many priced legs used the BS-IV
	// Newton-Raphson fallback because the gateway never pushed a
	// model-computation tick. Pre-market this is often equal to
	// PricedLegCount (the model engine is idle); during regular hours it
	// should stay at 0. Renderers surface a "compute used N derived
	// IVs" disclosure so readers can tell those IVs came from option
	// quote/close inversion rather than live model ticks.
	DerivedIVLegs int `json:"derived_iv_legs,omitempty"`
	// ModelTickLegs counts priced legs whose IV came from IBKR's
	// option model-computation tick. DerivedLiveMidLegs and
	// DerivedPrevCloseLegs split the BS-IV fallback by price anchor:
	// live bid/ask midpoint versus prior-session option close. The
	// split is optional and additive; legacy consumers can continue to
	// read DerivedIVLegs as the total fallback count.
	ModelTickLegs        int `json:"model_tick_legs,omitempty"`
	DerivedLiveMidLegs   int `json:"derived_live_mid_legs,omitempty"`
	DerivedPrevCloseLegs int `json:"derived_prev_close_legs,omitempty"`
	// LegDiagnostics explains how priced legs flowed through the
	// GEX-contribution funnel. It is especially useful when a forced
	// off-hours run prices legs but every row has missing/zero OI.
	LegDiagnostics *GammaLegDiagnostics `json:"leg_diagnostics,omitempty"`
	// CollectionDiagnostics exposes the source-level request funnel per
	// underlying/tradingClass/expiry: contracts qualified, market-data legs
	// requested, priced legs, live-vs-carried OI, timeouts, rejects, and cap
	// truncation. This is the production diagnostic surface for deciding
	// whether gamma is source-limited or merely gate-blocked.
	CollectionDiagnostics []GammaCollectionDiagnostic `json:"collection_diagnostics,omitempty"`
	// Quality is the explicit rankability contract for gamma as an
	// algo-trading signal. Result can be present while Quality says
	// "context_only" or "blocked"; regime/Stress consumers must not
	// count the gamma band unless this says "rankable".
	Quality *GammaSignalQuality `json:"quality,omitempty"`
	// Warnings is the daemon-internal list of non-fatal condition codes:
	// "no_crossing_in_window", "spxw_partial_oi", "throttled",
	// "all_iv_derived". Empty when the computation was clean. It is not
	// serialized; wire consumers read WarningDetails instead.
	// Runs whose leg coverage falls below the MinLegCoverageFraction
	// persist threshold are surfaced as Status="error" with no
	// Result, not as a warning — see gamma_zero_compute's coverage
	// gate (mirror of breadth's MinCoverageFraction=0.80 pattern).
	Warnings []string `json:"-"`
	// WarningDetails is the serialized warning surface: scoped,
	// user-facing explanations plus optional impact/action text.
	WarningDetails []GammaWarningDetail `json:"warning_details,omitempty"`
	// Summary is a compact interpretation of the result. It is designed
	// for CLI/MCP consumers that need to answer "what did the model
	// identify?" before drilling into profile arrays.
	Summary *GammaZeroSummary `json:"summary,omitempty"`

	// ZeroGamma0DTE / Profile0DTE / GammaSign0DTE / LegCount0DTE are the
	// same headline triple computed over legs with DTE == 0 only —
	// same-day expiries before their settlement cutoff. Captures the
	// short-fuse flow that Cboe's 2025 data shows is ~59% of SPX
	// volume, isolated from the longer-dated weeklies and monthlies.
	// Nil when no 0DTE legs fell in the bucket (e.g. mid-week after
	// Monday's daily settled, before the next daily lists) OR when
	// the sweep over those legs had no crossing inside the ±10% band.
	// GammaSign0DTE="no_data" plus a "0dte_no_legs" warning communicate
	// the empty-bucket case.
	ZeroGamma0DTE *float64            `json:"zero_gamma_0dte,omitempty"`
	Profile0DTE   []GammaProfilePoint `json:"profile_0dte,omitempty"`
	GammaSign0DTE string              `json:"gamma_sign_0dte,omitempty"`
	LegCount0DTE  int                 `json:"leg_count_0dte,omitempty"`

	// ZeroGamma1to7 / Profile1to7 / GammaSign1to7 / LegCount1to7 are the
	// matching triple for legs with 0 < DTE ≤ 7 days — overnight
	// through one calendar week. Captures end-of-week dynamics
	// (weeklies, EOW Friday flow) without commingling with the 0DTE
	// term that swamps the bucket on a third Friday.
	ZeroGamma1to7 *float64            `json:"zero_gamma_1to7,omitempty"`
	Profile1to7   []GammaProfilePoint `json:"profile_1to7,omitempty"`
	GammaSign1to7 string              `json:"gamma_sign_1to7,omitempty"`
	LegCount1to7  int                 `json:"leg_count_1to7,omitempty"`

	// ZeroGammaTerm / ProfileTerm / GammaSignTerm / LegCountTerm are the
	// matching triple for legs with DTE > 7 days — monthly OPEX and
	// quarterly horizons. Slower-moving than the two near buckets;
	// dominated by collar/structured-product positioning rather than
	// dealer-flow speed.
	ZeroGammaTerm *float64            `json:"zero_gamma_term,omitempty"`
	ProfileTerm   []GammaProfilePoint `json:"profile_term,omitempty"`
	GammaSignTerm string              `json:"gamma_sign_term,omitempty"`
	LegCountTerm  int                 `json:"leg_count_term,omitempty"`

	// MethodologyCitations is the short bibliography backing the
	// methodology disclosure. Each entry is a single line of the form
	// "Author (Year) — short claim". Surfaced on the result envelope so
	// renderers can show the citations alongside the headline numbers
	// without the user having to consult out-of-band documentation.
	MethodologyCitations []string `json:"methodology_citations,omitempty"`

	// SkewModel names the IV model used during the sweep. v2 cutover:
	// "sticky-moneyness-v1" means a quadratic skew curve in
	// log-moneyness was fitted per expiry and σ was looked up at each
	// (scenario spot, strike) pair. Empty when the curve fell back to
	// sticky-IV everywhere (degenerate fits across every expiry); a
	// per-expiry fallback shows up in warning_details.
	SkewModel string `json:"skew_model,omitempty"`
	// SkewFitQuality is one SkewFitInfo per expiry that fitted a curve
	// successfully. Keyed by compact YYYYMMDD. Renderers can show fit
	// quality alongside the headline so the reader can audit how
	// confident the underlying skew curve is.
	SkewFitQuality map[string]SkewFitInfo `json:"skew_fit_quality,omitempty"`

	// Params echoes the v1 calibration window so a renderer can show
	// "computed over 6 expirations inside ATM ± 10%" without consulting
	// out-of-band documentation. The daemon caps the live fan-out to
	// the nearest 80 listed strikes per expiry; warning_details includes
	// strike_budget_capped when the candidate window exceeded that cap.
	Params GammaZeroParams `json:"params"`
	// Source identifies the data provenance for the headline numbers.
	Source string `json:"source"`
	// AuthorityProvenance is empty for a current-code compute. A non-empty
	// value identifies an explicit persistence recovery path and is consumed
	// by the gamma quality gate; recovered evidence remains displayable but
	// cannot become a rankable trading signal merely because its timestamp is
	// inside the current session.
	AuthorityProvenance string `json:"authority_provenance,omitempty"`
	// Method is a short stable token for the computation path. v3:
	// "bs-gamma-profile-v3-stickymoneyness-0dte-split". The v3 bump
	// signals two semantic changes from v2:
	//   - horizon split is now 0DTE / 1-7 / >7 (was ≤7 / >7), because
	//     Cboe 2025 data shows 0DTE = ~59% of SPX volume and lumping
	//     it with weeklies muddies the signal.
	//   - the per-leg snapshot gamma is BS-recomputed from captured IV
	//     rather than read from the gateway's optional Greeks tick;
	//     fixes a v2 race where IV-but-no-Greeks legs contributed 0 to
	//     GammaTotalAbs.
	// "perfiliev" is dropped from the token because Perfiliev's
	// published method used sticky-IV; the sticky-moneyness refinement
	// is citable to Derman / Daglish-Hull-Suo (see MethodologyCitations).
	// Full disclosure lives in docs/docs/internals/regime-dashboard.md so
	// renderers can deep-link.
	Method string `json:"method"`
	// AsOf is the daemon's wall-clock when the compute finished.
	AsOf time.Time `json:"as_of"`
	// DurationMS is honest about how long the compute took on the wall
	// clock; useful for tuning ExpiryCount / StrikeWidthPct.
	DurationMS int64 `json:"duration_ms"`

	// Scope is the discriminator for combined-vs-single-underlying
	// payloads:
	//   "spy"     — SPY-only; PerIndex is nil
	//   "spx"     — SPX-only (--only=spx); PerIndex is nil
	//   "spy+spx" — combined; price-level fields stay under PerIndex
	//               because there is no meaningful combined price scale.
	// Empty is treated as Scope="spy" by legacy renderers only.
	Scope string `json:"scope,omitempty"`

	// PerIndex carries the per-underlying detail when Scope="spy+spx".
	// Nil for single-underlying scopes. Keys are uppercased symbols
	// ("SPY", "SPX"). Each entry is a self-contained GammaZeroComputed
	// with its own Scope ("spy" or "spx"), so a renderer can recurse on
	// the per-index slice and reuse the single-underlying formatting.
	//
	// Pointer values rather than struct values so the field can be
	// nil-checked rather than length-tested in renderers, and so the
	// recursive type doesn't bloat the SPY-only path's payload.
	PerIndex map[string]*GammaZeroComputed `json:"per_index,omitempty"`

	// PartialClasses surfaces per-trading-class entitlement gaps when
	// one class of an underlying lands but the other 354s. Keyed by
	// the unreachable trading class (e.g. {"SPX": "354"} when SPX-class
	// AM-monthlies return "not subscribed" but SPXW-class weeklies
	// land). Empty when both classes land cleanly OR when neither
	// lands (the latter surfaces as Status="error" upstream).
	PartialClasses map[string]string `json:"partial_classes,omitempty"`

	// RegimeAgreement classifies whether the SPY and SPX dealer-gamma
	// regimes agree, populated only on Scope="spy+spx" runs. One of:
	//
	//   "agree:long-gamma"  — both indices' sweeps stay positive (dealer
	//                         long-γ across the ±15% window, stabilizing).
	//   "agree:short-gamma" — both stay negative (short-γ, amplifying).
	//   "agree:transition-gamma" — both are within ±2% of their γ-zero
	//                         crossings. The per-index ZeroGamma levels
	//                         carry the precise prices.
	//   "disagree"          — one index is long-γ, the other short-γ
	//                         (or transition while the other isn't).
	//                         The actionable signal: institutional SPX
	//                         book and retail/ETF SPY book are positioned
	//                         opposite, which the regime-call use case
	//                         cares about more than any combined number.
	//   ""                  — at least one bucket has no data; can't
	//                         classify. Renderers fall back to per-index.
	//
	// Replaces the earlier DecoupledCorr field, which gated on 20-day
	// price correlation. Price correlation stays > 0.99 essentially
	// always; that gate never fired and missed the actual case worth
	// flagging — gamma regimes that decouple while prices stay tightly
	// correlated.
	RegimeAgreement string `json:"regime_agreement,omitempty"`
}

GammaZeroComputed is the actual zero-gamma payload — populated when GammaZeroSPXResult.Status is GammaZeroStatusReady. Kept as a separate struct so the envelope (Status / Eta / Progress / Result pointer) can evolve independently of the computation payload.

Sign convention: ZeroGamma assumes the 2018-era "dealers long calls, short puts" Perfiliev convention. This is a defensible baseline at the SPX index level but can invert near autocallable barriers and when covered-call ETF flow dominates. Treat ZeroGamma as a regime hint, not a precise level; consult TopStrikes (sign-agnostic) for the more robust positioning view. See docs/docs/internals/regime-dashboard.md for the full methodology disclosure.

Combined-scope semantics:

When Scope == "spy+spx", there is intentionally no top-level ZeroGamma, GapPct, GammaSign, SpotUnderlying, or horizon bucket. SPY and SPX live on different price scales, so consumers must read per_index.SPY and per_index.SPX for price-level regime detail. The combined top level is limited to scale-safe diagnostics: summary, regime agreement, sign-agnostic magnitude, top strikes, counts, warnings, method/source, citations, timestamps, and the per-index map.

type GammaZeroParams

type GammaZeroParams struct {
	// ExpiryCount is the number of nearest non-0DTE-post-settlement
	// expirations included in the aggregation.
	ExpiryCount int `json:"expiry_count"`
	// StrikeWidthPct is the half-width of the strike grid around spot,
	// expressed as a fraction (0.10 = ATM ± 10 %).
	StrikeWidthPct float64 `json:"strike_width_pct"`
	// SweepRangePct is the half-range of the spot sweep used to find
	// the zero-crossing (0.15 = [0.85, 1.15] × spot).
	SweepRangePct float64 `json:"sweep_range_pct"`
	// WorkerCount is the per-leg fan-out concurrency. 4 matches the
	// documented safe gateway throttle; bumping it requires retuning
	// AcquireMarketDataSlot.
	WorkerCount int `json:"worker_count"`
}

GammaZeroParams echoes the v1 calibration window back to the caller so renderers can show "computed over N expirations within ±X%." Future versions can add fields here without breaking the result shape — every renderer-relevant tuning parameter lives on this echo.

type GammaZeroSPXParams

type GammaZeroSPXParams struct {
	// WaitMs is the maximum time the daemon blocks on an in-flight or
	// just-kicked-off compute before returning the current state. 0
	// (the default) means "return immediately with whatever state we
	// have." A non-zero value is capped daemon-side to keep the RPC
	// under the per-method deadline.
	WaitMs int `json:"wait_ms,omitempty"`
	// Force, when true, starts a fresh diagnostic compute. If a good
	// cached result is already serving, the daemon keeps serving it and
	// promotes the forced compute only on success. Useful for diagnostics;
	// dashboards should leave this off and let the daily cache handle
	// freshness.
	Force bool `json:"force,omitempty"`
	// Scope selects which underlying(s) to compute. One of GammaZeroScopeSPY
	// ("spy"), GammaZeroScopeSPX ("spx"), or GammaZeroScopeCombined ("spy+spx").
	// Empty defaults to "spy+spx" with SPX-skipped fallback.
	Scope string `json:"scope,omitempty"`
	// IncludeProfiles asks clients/renderers to retain the full profile
	// arrays in JSON/MCP responses. The daemon compute always produces
	// profiles where meaningful; thin adapters may strip them by default
	// to keep agent/tool payloads compact.
	IncludeProfiles bool `json:"include_profiles,omitempty"`
}

GammaZeroSPXParams is the input for MethodGammaZeroSPX. All fields are optional; defaults match the v1 calibration window documented in docs/docs/internals/regime-dashboard.md.

type GammaZeroSPXResult

type GammaZeroSPXResult struct {
	// Status is one of GammaZeroStatusComputing / Ready / Error.
	Status string `json:"status"`
	// Refreshing is true when a newer compute is in flight while this
	// envelope serves the last good result. Ready + StartedAt cannot express
	// that: StartedAt describes the compute that produced Result, so without
	// this field a consumer cannot tell a current-session compute in flight
	// from one that never started. Mirrors BreadthSPXResult.Refreshing.
	Refreshing bool `json:"refreshing,omitempty"`
	// StartedAt is when the currently-relevant compute kicked off — for
	// "computing", that's the in-flight job; for "ready", it's the
	// compute that produced Result. Nil if no compute has ever started.
	StartedAt *time.Time `json:"started_at,omitempty"`
	// EtaSeconds is an initial estimate of the total wall-clock the
	// compute will need from kickoff. Used by renderers to show a
	// progress meter or set a polling cadence. 0 when Status != computing.
	EtaSeconds int `json:"eta_seconds,omitempty"`
	// Progress is a 0-100 hint, best-effort. 0 when Status != computing.
	Progress int `json:"progress,omitempty"`
	// Result is populated when Status == "ready".
	Result *GammaZeroComputed `json:"result,omitempty"`
	// DiagnosticResult is populated when a compute failed after collecting
	// source-level evidence (for example priced option legs with no usable OI),
	// or when a preserved ready cache has a newer failed diagnostic refresh.
	// It must not be treated as a trading signal; it exists to expose the
	// option-chain/OI source blocker that prevented Result from updating.
	DiagnosticResult *GammaZeroComputed `json:"diagnostic_result,omitempty"`
	// Error is populated when Status == "error".
	Error string `json:"error,omitempty"`
	// ColdReasonCode / ColdReason / ColdAction are populated when the
	// daemon knows why no fresh result can be served, and say when the
	// next attempt is due. On Status == "cold" they distinguish a
	// first-run cache from a persisted snapshot that existed but was
	// rejected by schema, methodology, or data-quality gates. They are
	// also populated on Status == "error" when the failed attempt is
	// being retained across a closed options session, where no automatic
	// retry runs until the next regular session — Error still carries the
	// failure itself and is not softened.
	ColdReasonCode string `json:"cold_reason_code,omitempty"`
	ColdReason     string `json:"cold_reason,omitempty"`
	ColdAction     string `json:"cold_action,omitempty"`
	// RetryOfErrorAt + RetryOfErrorSummary are non-nil/non-empty only
	// when Status == "computing" AND the in-flight compute was kicked
	// because the previous attempt failed past gammaErrorRetryTTL. The
	// renderer surfaces them as "computing · retry of <summary> at
	// HH:MM:SS" so the user sees the prior failure context — without
	// this, the dashboard silently switched from "error" to "computing"
	// and the user had to grep the daemon log to understand why.
	RetryOfErrorAt      *time.Time `json:"retry_of_error_at,omitempty"`
	RetryOfErrorSummary string     `json:"retry_of_error_summary,omitempty"`
}

GammaZeroSPXResult is the envelope returned by MethodGammaZeroSPX. Always carries a Status; Result is populated when Status is "ready". The split (envelope vs computed payload) keeps the wire stable while the compute pipeline can evolve — adding fields to GammaZeroComputed doesn't churn the polling contract.

type GammaZeroSummary

type GammaZeroSummary struct {
	PrimaryStatement string                       `json:"primary_statement,omitempty"`
	ZeroGammaStatus  string                       `json:"zero_gamma_status,omitempty"`
	Regime           string                       `json:"regime,omitempty"`
	Confidence       string                       `json:"confidence,omitempty"`
	NotAdvice        string                       `json:"not_advice,omitempty"`
	PerIndex         map[string]GammaIndexSummary `json:"per_index,omitempty"`
}

GammaZeroSummary is the compact, non-advisory readout of a gamma result. The raw fields remain canonical for charting and backtests; Summary is for humans and agents answering "which gamma zero, if any, did we identify?"

type GovernorAction

type GovernorAction struct {
	Action   string   `json:"action"`
	From     string   `json:"from,omitempty"`
	To       string   `json:"to,omitempty"`
	Reason   string   `json:"reason,omitempty"`
	Clusters []string `json:"clusters,omitempty"`
}

GovernorAction is one disclosed policy downgrade. Reasons are stable tokens: "pending_backtest_no_tape_cosign" (heuristic threshold sets confirmed the stage but no fresh tape co-signature was present) and "confirming_cluster_quality" (a confirming cluster's data quality is stale/partial/degraded).

type HealthResult

type HealthResult struct {
	DaemonVersion string    `json:"daemon_version"`
	DaemonStarted time.Time `json:"daemon_started"`
	UptimeSeconds int64     `json:"uptime_seconds"`
	Account       string    `json:"account,omitempty"`
	// ConnectedAccount is the one account the connected TWS/Gateway session is
	// scoped to, never a list. It is the code the session advertises via
	// managedAccounts / accountSummary when that is a single account, and the
	// configured [gateway].account pin when the login holds several and the
	// advertised value is the comma-joined inventory. It is empty when neither
	// is one concrete account — an unpinned multi-account login has no account
	// to name. It differs from Account when [gateway].account is empty and the
	// daemon auto-detected the account after handshake. The session's full
	// inventory is not served here.
	ConnectedAccount string `json:"connected_account,omitempty"`
	// AccountMode is the daemon's best classification of the connected
	// endpoint/account: "paper", "live", or "unknown".
	AccountMode   string `json:"account_mode,omitempty"`
	GatewayHost   string `json:"gateway_host"`
	GatewayPort   int    `json:"gateway_port"`
	GatewayTLS    bool   `json:"gateway_tls"`
	NegotiatedTLS bool   `json:"negotiated_tls"`
	PortOrigin    string `json:"port_origin"`
	TLSOrigin     string `json:"tls_origin"`
	Alternates    []int  `json:"alternates,omitempty"`
	ClientID      int    `json:"client_id"`
	Connected     bool   `json:"connected"`
	// GatewayPhase classifies which connectivity boundary currently blocks
	// service. A backend_link_down phase can coexist with Connected=true: the
	// local API session is ready while TWS reports its IBKR backend link lost.
	GatewayPhase   string    `json:"gateway_phase"`
	GatewayPhaseAt time.Time `json:"gateway_phase_at,omitzero"`
	DataType       string    `json:"data_type,omitempty"`
	ServerVersion  int       `json:"server_version,omitempty"`
	LastError      string    `json:"last_error,omitempty"`
	// BackgroundTasks lists daemon-internal long-running computes that
	// are running or waiting for a scheduled retry. Empty when nothing
	// is active. Always present on the wire (never omitted) so
	// consumers can rely on `len(result.background_tasks) == 0` to
	// mean "idle" without inferring from absence.
	BackgroundTasks []BackgroundTaskStatus `json:"background_tasks"`
	Subsystems      []SubsystemHealth      `json:"subsystems,omitempty"`
	DataQuality     []DataQualityHealth    `json:"data_quality,omitempty"`
	DataFarms       []DataFarmHealth       `json:"data_farms,omitempty"`
	// MarketDataAccess lists route keys the gateway is currently refusing
	// market data for. Empty is the normal case and the only claim absence
	// makes is that nothing was refused inside the window — not that every
	// name is entitled.
	MarketDataAccess []MarketDataAccessHealth `json:"market_data_access,omitempty"`
	// Members carries the runtime SPX-membership state: source
	// (cache vs embedded), count, as-of timestamp, refresh health.
	// Populated unconditionally — even when the daemon falls back
	// to the embedded list, the user needs to see WHICH list it's
	// using so silent parser rot / disabled-refresh shows up in
	// `canary status`. Zero-value Source means the daemon doesn't
	// know yet (engine construction failed); the CLI hides the row
	// in that case.
	Members MembersHealth `json:"members"`
	Trading TradingStatus `json:"trading"`
}

HealthResult is the response to MethodStatusHealth.

PortOrigin / TLSOrigin record how the daemon arrived at the values shown — "pinned" (user wrote them in config), "discovered" (probe found the gateway), or "default" (built-in fallback). Alternates lists other ports that responded during discovery but lost the first-hit race. Empty alternates is the common case (single gateway up).

type HeldStress

type HeldStress struct {
	Underlying            string            `json:"underlying"`
	MaterialReasons       []string          `json:"material_reasons,omitempty"`
	MarketValuePctNLV     *float64          `json:"market_value_pct_nlv,omitempty"`
	DeltaPctNLV           *float64          `json:"delta_pct_nlv,omitempty"`
	DailyPnLPctNLV        *float64          `json:"daily_pnl_pct_nlv,omitempty"`
	NearExpiryDeltaPctNLV *float64          `json:"near_expiry_delta_pct_nlv,omitempty"`
	NearExpiryGamma       *float64          `json:"near_expiry_gamma,omitempty"`
	NearExpiryMinDTE      *int              `json:"near_expiry_min_dte,omitempty"`
	LiquidityFlags        []string          `json:"liquidity_flags,omitempty"`
	MarketFlags           []MarketEventFlag `json:"market_flags,omitempty"`
	SignalIDs             []risk.SignalID   `json:"signal_ids,omitempty"`
}

HeldStress is a bounded, positions-only explanation of stress inside material held underlyings. It deliberately avoids option-chain fan-out; all fields come from the existing positions/account snapshot.

type HistoryBar

type HistoryBar struct {
	Date   string  `json:"date"` // YYYY-MM-DD
	Open   float64 `json:"open"`
	High   float64 `json:"high"`
	Low    float64 `json:"low"`
	Close  float64 `json:"close"`
	Volume int64   `json:"volume"`
}

HistoryBar is one daily OHLCV row.

type HistoryDailyParams

type HistoryDailyParams struct {
	Symbol     string `json:"symbol"`
	Days       int    `json:"days,omitempty"` // default 90 when zero
	WhatToShow string `json:"what_to_show,omitempty"`
}

HistoryDailyParams requests N days of daily OHLCV bars for a symbol.

type HistoryDailyResult

type HistoryDailyResult struct {
	Symbol     string       `json:"symbol"`
	Days       int          `json:"days"`
	WhatToShow string       `json:"what_to_show,omitempty"`
	DataType   string       `json:"data_type,omitempty"`
	Bars       []HistoryBar `json:"bars"`
	AsOf       time.Time    `json:"as_of"`
}

HistoryDailyResult wraps the daily bars for the CLI. Historical daily bars are gateway-stored data with no live/delayed dimension; DataType is therefore unused on this response and kept only as a reserved field (omitempty) for shape parity with the streaming surfaces.

type HistoryIndexHealth

type HistoryIndexHealth struct {
	// LastIngestAt is a retired legacy-ingest field and is zero for direct
	// daemon.db history reads.
	LastIngestAt time.Time `json:"last_ingest_at,omitzero"`
	// IngestedBytes is a retired legacy journal watermark.
	IngestedBytes int64 `json:"ingested_bytes"`
	// JournalBytes is a retired legacy journal-size field.
	JournalBytes int64 `json:"journal_bytes"`
}

HistoryIndexHealth is retained in history result shapes for wire compatibility. The daemon.db authority has no asynchronous JSONL ingest or journal-byte freshness comparison; storage availability is reported by the RPC outcome and daemon health surface.

type HistoryRotationSettings

type HistoryRotationSettings struct {
	Enabled SettingsBool `json:"enabled"`
	// KeepRawMonths is retained for wire compatibility and has no live
	// journal-retention effect.
	KeepRawMonths SettingsInt `json:"keep_raw_months"`
}

HistoryRotationSettings is a retired compatibility shape. Its fields do not enable a rotation worker or authorize writes to legacy journals/archives.

type LifecycleEvidence

type LifecycleEvidence struct {
	Source    string `json:"source,omitempty"`
	Signal    string `json:"signal,omitempty"`
	Bucket    string `json:"bucket,omitempty"`
	Timing    string `json:"timing,omitempty"`
	Severity  string `json:"severity,omitempty"`
	Confirmed bool   `json:"confirmed,omitempty"`
}

LifecycleEvidence is one classified input to a lifecycle decision. Confirmed distinguishes qualifying evidence from context retained for explanation.

type LifecycleState

type LifecycleState struct {
	Stage       string              `json:"stage,omitempty"`
	Scope       string              `json:"scope,omitempty"`
	Severity    string              `json:"severity,omitempty"`
	Readiness   string              `json:"readiness,omitempty"`
	Timing      string              `json:"timing,omitempty"`
	Confidence  string              `json:"confidence,omitempty"`
	Evidence    []LifecycleEvidence `json:"evidence,omitempty"`
	ConfirmedBy []string            `json:"confirmed_by,omitempty"`
	Unconfirmed []string            `json:"unconfirmed,omitempty"`
	Suppressed  []string            `json:"suppressed,omitempty"`
	RejectedBy  []string            `json:"rejected_by,omitempty"`
	// Governors discloses every policy downgrade applied after stage
	// selection (provenance gate, evidence-keyed quality cap). Nothing is
	// silently weakened: when severity reads lower than the stage suggests,
	// this is where the reason lives.
	Governors    []GovernorAction `json:"governors,omitempty"`
	Fingerprint  Fingerprint      `json:"fingerprint,omitzero"`
	NotExecution string           `json:"not_execution,omitempty"`
}

LifecycleState is the stable monitor/orchestration surface for regime and Stress payloads. Stage is intentionally a small state machine, while Evidence preserves weak/unconfirmed inputs without letting them dominate the trigger.

func BuildRegimeLifecycle

func BuildRegimeLifecycle(r *RegimeSnapshotResult) LifecycleState

BuildRegimeLifecycle classifies broad-market-only regime evidence into the stress lifecycle used by downstream orchestration. It does not look at account, position, margin, or execution state.

Confirmation policy (internal-docs/design/regime-calibration.md): only ELIGIBLE reds — deep, persistent, cadence-fresh evidence per the shared gates — count toward confirmed_stress/panic and confirmed_by. Provisional reds stay visible and land in unconfirmed. They drive early_warning only while the required input set is usable; broken or overdue evidence produces an explicit data_quality state instead of masquerading as a market warning. Independently current confirmed stress/panic is preserved even when an unrelated source is impaired. A severity governor then applies the provenance gate (heuristic pending_backtest evidence without a tape co-signature is capped one rung down) and the evidence-keyed quality cap, disclosing every downgrade in Governors.

type MarketCalendarParams

type MarketCalendarParams struct {
	Market string    `json:"market,omitempty"`
	Date   string    `json:"date,omitempty"`
	At     time.Time `json:"at,omitzero"`
	Days   int       `json:"days,omitempty"`
}

MarketCalendarParams requests official exchange-session context. Market is one of "us", "us-equity", "us-options", "de", or "de-xetra" aliases; the daemon normalizes it to the stable result.market token. Date is YYYY-MM-DD in the market's local timezone. At, when non-zero, wins over Date and asks for the market state at that exact instant. Days controls how many calendar days to include in Sessions; default 14, capped daemon-side at 400.

type MarketCalendarResult

type MarketCalendarResult struct {
	Market        string          `json:"market"`
	Label         string          `json:"label"`
	Timezone      string          `json:"timezone"`
	AsOf          time.Time       `json:"as_of"`
	CoverageStart string          `json:"coverage_start"`
	CoverageEnd   string          `json:"coverage_end"`
	Source        string          `json:"source"`
	SourceURL     string          `json:"source_url"`
	Session       MarketSession   `json:"session"`
	Sessions      []MarketSession `json:"sessions,omitempty"`
}

MarketCalendarResult is MethodMarketCalendar's payload.

type MarketDataAccessHealth added in v2.8.0

type MarketDataAccessHealth struct {
	// RouteKey is the connector's own subscription key — a bare symbol, or
	// the pipe-joined contract route for an explicitly routed request.
	RouteKey string `json:"route_key"`
	// Symbol is RouteKey's leading symbol component, for display.
	Symbol     string    `json:"symbol,omitempty"`
	Code       int       `json:"code"`
	Reason     string    `json:"reason"`
	ObservedAt time.Time `json:"observed_at,omitzero"`
	// RetryAt is when the suppression window lifts and the next request for
	// this key reaches the gateway again.
	RetryAt time.Time `json:"retry_at,omitzero"`
}

MarketDataAccessHealth reports one route key the gateway is currently refusing market data for, so a missing subscription is legible in one place instead of being re-diagnosed per feature.

This is an observation of a time-windowed rejection, never an entitlement record: nothing persists it, nothing may gate on it, and it can be wrong in both directions (a delayed-data fallback or a farm outage can produce a rejection for a name the account does hold, and a name never requested during the window produces no row at all). Consumers degrade loudly and keep serving — a cached result stays valid while a fresh fetch for the same key would be refused.

Reason is derived from Code through MarketDataAccessReason. Message is deliberately absent: broker free text is untrusted and never reaches a typed field or a classification input.

type MarketEventBorrowFeeCoverage

type MarketEventBorrowFeeCoverage struct {
	Symbol              string         `json:"symbol"`
	ContractConID       int            `json:"contract_con_id,omitempty"`
	ContractFingerprint string         `json:"contract_fingerprint,omitempty"`
	CoverageScope       string         `json:"coverage_scope"`
	Status              string         `json:"status"`
	Reason              string         `json:"reason,omitempty"`
	Source              string         `json:"source"`
	DataType            string         `json:"data_type"`
	AsOf                time.Time      `json:"as_of,omitzero"`
	ObservedAt          time.Time      `json:"observed_at,omitzero"`
	FeeRate             *float64       `json:"fee_rate,omitempty"`
	Entitlement         string         `json:"entitlement"`
	ScaleStatus         string         `json:"scale_status"`
	PolicyEligible      bool           `json:"policy_eligible"`
	LastFailure         *SourceFailure `json:"last_failure,omitempty"`
}

MarketEventBorrowFeeCoverage is one typed borrow-fee observation or gap. ContractConID and ContractFingerprint are absent only for symbol-level gaps where no exact currently-held short-stock contract was available. FeeRate is nullable so unavailable evidence can never collapse to a zero fee.

type MarketEventFlag

type MarketEventFlag struct {
	ID             string        `json:"id"`
	Symbol         string        `json:"symbol"`
	Label          string        `json:"label"`
	Status         string        `json:"status"`
	Severity       string        `json:"severity"`
	Role           string        `json:"role"`
	Source         string        `json:"source"`
	SourceURL      string        `json:"source_url,omitempty"`
	AsOf           time.Time     `json:"as_of,omitzero"`
	ObservedAt     time.Time     `json:"observed_at,omitzero"`
	ExpiresAt      time.Time     `json:"expires_at,omitzero"`
	Value          *float64      `json:"value,omitempty"`
	Unit           string        `json:"unit,omitempty"`
	Details        []string      `json:"details,omitempty"`
	WarningDetails []DataWarning `json:"warning_details,omitempty"`
}

MarketEventFlag is one allowlisted observed-data finding. Optional timestamps and Value remain absent when unavailable rather than being zero-filled.

type MarketEventsParams

type MarketEventsParams struct {
	Symbol  string   `json:"symbol,omitempty"`
	Symbols []string `json:"symbols,omitempty"`
}

MarketEventsParams selects one or more held-name symbols. Empty scope asks the daemon for its default observed universe; callers do not select sources.

type MarketEventsResult

type MarketEventsResult struct {
	Kind          string                       `json:"kind"`
	SchemaVersion string                       `json:"schema_version"`
	AsOf          time.Time                    `json:"as_of"`
	Symbols       []string                     `json:"symbols,omitempty"`
	Flags         []MarketEventFlag            `json:"flags,omitempty"`
	BySymbol      map[string][]MarketEventFlag `json:"by_symbol,omitempty"`
	SourceHealth  []SourceHealth               `json:"source_health,omitempty"`
	// BorrowFeeCoverage makes source scope and exact-contract completeness
	// explicit. In particular, portfolio-only historical FEE_RATE rows remain
	// policy-ineligible until their broker numeric scale is commissioned.
	BorrowFeeCoverage []MarketEventBorrowFeeCoverage `json:"borrow_fee_coverage,omitempty"`
	Fingerprint       Fingerprint                    `json:"fingerprint,omitzero"`
	WarningDetails    []DataWarning                  `json:"warning_details,omitempty"`
	NotExecution      string                         `json:"not_execution,omitempty"`
}

MarketEventsResult is the daemon-authored market-event snapshot. Empty flags are conclusive only when SourceHealth establishes complete, current coverage.

type MarketSession

type MarketSession struct {
	Market        string     `json:"market"`
	Label         string     `json:"label,omitempty"`
	Date          string     `json:"date"`
	Timezone      string     `json:"timezone"`
	State         string     `json:"state"`
	IsOpen        bool       `json:"is_open"`
	Reason        string     `json:"reason,omitempty"`
	Open          time.Time  `json:"open,omitzero"`
	Close         time.Time  `json:"close,omitzero"`
	NextOpen      *time.Time `json:"next_open,omitempty"`
	NextClose     *time.Time `json:"next_close,omitempty"`
	Source        string     `json:"source,omitempty"`
	SourceURL     string     `json:"source_url,omitempty"`
	CoverageStart string     `json:"coverage_start,omitempty"`
	CoverageEnd   string     `json:"coverage_end,omitempty"`
	Notes         string     `json:"notes,omitempty"`
}

MarketSession is one official market-calendar row. Open/Close are present for trading days; NextOpen/NextClose are present when the requested instant is closed but a next session is known within coverage.

type MembersHealth

type MembersHealth struct {
	Source       string    `json:"source"`
	AsOf         time.Time `json:"as_of"`
	Count        int       `json:"count"`
	RefreshState string    `json:"refresh_state"`
}

MembersHealth is the wire shape for the SPX-members surface rendered in `canary status`. Distinct from BreadthSPXResult: that carries the COMPUTED breadth value; this carries metadata about the constituent LIST.

Source is "cache" when the daemon loaded the runtime-refreshed file, "embedded" when it fell back to the binary's compiled-in baseline. AsOf is the date the active list was generated. RefreshState is one of the spx.RefreshState constants ("healthy", "network_failed", "parse_failed", "disabled (config)", "disabled (env)"). Healthy is the steady-state; renderer omits the `refresh:` segment when healthy.

type MethodLifetime added in v2.8.0

type MethodLifetime uint8

MethodLifetime says whether a daemon method is a bounded request or owns a stream that lives until its caller cancels it.

const (
	MethodLifetimeUnary MethodLifetime = iota + 1
	MethodLifetimeStreaming
)

Method lifetime values distinguish bounded calls from caller-owned streams.

type MethodTiming added in v2.8.0

type MethodTiming struct {
	Method        string
	Lifetime      MethodLifetime
	DaemonTimeout time.Duration
}

MethodTiming is the shared timing contract for one daemon RPC method. DaemonTimeout is the daemon's own handler deadline. Adapters must add an explicit positive headroom rather than copying this value into another timeout table; that leaves enough time for the daemon's classified response to cross the socket before the caller gives up.

func LookupMethodTiming added in v2.8.0

func LookupMethodTiming(method string) (MethodTiming, bool)

LookupMethodTiming returns the shared lifetime and daemon deadline for a stable method name.

func MethodTimings added in v2.8.0

func MethodTimings() []MethodTiming

MethodTimings returns a copy of the complete method timing catalog.

func (MethodTiming) ClientTimeout added in v2.8.0

func (t MethodTiming) ClientTimeout(headroom time.Duration) time.Duration

ClientTimeout returns the deadline a caller should use after choosing its transport/rendering headroom. Streaming methods have no fixed deadline. A non-positive headroom is a programming error because equal client and daemon deadlines race and can hide the daemon's typed timeout response.

type NudgeCandidate

type NudgeCandidate struct {
	Fingerprint string    `json:"fingerprint"`
	Kind        string    `json:"kind"`
	State       string    `json:"state"`
	Severity    string    `json:"severity"`
	Title       string    `json:"title"`
	Body        string    `json:"body"`
	OccurredAt  time.Time `json:"occurred_at,omitzero"`
	DueAt       time.Time `json:"due_at,omitzero"`
	ExpiresAt   time.Time `json:"expires_at,omitzero"`
	Destination string    `json:"destination"`
}

NudgeCandidate is intentionally lockscreen-safe. Its title and body are daemon-authored enum templates; Fingerprint is an opaque semantic identity.

type NudgeConfirmedFlowCoverage

type NudgeConfirmedFlowCoverage struct {
	CoverageFrom              time.Time `json:"coverage_from"`
	PreCutoverFlowsUnreviewed bool      `json:"pre_cutover_flows_unreviewed"`
}

NudgeConfirmedFlowCoverage discloses only the redacted cutover boundary and whether flows before that boundary still require review.

type NudgeCutoverReviewEvidence

type NudgeCutoverReviewEvidence string

NudgeCutoverReviewEvidence identifies the fixed evidence class recorded by a cutover review.

const NudgeCutoverReviewEvidencePairedDeviceForegroundRender NudgeCutoverReviewEvidence = "paired_device_foreground_render_review"

NudgeCutoverReviewEvidencePairedDeviceForegroundRender means the paired device visibly rendered the review in the foreground.

type NudgeCutoverReviewOrigin

type NudgeCutoverReviewOrigin string

NudgeCutoverReviewOrigin identifies the authenticated surface supplying cutover-review evidence.

const NudgeCutoverReviewOriginPairedDevice NudgeCutoverReviewOrigin = "paired_device"

NudgeCutoverReviewOriginPairedDevice is the only accepted review origin.

type NudgeDrawdownSummary

type NudgeDrawdownSummary struct {
	Tier        string   `json:"tier"`
	ConsumedPct *float64 `json:"consumed_pct"`
}

NudgeDrawdownSummary reports the active tier and optional consumption. A nil percentage means the value is unavailable, not zero.

type NudgeInputHealth

type NudgeInputHealth struct {
	Status string    `json:"status"` // ok | unapproved | stale | unavailable | error
	Reason string    `json:"reason,omitempty"`
	AsOf   time.Time `json:"as_of,omitzero"`
}

NudgeInputHealth reports one input's allowlisted status and reason. A zero AsOf is invalid and is normalized to error rather than treated as current.

type NudgeShadowSummary

type NudgeShadowSummary struct {
	Count int `json:"count"`
}

NudgeShadowSummary reports the redacted number of shadow findings.

type NudgeSnapshotContext

type NudgeSnapshotContext struct {
	Shadow   *NudgeShadowSummary   `json:"shadow,omitempty"`
	Drawdown *NudgeDrawdownSummary `json:"drawdown,omitempty"`
}

NudgeSnapshotContext is visible snapshot detail, never candidate or push copy. Its concrete summaries deliberately admit no arbitrary display text.

type NudgeSourceHealth

type NudgeSourceHealth struct {
	Aggregate      string           `json:"aggregate"` // ready | suppressed | degraded
	Policy         NudgeInputHealth `json:"policy"`
	Reconciliation NudgeInputHealth `json:"reconciliation"`
	Capital        NudgeInputHealth `json:"capital"`
	Pins           NudgeInputHealth `json:"pins"`
	Cadence        NudgeInputHealth `json:"cadence"`
	ConfirmedFlow  NudgeInputHealth `json:"confirmed_flow"`
}

NudgeSourceHealth is separate from app polling/relay health. Fixed fields prevent generic notes, raw fingerprints, or unknown source names from widening the wire contract.

func NormalizeNudgeSourceHealth

func NormalizeNudgeSourceHealth(health NudgeSourceHealth, candidateCount int) NudgeSourceHealth

NormalizeNudgeSourceHealth is the mandatory wire boundary. It removes raw or incoherent status/reason values, preserves missing timestamps as missing, and derives Aggregate rather than trusting caller-provided state.

func (NudgeSourceHealth) MarshalJSON

func (health NudgeSourceHealth) MarshalJSON() ([]byte, error)

MarshalJSON prevents standalone source-health values from carrying a false ready aggregate. Without result candidate context, partial health is conservatively suppressed.

type NudgesCutoverReviewParams

type NudgesCutoverReviewParams struct {
	Origin   NudgeCutoverReviewOrigin   `json:"origin"`
	Evidence NudgeCutoverReviewEvidence `json:"evidence"`
}

NudgesCutoverReviewParams carries only the fixed paired-surface evidence labels. The daemon, not this DTO, authenticates the origin and authorizes the advisory evidence write against current broker-backed report health.

func (NudgesCutoverReviewParams) MarshalJSON

func (params NudgesCutoverReviewParams) MarshalJSON() ([]byte, error)

MarshalJSON validates the fixed origin and evidence values before encoding.

func (*NudgesCutoverReviewParams) UnmarshalJSON

func (params *NudgesCutoverReviewParams) UnmarshalJSON(data []byte) error

UnmarshalJSON rejects null, missing, duplicate, or unknown fields and validates the resulting review evidence.

type NudgesCutoverReviewResult

type NudgesCutoverReviewResult struct {
	OK              bool                       `json:"ok"`
	AlreadyReviewed bool                       `json:"already_reviewed"`
	ReviewedAt      time.Time                  `json:"reviewed_at"`
	CoverageFrom    time.Time                  `json:"coverage_from"`
	Evidence        NudgeCutoverReviewEvidence `json:"evidence"`
}

NudgesCutoverReviewResult reports only daemon-authored, redacted evidence. It is neither broker authority nor monthly-pulse completion.

func (NudgesCutoverReviewResult) MarshalJSON

func (result NudgesCutoverReviewResult) MarshalJSON() ([]byte, error)

MarshalJSON validates success, timestamps, and evidence before encoding.

func (*NudgesCutoverReviewResult) UnmarshalJSON

func (result *NudgesCutoverReviewResult) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts only the exact validated result shape.

type NudgesSnapshotParams

type NudgesSnapshotParams struct{}

NudgesSnapshotParams is empty because nudges.snapshot is a gateway-independent, side-effect-free read.

func (NudgesSnapshotParams) MarshalJSON

func (NudgesSnapshotParams) MarshalJSON() ([]byte, error)

MarshalJSON emits the canonical empty object and never JSON null.

func (*NudgesSnapshotParams) UnmarshalJSON

func (params *NudgesSnapshotParams) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts only an exact empty object.

type NudgesSnapshotResult

type NudgesSnapshotResult struct {
	AsOf                  time.Time                   `json:"as_of"`
	Candidates            []NudgeCandidate            `json:"candidates"`
	SourceHealth          NudgeSourceHealth           `json:"source_health"`
	Reconciliation        *ReconAutomationStatus      `json:"reconciliation,omitempty"`
	ConfirmedFlowCoverage *NudgeConfirmedFlowCoverage `json:"confirmed_flow_coverage,omitempty"`
	Context               *NudgeSnapshotContext       `json:"context,omitempty"`
}

NudgesSnapshotResult is the daemon-authored advisory nudge snapshot. An empty Candidates slice is reassuring only when SourceHealth is ready.

func (NudgesSnapshotResult) IsCleanEmpty

func (result NudgesSnapshotResult) IsCleanEmpty() bool

IsCleanEmpty reports whether the snapshot is valid, fully covered, and has neither candidates nor contextual findings.

func (NudgesSnapshotResult) MarshalJSON

func (result NudgesSnapshotResult) MarshalJSON() ([]byte, error)

MarshalJSON validates and canonicalizes health and candidates before encoding the snapshot.

type Opportunity

type Opportunity struct {
	Key                      string                        `json:"key"`
	Revision                 string                        `json:"revision"`
	State                    string                        `json:"state"`
	Bucket                   string                        `json:"bucket"`
	Rank                     int                           `json:"rank"`
	Symbol                   string                        `json:"symbol"`
	SecType                  string                        `json:"sec_type"`
	Action                   string                        `json:"action"`
	ExerciseAction           int                           `json:"exercise_action"`
	Quantity                 int                           `json:"quantity"`
	MaxQuantity              int                           `json:"max_quantity"`
	PositionQuantity         float64                       `json:"position_quantity"`
	PositionEffect           string                        `json:"position_effect"`
	UnderlyingQuantityBefore float64                       `json:"underlying_quantity_before"`
	UnderlyingQuantityAfter  float64                       `json:"underlying_quantity_after"`
	UnderlyingShareChange    float64                       `json:"underlying_share_change"`
	PostExerciseRisk         *OpportunityPostExerciseRisk  `json:"post_exercise_risk,omitempty"`
	Contract                 ContractParams                `json:"contract"`
	UnderlyingContract       ContractParams                `json:"underlying_contract"`
	ExpectedGain             float64                       `json:"expected_gain,omitempty"`
	ExpectedGainCurrency     string                        `json:"expected_gain_currency,omitempty"`
	IntrinsicValue           float64                       `json:"intrinsic_value,omitempty"`
	CloseValue               float64                       `json:"close_value,omitempty"`
	OptionBid                *float64                      `json:"option_bid,omitempty"`
	UnderlyingBid            *float64                      `json:"underlying_bid,omitempty"`
	UnderlyingAsk            *float64                      `json:"underlying_ask,omitempty"`
	Reason                   string                        `json:"reason"`
	Details                  []string                      `json:"details,omitempty"`
	Score                    float64                       `json:"score,omitempty"`
	PolicyID                 string                        `json:"policy_id,omitempty"`
	PolicyVersion            int                           `json:"policy_version,omitempty"`
	PolicyFingerprint        Fingerprint                   `json:"policy_fingerprint,omitzero"`
	SourceFingerprints       OpportunitySourceFingerprints `json:"source_fingerprints,omitzero"`
	Blockers                 []TradingBlocker              `json:"blockers,omitempty"`
	CreatedAt                time.Time                     `json:"created_at,omitzero"`
}

Opportunity is an advisory exercise candidate bound to its key and revision. It is not a preview token or exercise authorization.

type OpportunityCounts

type OpportunityCounts struct {
	Total                int     `json:"total"`
	Actionable           int     `json:"actionable"`
	Blocked              int     `json:"blocked"`
	OptionExercise       int     `json:"option_exercise"`
	ExpectedGain         float64 `json:"expected_gain,omitempty"`
	ExpectedGainCurrency string  `json:"expected_gain_currency,omitempty"`
}

OpportunityCounts summarizes the opportunities in the enclosing revision.

type OpportunityExercisePreviewParams

type OpportunityExercisePreviewParams struct {
	Key       string `json:"key"`
	Revision  string `json:"revision"`
	Quantity  int    `json:"quantity,omitempty"`
	TimeoutMs int    `json:"timeout_ms,omitempty"`
	Origin    string `json:"origin,omitempty"`
}

OpportunityExercisePreviewParams identifies an exact candidate revision for gated broker preview. Origin is audit evidence, not authority by itself.

type OpportunityExercisePreviewResult

type OpportunityExercisePreviewResult struct {
	Accepted              bool             `json:"accepted"`
	Opportunity           Opportunity      `json:"opportunity"`
	PreviewTokenID        string           `json:"preview_token_id,omitempty"`
	TokenMinted           bool             `json:"token_minted"`
	PreviewTokenExpiresAt time.Time        `json:"preview_token_expires_at,omitzero"`
	SubmitEligible        bool             `json:"submit_eligible"`
	Blockers              []TradingBlocker `json:"blockers,omitempty"`
	AsOf                  time.Time        `json:"as_of"`
}

OpportunityExercisePreviewResult reports daemon and broker eligibility. A token ID is an audit identifier; the raw authorizing token remains private.

type OpportunityExerciseSubmitParams

type OpportunityExerciseSubmitParams struct {
	Key       string `json:"key"`
	Revision  string `json:"revision"`
	Quantity  int    `json:"quantity,omitempty"`
	TimeoutMs int    `json:"timeout_ms,omitempty"`
	Origin    string `json:"origin,omitempty"`
}

OpportunityExerciseSubmitParams requests gated exercise of an exact revision. The daemon revalidates current authority; prior preview is not submit consent.

type OpportunityExerciseSubmitResult

type OpportunityExerciseSubmitResult struct {
	Accepted       bool                              `json:"accepted"`
	Opportunity    Opportunity                       `json:"opportunity"`
	Preview        *OpportunityExercisePreviewResult `json:"preview,omitempty"`
	PreviewTokenID string                            `json:"preview_token_id,omitempty"`
	OrderRef       string                            `json:"order_ref,omitempty"`
	Blockers       []TradingBlocker                  `json:"blockers,omitempty"`
	Message        string                            `json:"message,omitempty"`
	AsOf           time.Time                         `json:"as_of"`
}

OpportunityExerciseSubmitResult reports the terminal outcome of a gated submission request. Accepted is false when blockers prevented submission.

type OpportunityIgnoreParams

type OpportunityIgnoreParams struct {
	Key      string `json:"key"`
	Revision string `json:"revision,omitempty"`
	Reason   string `json:"reason,omitempty"`
}

OpportunityIgnoreParams dismisses an advisory candidate revision; it does not alter positions or broker orders.

type OpportunityIgnoreResult

type OpportunityIgnoreResult struct {
	Accepted bool      `json:"accepted"`
	Key      string    `json:"key"`
	Revision string    `json:"revision,omitempty"`
	Message  string    `json:"message,omitempty"`
	AsOf     time.Time `json:"as_of"`
}

OpportunityIgnoreResult reports whether the advisory dismissal was accepted.

type OpportunityPolicyStatus

type OpportunityPolicyStatus struct {
	Kind          string           `json:"kind,omitempty"`
	Status        string           `json:"status"`
	PolicyID      string           `json:"policy_id,omitempty"`
	PolicyVersion int              `json:"policy_version,omitempty"`
	Profile       string           `json:"profile,omitempty"`
	Fingerprint   Fingerprint      `json:"fingerprint,omitzero"`
	Source        string           `json:"source,omitempty"`
	Path          string           `json:"path,omitempty"`
	LoadedAt      time.Time        `json:"loaded_at,omitzero"`
	LastCheckedAt time.Time        `json:"last_checked_at,omitzero"`
	Message       string           `json:"message,omitempty"`
	Blockers      []TradingBlocker `json:"blockers,omitempty"`
}

OpportunityPolicyStatus reports the loaded policy identity and blockers. A status of active is required before absence of blockers is meaningful.

type OpportunityPostExerciseRisk

type OpportunityPostExerciseRisk struct {
	Underlying                      string   `json:"underlying,omitempty"`
	BeforeQuantity                  float64  `json:"before_quantity"`
	AfterQuantity                   float64  `json:"after_quantity"`
	ShareChange                     float64  `json:"share_change"`
	PositionEffect                  string   `json:"position_effect,omitempty"`
	RiskChange                      string   `json:"risk_change,omitempty"`
	RiskOpened                      bool     `json:"risk_opened,omitempty"`
	RiskIncreased                   bool     `json:"risk_increased,omitempty"`
	RiskFlipped                     bool     `json:"risk_flipped,omitempty"`
	ProtectionReviewNeeded          bool     `json:"protection_review_needed"`
	ProtectionReviewReason          string   `json:"protection_review_reason,omitempty"`
	ProtectionCoverageState         string   `json:"protection_coverage_state,omitempty"`
	CurrentProtectedQuantity        float64  `json:"current_protected_quantity,omitempty"`
	CurrentUnprotectedQuantity      float64  `json:"current_unprotected_quantity,omitempty"`
	CurrentUnprotectedNotionalBase  *float64 `json:"current_unprotected_notional_base,omitempty"`
	UnprotectedNotionalBaseCurrency string   `json:"unprotected_notional_base_currency,omitempty"`
	WarningCodes                    []string `json:"warning_codes,omitempty"`
}

OpportunityPostExerciseRisk is advisory context for what exercising a long option would do to the underlying stock/ETF exposure. It does not authorize or block submit; preview/submit gates remain daemon-owned and broker-gated.

type OpportunityRefreshParams

type OpportunityRefreshParams struct {
	Show bool `json:"show,omitempty"`
}

OpportunityRefreshParams requests recomputation; Show controls rendering.

type OpportunitySnapshot

type OpportunitySnapshot struct {
	Kind               string                        `json:"kind"`
	SchemaVersion      string                        `json:"schema_version"`
	AsOf               time.Time                     `json:"as_of"`
	Revision           string                        `json:"revision"`
	AccountID          string                        `json:"account_id,omitempty"`
	AccountMode        string                        `json:"account_mode,omitempty"`
	PolicyID           string                        `json:"policy_id,omitempty"`
	PolicyVersion      int                           `json:"policy_version,omitempty"`
	PolicyFingerprint  Fingerprint                   `json:"policy_fingerprint,omitzero"`
	PolicyStatus       OpportunityPolicyStatus       `json:"policy_status"`
	Status             OpportunityStatus             `json:"status"`
	Trading            TradingStatus                 `json:"trading"`
	SourceFingerprints OpportunitySourceFingerprints `json:"source_fingerprints,omitzero"`
	Opportunities      []Opportunity                 `json:"opportunities"`
	Counts             OpportunityCounts             `json:"counts"`
	Blockers           []TradingBlocker              `json:"blockers,omitempty"`
	LoadedFromState    bool                          `json:"loaded_from_state,omitempty"`
}

OpportunitySnapshot is one daemon-authored, account-and-mode-scoped revision. LoadedFromState identifies retained output; callers must still honor status and blockers rather than treating persistence as freshness.

type OpportunitySnapshotParams

type OpportunitySnapshotParams struct {
	Show bool `json:"show,omitempty"`
}

OpportunitySnapshotParams controls adapter rendering only; Show does not expand daemon authority or eligibility.

type OpportunitySourceFingerprints

type OpportunitySourceFingerprints struct {
	Account   *Fingerprint `json:"account,omitempty"`
	Positions *Fingerprint `json:"positions,omitempty"`
}

OpportunitySourceFingerprints carries optional semantic identities for the account and position snapshots used to derive an opportunity revision.

type OpportunityStatus

type OpportunityStatus struct {
	Kind           string                  `json:"kind,omitempty"`
	AsOf           time.Time               `json:"as_of,omitzero"`
	Enabled        bool                    `json:"enabled"`
	HotReload      bool                    `json:"hot_reload"`
	ReloadInterval string                  `json:"reload_interval,omitempty"`
	RefreshCadence string                  `json:"refresh_cadence,omitempty"`
	Policy         OpportunityPolicyStatus `json:"policy"`
	Trading        TradingStatus           `json:"trading"`
	Blocked        bool                    `json:"blocked"`
	Blockers       []TradingBlocker        `json:"blockers,omitempty"`
}

OpportunityStatus combines opportunity-policy and trading readiness. It is status evidence only and does not authorize exercise submission.

type OptionHealthSummary

type OptionHealthSummary struct {
	GreeksCoverage                  int     `json:"greeks_coverage"`
	GreeksTotal                     int     `json:"greeks_total"`
	MissingGreeksCount              int     `json:"missing_greeks_count"`
	LowDTECount                     int     `json:"low_dte_count"`
	LowDTEThresholdDays             int     `json:"low_dte_threshold_days"`
	OptionsClosedCount              int     `json:"options_closed_count"`
	MarkOutsideBidAskCount          int     `json:"mark_outside_bid_ask_count"`
	LargeStaleDailyLossCount        int     `json:"large_stale_daily_loss_count"`
	LargeStaleDailyLossThresholdPct float64 `json:"large_stale_daily_loss_threshold_pct_nlv"`
	FlaggedLegCount                 int     `json:"flagged_leg_count"`
	FlaggedLegsReturned             int     `json:"flagged_legs_returned"`
}

OptionHealthSummary summarizes availability and concentration of option risk.

type OptionRiskLegSummary

type OptionRiskLegSummary struct {
	Symbol       string    `json:"symbol"`
	Expiry       string    `json:"expiry,omitempty"`
	DTE          *int      `json:"dte,omitempty"`
	Right        string    `json:"right,omitempty"`
	Strike       float64   `json:"strike,omitempty"`
	Quantity     float64   `json:"quantity"`
	MarketValue  float64   `json:"market_value_ccy"`
	DailyPnLBase *float64  `json:"daily_pnl_base,omitempty"`
	Delta        *float64  `json:"delta,omitempty"`
	Gamma        *float64  `json:"gamma,omitempty"`
	Theta        *float64  `json:"theta,omitempty"`
	Vega         *float64  `json:"vega,omitempty"`
	DataType     string    `json:"data_type,omitempty"`
	QuoteQuality string    `json:"quote_quality,omitempty"`
	Warnings     []string  `json:"warnings,omitempty"`
	Reasons      []string  `json:"reasons"`
	AsOf         time.Time `json:"as_of,omitzero"`
}

OptionRiskLegSummary is one material option-risk leg in a compact result.

type OrderCancelParams

type OrderCancelParams struct {
	ID        string `json:"id"`
	TimeoutMs int    `json:"timeout_ms,omitempty"`
	// Origin is journaled for audit. Cancel is exempt from the live
	// agent-origin block: refusing a cancel can never reduce risk less than
	// allowing it, though cancelling a protective stop does remove
	// protection — see SECURITY.md.
	Origin string `json:"origin,omitempty"`
}

OrderCancelParams requests cancellation of a locally tracked order. Cancel is intentionally identified by local order_ref, IBKR order ID, or permanent ID so the daemon can bind the request to journal evidence first.

type OrderCancelResult

type OrderCancelResult struct {
	Accepted        bool      `json:"accepted"`
	Order           OrderView `json:"order"`
	Status          string    `json:"status,omitempty"`
	LifecycleStatus string    `json:"lifecycle_status,omitempty"`
	SendState       string    `json:"send_state,omitempty"`
	Message         string    `json:"message,omitempty"`
	AsOf            time.Time `json:"as_of"`
}

OrderCancelResult reports the observed state after a cancellation request. Accepted does not imply the broker has confirmed cancellation.

type OrderDraft

type OrderDraft struct {
	Action        string          `json:"action"`
	Contract      ContractParams  `json:"contract"`
	Quantity      int             `json:"quantity"`
	OrderType     string          `json:"order_type"`
	LimitPrice    float64         `json:"limit_price"`
	Trail         *OrderTrailSpec `json:"trail,omitempty"`
	TriggerMethod int             `json:"trigger_method,omitempty"`
	TIF           string          `json:"tif"`
	OutsideRTH    bool            `json:"outside_rth"`
	Strategy      string          `json:"strategy"`
	OrderRef      string          `json:"order_ref"`
	OpenClose     string          `json:"open_close,omitempty"`
	Source        string          `json:"source,omitempty"`
}

OrderDraft is the canonical local intent bound into a preview token.

type OrderEvent

type OrderEvent struct {
	At              time.Time       `json:"at"`
	Type            string          `json:"type"`
	OrderRef        string          `json:"order_ref,omitempty"`
	PreviewTokenID  string          `json:"preview_token_id,omitempty"`
	ReservedOrderID int             `json:"reserved_order_id,omitempty"`
	ClientID        int             `json:"client_id,omitempty"`
	PermID          int             `json:"perm_id,omitempty"`
	Account         string          `json:"account,omitempty"`
	Endpoint        string          `json:"endpoint,omitempty"`
	Mode            string          `json:"mode,omitempty"`
	Source          string          `json:"source,omitempty"`
	PurgeID         string          `json:"purge_id,omitempty"`
	LegID           string          `json:"leg_id,omitempty"`
	BypassPreview   bool            `json:"bypass_preview,omitempty"`
	Symbol          string          `json:"symbol,omitempty"`
	SecType         string          `json:"sec_type,omitempty"`
	ConID           int             `json:"con_id,omitempty"`
	Exchange        string          `json:"exchange,omitempty"`
	PrimaryExch     string          `json:"primary_exch,omitempty"`
	Currency        string          `json:"currency,omitempty"`
	LocalSymbol     string          `json:"local_symbol,omitempty"`
	TradingClass    string          `json:"trading_class,omitempty"`
	Expiry          string          `json:"expiry,omitempty"`
	Strike          float64         `json:"strike,omitempty"`
	Right           string          `json:"right,omitempty"`
	Multiplier      int             `json:"multiplier,omitempty"`
	Action          string          `json:"action,omitempty"`
	OrderType       string          `json:"order_type,omitempty"`
	TIF             string          `json:"tif,omitempty"`
	TriggerMethod   int             `json:"trigger_method,omitempty"`
	OutsideRTH      bool            `json:"outside_rth,omitempty"`
	Quantity        float64         `json:"quantity,omitempty"`
	LimitPrice      float64         `json:"limit_price,omitempty"`
	Trail           *OrderTrailSpec `json:"trail,omitempty"`
	OpenClose       string          `json:"open_close,omitempty"`
	Status          string          `json:"status,omitempty"`
	LifecycleStatus string          `json:"lifecycle_status,omitempty"`
	Filled          float64         `json:"filled,omitempty"`
	Remaining       float64         `json:"remaining,omitempty"`
	AvgFillPrice    float64         `json:"avg_fill_price,omitempty"`
	LastFillPrice   float64         `json:"last_fill_price,omitempty"`
	WhyHeld         string          `json:"why_held,omitempty"`
	MktCapPrice     float64         `json:"mkt_cap_price,omitempty"`
	ExecID          string          `json:"exec_id,omitempty"`
	ExecTime        string          `json:"exec_time,omitempty"`
	ErrorCode       int             `json:"error_code,omitempty"`
	SendState       string          `json:"send_state,omitempty"`
	Message         string          `json:"message,omitempty"`
}

OrderEvent is the read-only lifecycle/audit row exposed from the private journal. It redacts full preview tokens and never implies a broker write unless Type/SendState explicitly say one was attempted.

type OrderMarginImpact

type OrderMarginImpact struct {
	Currency                string   `json:"currency,omitempty"`
	InitialMarginBefore     *float64 `json:"initial_margin_before,omitempty"`
	InitialMarginAfter      *float64 `json:"initial_margin_after,omitempty"`
	MaintenanceMarginBefore *float64 `json:"maintenance_margin_before,omitempty"`
	MaintenanceMarginAfter  *float64 `json:"maintenance_margin_after,omitempty"`
	EquityWithLoanBefore    *float64 `json:"equity_with_loan_before,omitempty"`
	EquityWithLoanAfter     *float64 `json:"equity_with_loan_after,omitempty"`
	Commission              *float64 `json:"commission,omitempty"`
	MinCommission           *float64 `json:"min_commission,omitempty"`
	MaxCommission           *float64 `json:"max_commission,omitempty"`
	CommissionCurrency      string   `json:"commission_currency,omitempty"`
	WarningText             string   `json:"warning_text,omitempty"`
	CompletedStatus         string   `json:"completed_status,omitempty"`
	CompletedTime           string   `json:"completed_time,omitempty"`
}

OrderMarginImpact is populated from IBKR WhatIf once the raw preview-only path is available in the trading build.

type OrderModifyParams

type OrderModifyParams struct {
	ID           string `json:"id"`
	PreviewToken string `json:"preview_token"`
	TimeoutMs    int    `json:"timeout_ms,omitempty"`
	Origin       string `json:"origin,omitempty"`
}

OrderModifyParams applies a constrained modify to a locally tracked open order. The preview token must describe the replacement draft; the daemon reuses the existing broker order ID instead of creating a new one.

type OrderModifyResult

type OrderModifyResult struct {
	Accepted        bool       `json:"accepted"`
	Mode            string     `json:"mode"`
	Account         string     `json:"account"`
	Endpoint        string     `json:"endpoint"`
	ClientID        int        `json:"client_id"`
	OrderRef        string     `json:"order_ref"`
	PreviewTokenID  string     `json:"preview_token_id"`
	ReservedOrderID int        `json:"reserved_order_id"`
	Draft           OrderDraft `json:"draft"`
	Status          string     `json:"status,omitempty"`
	LifecycleStatus string     `json:"lifecycle_status,omitempty"`
	SendState       string     `json:"send_state,omitempty"`
	Message         string     `json:"message,omitempty"`
	AsOf            time.Time  `json:"as_of"`
}

OrderModifyResult reports the durable local and broker-send state of a gated modification attempt. Accepted does not imply broker acknowledgement.

type OrderPlaceParams

type OrderPlaceParams struct {
	PreviewToken string `json:"preview_token"`
	TimeoutMs    int    `json:"timeout_ms,omitempty"`
	// Origin identifies who is asking (OrderOrigin*) for audit and any
	// origin-specific policy.
	Origin string `json:"origin,omitempty"`
}

OrderPlaceParams redeems a submit-eligible preview token for a broker transmit. The daemon revalidates the local trading gate and token binding before any socket write.

type OrderPlaceResult

type OrderPlaceResult struct {
	Accepted        bool       `json:"accepted"`
	Mode            string     `json:"mode"`
	Account         string     `json:"account"`
	Endpoint        string     `json:"endpoint"`
	ClientID        int        `json:"client_id"`
	OrderRef        string     `json:"order_ref"`
	PreviewTokenID  string     `json:"preview_token_id"`
	ReservedOrderID int        `json:"reserved_order_id"`
	Draft           OrderDraft `json:"draft"`
	Status          string     `json:"status,omitempty"`
	LifecycleStatus string     `json:"lifecycle_status,omitempty"`
	SendState       string     `json:"send_state,omitempty"`
	Message         string     `json:"message,omitempty"`
	AsOf            time.Time  `json:"as_of"`
}

OrderPlaceResult reports the durable local and broker-send state of a gated placement attempt. Accepted does not imply a fill; LifecycleStatus and SendState describe subsequent authority.

type OrderPositionImpact

type OrderPositionImpact struct {
	Before float64 `json:"before"`
	After  float64 `json:"after"`
	Effect string  `json:"effect"`
}

OrderPositionImpact reports local position-effect math. Broker permissions and margin remain authoritative; this is a disclosure and local safety gate.

type OrderPreviewParams

type OrderPreviewParams struct {
	Action     string          `json:"action"` // BUY | SELL, case-insensitive
	Contract   ContractParams  `json:"contract"`
	Quantity   int             `json:"quantity"`
	OrderType  string          `json:"order_type,omitempty"` // LMT | TRAIL | TRAIL LIMIT
	LimitPrice *float64        `json:"limit_price,omitempty"`
	Trail      *OrderTrailSpec `json:"trail,omitempty"`
	// TriggerMethod is the IBKR stop/trigger method integer. Zero delegates
	// to IBKR defaults; protective stock/ETF trails default to LAST (2).
	TriggerMethod int    `json:"trigger_method,omitempty"`
	Strategy      string `json:"strategy,omitempty"` // default patient-limit for stocks/ETFs
	TIF           string `json:"tif,omitempty"`      // default DAY
	OutsideRTH    bool   `json:"outside_rth,omitempty"`
	ReplaceID     string `json:"replace_id,omitempty"`
	TimeoutMs     int    `json:"timeout_ms,omitempty"`
	Source        string `json:"source,omitempty"`
}

OrderPreviewParams asks the daemon to validate and price an order draft, then mint a short-lived preview token. The preview path never places the order; place/modify/cancel remain separate gated RPCs.

type OrderPreviewResult

type OrderPreviewResult struct {
	PreviewToken          string    `json:"preview_token,omitempty"`
	PreviewTokenID        string    `json:"preview_token_id,omitempty"`
	PreviewTokenScope     string    `json:"preview_token_scope,omitempty"`
	PreviewTokenExpiresAt time.Time `json:"preview_token_expires_at,omitzero"`
	TokenMinted           bool      `json:"token_minted"`
	SubmitEligible        bool      `json:"submit_eligible"`
	// Executable is retained for older clients and is equivalent to
	// SubmitEligible. A minted preview token is not executable unless an
	// accepted broker WhatIf result is bound into the token.
	Executable bool                `json:"executable"`
	Mode       string              `json:"mode"`
	Account    string              `json:"account"`
	Endpoint   string              `json:"endpoint"`
	ClientID   int                 `json:"client_id"`
	Draft      OrderDraft          `json:"draft"`
	Quote      OrderQuoteSnapshot  `json:"quote"`
	Position   OrderPositionImpact `json:"position"`
	Notional   float64             `json:"notional"`
	// Notional is expressed in NotionalCurrency. NotionalBase is the same
	// amount converted through current typed FX evidence for comparison with
	// MaxNotional, which is always denominated in BaseCurrency.
	NotionalCurrency string            `json:"notional_currency,omitempty"`
	NotionalBase     float64           `json:"notional_base,omitempty"`
	BaseCurrency     string            `json:"base_currency,omitempty"`
	FXRate           float64           `json:"fx_rate,omitempty"` // BaseCurrency per NotionalCurrency.
	FXEvidenceAt     time.Time         `json:"fx_evidence_at,omitzero"`
	FXDataType       string            `json:"fx_data_type,omitempty"`
	FXSource         string            `json:"fx_source,omitempty"`
	MaxNotional      float64           `json:"max_notional,omitempty"`
	WhatIf           OrderWhatIfResult `json:"what_if"`
	Warnings         []DataWarning     `json:"warnings,omitempty"`
	AsOf             time.Time         `json:"as_of"`
}

OrderPreviewResult is returned by order.preview. PreviewToken is a daemon- signed bearer token for a later place flow; this RPC itself does not submit anything to IBKR.

type OrderQuoteSnapshot

type OrderQuoteSnapshot struct {
	Symbol         string         `json:"symbol"`
	Bid            *float64       `json:"bid,omitempty"`
	Ask            *float64       `json:"ask,omitempty"`
	Last           *float64       `json:"last,omitempty"`
	Mark           *float64       `json:"mark,omitempty"`
	Midpoint       *float64       `json:"midpoint,omitempty"`
	DataType       string         `json:"data_type,omitempty"`
	QuoteQuality   string         `json:"quote_quality,omitempty"`
	SpreadPct      *float64       `json:"spread_pct,omitempty"`
	PriceAt        time.Time      `json:"price_at,omitzero"`
	PriceAsOf      string         `json:"price_as_of,omitempty"`
	Stale          bool           `json:"stale,omitempty"`
	StaleReason    string         `json:"stale_reason,omitempty"`
	AsOf           time.Time      `json:"as_of,omitzero"`
	SessionContext *MarketSession `json:"session_context,omitempty"`
	Warnings       []DataWarning  `json:"warnings,omitempty"`
}

OrderQuoteSnapshot captures the market-data inputs used by preview pricing.

type OrderStatusParams

type OrderStatusParams struct {
	ID string `json:"id"`
}

OrderStatusParams identifies one journal-backed order view by order ref, IBKR order ID, or permanent ID.

type OrderStatusResult

type OrderStatusResult struct {
	Found              bool         `json:"found"`
	Order              OrderView    `json:"order,omitzero"`
	Events             []OrderEvent `json:"events,omitempty"`
	AsOf               time.Time    `json:"as_of"`
	Account            string       `json:"account,omitempty"`
	Mode               string       `json:"mode,omitempty"`
	LastLocalEventAt   time.Time    `json:"last_local_event_at,omitzero"`
	NotBrokerStatement string       `json:"not_broker_statement"`
	Limitations        []string     `json:"limitations"`
}

OrderStatusResult returns local product state and bounded audit events for one order identity. Found false leaves Order at its zero value.

type OrderTrailSpec

type OrderTrailSpec struct {
	Basis            string   `json:"basis,omitempty"`
	OffsetType       string   `json:"offset_type"`
	TrailingPercent  *float64 `json:"trailing_percent,omitempty"`
	TrailingAmount   *float64 `json:"trailing_amount,omitempty"`
	InitialStopPrice float64  `json:"initial_stop_price"`
	LimitOffset      *float64 `json:"limit_offset,omitempty"`
}

OrderTrailSpec is the canonical broker-side trailing-stop intent. Percent values use IBKR API semantics: 2 means 2%, and 0.50 means 0.50%.

type OrderView

type OrderView struct {
	OrderRef        string          `json:"order_ref,omitempty"`
	PreviewTokenID  string          `json:"preview_token_id,omitempty"`
	ReservedOrderID int             `json:"reserved_order_id,omitempty"`
	ClientID        int             `json:"client_id,omitempty"`
	PermID          int             `json:"perm_id,omitempty"`
	Account         string          `json:"account,omitempty"`
	Endpoint        string          `json:"endpoint,omitempty"`
	Mode            string          `json:"mode,omitempty"`
	Source          string          `json:"source,omitempty"`
	PurgeID         string          `json:"purge_id,omitempty"`
	LegID           string          `json:"leg_id,omitempty"`
	BypassPreview   bool            `json:"bypass_preview,omitempty"`
	Symbol          string          `json:"symbol,omitempty"`
	SecType         string          `json:"sec_type,omitempty"`
	ConID           int             `json:"con_id,omitempty"`
	Exchange        string          `json:"exchange,omitempty"`
	PrimaryExch     string          `json:"primary_exch,omitempty"`
	Currency        string          `json:"currency,omitempty"`
	LocalSymbol     string          `json:"local_symbol,omitempty"`
	TradingClass    string          `json:"trading_class,omitempty"`
	Expiry          string          `json:"expiry,omitempty"`
	Strike          float64         `json:"strike,omitempty"`
	Right           string          `json:"right,omitempty"`
	Multiplier      int             `json:"multiplier,omitempty"`
	Action          string          `json:"action,omitempty"`
	OrderType       string          `json:"order_type,omitempty"`
	TIF             string          `json:"tif,omitempty"`
	TriggerMethod   int             `json:"trigger_method,omitempty"`
	OutsideRTH      bool            `json:"outside_rth,omitempty"`
	Quantity        float64         `json:"quantity,omitempty"`
	LimitPrice      float64         `json:"limit_price,omitempty"`
	Trail           *OrderTrailSpec `json:"trail,omitempty"`
	OpenClose       string          `json:"open_close,omitempty"`
	Status          string          `json:"status,omitempty"`
	LifecycleStatus string          `json:"lifecycle_status"`
	Filled          float64         `json:"filled,omitempty"`
	Remaining       float64         `json:"remaining,omitempty"`
	AvgFillPrice    float64         `json:"avg_fill_price,omitempty"`
	LastFillPrice   float64         `json:"last_fill_price,omitempty"`
	WhyHeld         string          `json:"why_held,omitempty"`
	MktCapPrice     float64         `json:"mkt_cap_price,omitempty"`
	SendState       string          `json:"send_state,omitempty"`
	LastEvent       string          `json:"last_event,omitempty"`
	// LastErrorCode is populated only when LastEvent is broker-error. It is
	// typed audit evidence; LastMessage remains untrusted display text.
	LastErrorCode       int    `json:"last_error_code,omitempty"`
	LastMessage         string `json:"last_message,omitempty"`
	ReconciliationState string `json:"reconciliation_state,omitempty"`
	// ReconciliationKind classifies a position_mismatch by consequence:
	// short_entry_full (no coverage left; triggering opens a fresh
	// opposite-direction position of the full remaining quantity) or
	// short_entry_excess (partial coverage; triggering closes the position
	// and opens the excess). Severity is always "critical" for both — the
	// damaging event is identical; the kinds differ only in the offered fix
	// (cancel vs reduce). ReduceToQuantity is set only for the excess kind:
	// the exact quantity a reduce-modify must target.
	ReconciliationKind     string    `json:"reconciliation_kind,omitempty"`
	ReconciliationSeverity string    `json:"reconciliation_severity,omitempty"`
	ShortRiskQuantity      float64   `json:"short_risk_quantity,omitempty"`
	ReduceToQuantity       float64   `json:"reduce_to_quantity,omitempty"`
	BrokerTruthAsOf        time.Time `json:"broker_truth_as_of,omitzero"`
	UpdatedAt              time.Time `json:"updated_at,omitzero"`
	Open                   bool      `json:"open"`
	ModifyEligible         bool      `json:"modify_eligible"`
	CancelEligible         bool      `json:"cancel_eligible"`
}

OrderView is the daemon's read-only product state for one locally observed order intent. It is reduced from the append-only journal; broker callbacks remain authoritative for acknowledgement/fill/cancel status.

type OrderWhatIfResult

type OrderWhatIfResult struct {
	Status             string             `json:"status"`
	RequiredForSubmit  bool               `json:"required_for_submit"`
	Available          bool               `json:"available"`
	Message            string             `json:"message,omitempty"`
	Action             string             `json:"action,omitempty"`
	AdvancedRejectJSON string             `json:"advanced_reject_json,omitempty"`
	Margin             *OrderMarginImpact `json:"margin,omitempty"`
}

OrderWhatIfResult is the broker preview surface. Status is "accepted" only after IBKR returns a successful WhatIf response for this exact draft.

type OrdersHistoryParams

type OrdersHistoryParams struct {
	Since      string `json:"since,omitempty"`
	Until      string `json:"until,omitempty"`
	Limit      int    `json:"limit,omitempty"`
	EventLimit int    `json:"event_limit,omitempty"`
}

OrdersHistoryParams reads bounded local order-journal history for the current broker account/mode. Since and Until accept RFC3339 timestamps or YYYY-MM-DD UTC dates; Limit caps returned grouped order rows, while EventLimit caps returned lifecycle events per grouped order row.

type OrdersHistoryResult

type OrdersHistoryResult struct {
	Orders             []OrdersHistoryRow `json:"orders"`
	AsOf               time.Time          `json:"as_of"`
	Since              time.Time          `json:"since"`
	Until              time.Time          `json:"until"`
	Account            string             `json:"account,omitempty"`
	Mode               string             `json:"mode,omitempty"`
	Count              int                `json:"count"`
	TotalCount         int                `json:"total_count"`
	EventsCount        int                `json:"events_count"`
	TotalEventsCount   int                `json:"total_events_count"`
	Limit              int                `json:"limit"`
	EventLimit         int                `json:"event_limit"`
	Truncated          bool               `json:"truncated"`
	EventsTruncated    bool               `json:"events_truncated"`
	NotBrokerStatement string             `json:"not_broker_statement"`
	Limitations        []string           `json:"limitations"`
}

OrdersHistoryResult is a bounded local history query. Truncated and EventsTruncated disclose omitted rows and events; it is not a broker statement.

type OrdersHistoryRow

type OrdersHistoryRow struct {
	Order            OrderView    `json:"order"`
	Events           []OrderEvent `json:"events"`
	EventsCount      int          `json:"events_count"`
	TotalEventsCount int          `json:"total_events_count"`
	EventsTruncated  bool         `json:"events_truncated"`
}

OrdersHistoryRow combines one reduced order with a bounded event window.

type OrdersOpenParams

type OrdersOpenParams struct{}

OrdersOpenParams reads the current broker account/mode open-order view.

type OrdersOpenResult

type OrdersOpenResult struct {
	Orders             []OrderView `json:"orders"`
	AsOf               time.Time   `json:"as_of"`
	Account            string      `json:"account,omitempty"`
	Mode               string      `json:"mode,omitempty"`
	LastLocalEventAt   time.Time   `json:"last_local_event_at,omitzero"`
	NotBrokerStatement string      `json:"not_broker_statement"`
	Limitations        []string    `json:"limitations"`
}

OrdersOpenResult is the daemon's locally reduced view of currently open orders. It is explicitly not a broker statement.

type OverrideParams

type OverrideParams struct {
	// Control is the constitution key being excepted (e.g.
	// "drawdown.warn_consumed_pct").
	Control string `json:"control"`
	Reason  string `json:"reason"`
	// Hours must be positive and at most override.max_duration_hours.
	Hours  int    `json:"hours"`
	Origin string `json:"origin,omitempty"`
}

OverrideParams grants a one-shot exception against one named control.

type OverrideRecord

type OverrideRecord struct {
	ID                string    `json:"id"`
	Control           string    `json:"control"`
	Reason            string    `json:"reason"`
	GrantedAt         time.Time `json:"granted_at"`
	ExpiresAt         time.Time `json:"expires_at"`
	PolicyFingerprint string    `json:"policy_fingerprint,omitempty"`
	Active            bool      `json:"active"`
}

OverrideRecord is one override, active or expired, as journaled.

type PlatformAutoTradeSettings

type PlatformAutoTradeSettings struct {
	ProposalsEnabled SettingsBool   `json:"proposals_enabled"`
	FastPathEnabled  SettingsBool   `json:"fast_path_enabled"`
	PolicyFile       SettingsString `json:"policy_file"`
	HotReload        SettingsBool   `json:"hot_reload"`
	ReloadInterval   SettingsString `json:"reload_interval"`
	ProposalCadence  SettingsString `json:"proposal_cadence"`
}

PlatformAutoTradeSettings exposes proposal-generation preferences and loaded configuration; none of its fields are broker-write authority.

type PlatformBuildSettings

type PlatformBuildSettings struct {
	Channel                 SettingsString `json:"channel"`
	TradingWritesAvailable  SettingsBool   `json:"trading_writes_available"`
	ExperimentalTradingNote string         `json:"experimental_trading_note,omitempty"`
}

PlatformBuildSettings exposes immutable build-channel capabilities.

type PlatformFeatureSettings

type PlatformFeatureSettings struct {
	PurgeRestore    PurgeRestoreSettings    `json:"purge_restore"`
	StockProtection StockProtectionSettings `json:"stock_protection"`
	Rulebook        RulebookSettings        `json:"rulebook"`
}

PlatformFeatureSettings groups runtime feature preferences.

type PlatformHistorySettings

type PlatformHistorySettings struct {
	Rotation HistoryRotationSettings `json:"rotation"`
}

PlatformHistorySettings is retained to preserve the settings response wire shape. Decision-journal rotation is retired under daemon.db authority.

type PlatformMarketDataQuality

type PlatformMarketDataQuality struct {
	Status      string              `json:"status"`
	Summary     string              `json:"summary,omitempty"`
	QuoteCounts map[string]int      `json:"quote_counts,omitempty"`
	DataQuality []DataQualityHealth `json:"data_quality,omitempty"`
	Access      string              `json:"access"`
	Source      string              `json:"source"`
	Reason      string              `json:"reason,omitempty"`
	ObservedAt  time.Time           `json:"observed_at,omitzero"`
}

PlatformMarketDataQuality summarizes current observed feed quality. A zero ObservedAt means no observation is available.

type PlatformMarketDataSetting

type PlatformMarketDataSetting struct {
	Quality PlatformMarketDataQuality `json:"quality"`
}

PlatformMarketDataSetting exposes observed data quality and never persists broker entitlements.

type PlatformRegimeSettings

type PlatformRegimeSettings struct {
	Journal RegimeJournalSettings `json:"journal"`
}

PlatformRegimeSettings holds the regime engine's runtime preferences. Deliberately one knob: the confirmation-gate values (depth, streaks, co-sign, max ages) are code-owned pending_backtest policy — user-tunable gates would fork the decision corpus's comparability (internal-docs/design/regime-calibration.md Part 6).

type PlatformSettings

type PlatformSettings struct {
	Kind       string                    `json:"kind"`
	Features   PlatformFeatureSettings   `json:"features"`
	Trading    PlatformTradingSettings   `json:"trading"`
	AutoTrade  PlatformAutoTradeSettings `json:"auto_trade"`
	Regime     PlatformRegimeSettings    `json:"regime"`
	Stress     PlatformStressSettings    `json:"stress"`
	History    PlatformHistorySettings   `json:"history"`
	MarketData PlatformMarketDataSetting `json:"market_data"`
	Build      PlatformBuildSettings     `json:"build"`
	AsOf       time.Time                 `json:"as_of"`
}

PlatformSettings is the typed, daemon-authored settings view. It combines writable runtime preferences with read-only config, build, and observations.

type PlatformStressSettings

type PlatformStressSettings struct {
	Journal StressJournalSettings `json:"journal"`
}

PlatformStressSettings holds the portfolio-stress evidence-collection runtime preference (internal-docs/design/history-index.md).

type PlatformTradingSettings

type PlatformTradingSettings struct {
	// Freeze is the runtime trading brake: true blocks every new broker
	// write while cancels stay allowed. Toggled via
	// `canary settings set trading.freeze=true|false`.
	Freeze               SettingsBool         `json:"freeze"`
	Mode                 SettingsString       `json:"mode"`
	Account              SettingsString       `json:"account"`
	Endpoint             SettingsString       `json:"endpoint"`
	ClientID             SettingsInt          `json:"client_id"`
	MCPTrading           SettingsString       `json:"mcp_trading"`
	LiveOverride         SettingsString       `json:"live_override"`
	BuildWritesAvailable SettingsBool         `json:"build_writes_available"`
	Limits               TradingLimitSettings `json:"limits"`
}

PlatformTradingSettings combines the runtime freeze brake with read-only trading configuration, build capability, and limits.

type PolicyPinStatus

type PolicyPinStatus struct {
	Policy        string `json:"policy"` // rulebook | protection | stress
	PinnedID      string `json:"pinned_id,omitempty"`
	PinnedVersion string `json:"pinned_version,omitempty"`
	LiveID        string `json:"live_id,omitempty"`
	LiveVersion   string `json:"live_version,omitempty"`
	// Status is match | drift | unpinned | unavailable.
	Status string `json:"status"`
}

PolicyPinStatus compares one constitution inventory pin with the live sibling policy identity.

type PositionGroup

type PositionGroup struct {
	Underlying               string         `json:"underlying"`
	Stock                    *PositionView  `json:"stock,omitempty"`
	Options                  []PositionView `json:"options"`
	GroupMarketValue         float64        `json:"group_market_value_ccy"`
	GroupMarketValueBase     *float64       `json:"group_market_value_base,omitempty"`
	GroupMarketValuePctNLV   *float64       `json:"group_market_value_pct_nlv,omitempty"`
	GroupUnrealizedPnL       float64        `json:"group_unrealized_pnl_ccy"`
	GroupUnrealizedPnLBase   *float64       `json:"group_unrealized_pnl_base,omitempty"`
	GroupDailyPnLBase        *float64       `json:"group_daily_pnl_base,omitempty"`
	GroupEffectiveDelta      *float64       `json:"group_effective_delta,omitempty"`
	GroupDollarDelta         *float64       `json:"group_dollar_delta_ccy,omitempty"`
	GroupDollarDeltaCurrency string         `json:"group_dollar_delta_ccy_currency,omitempty"`
	GroupDollarDeltaBase     *float64       `json:"group_dollar_delta_base,omitempty"`
}

PositionGroup aggregates the stock leg (if any) and option legs per underlying. GroupUnrealizedPnL/GroupMarketValue are serialized with *_ccy names because they are local/security-currency sums across all legs. *_base fields are filled only when every contributing row can be converted to the account base currency. GroupEffectiveDelta / GroupDollarDelta are coherent per-underlying exposures (unlike portfolio-level share-equivalent sums across unrelated symbols).

type PositionView

type PositionView struct {
	Symbol       string  `json:"symbol"`
	SecType      string  `json:"sec_type"`
	ConID        int     `json:"con_id,omitempty"`
	Exchange     string  `json:"exchange,omitempty"`
	Currency     string  `json:"currency,omitempty"`
	LocalSymbol  string  `json:"local_symbol,omitempty"`
	TradingClass string  `json:"trading_class,omitempty"`
	Quantity     float64 `json:"quantity"`
	// Multiplier is the contract multiplier — 1 for stocks, 100 for standard
	// equity options, sometimes higher for index options. Needed by JSON
	// consumers to convert between per-share Mark and per-contract AvgCost
	// on options (IBKR's averageCost is multiplier-inclusive on OPT).
	Multiplier    int     `json:"multiplier"`
	AvgCost       float64 `json:"avg_cost"`
	Mark          float64 `json:"mark"`
	ValuationMark float64 `json:"valuation_mark,omitempty"`
	DataType      string  `json:"data_type,omitempty"`
	// PriceSource names the quote input that produced the row's quote
	// context (last, mark, prev_close, historical_close, ...). Optional
	// because position marks can arrive from the portfolio stream before
	// the daemon has enriched the row with quote data.
	PriceSource       string    `json:"price_source,omitempty"`
	RegularClose      *float64  `json:"regular_close,omitempty"`
	RegularCloseAt    time.Time `json:"regular_close_at,omitzero"`
	PriorRegularClose *float64  `json:"prior_regular_close,omitempty"`
	RegularChange     *float64  `json:"regular_change,omitempty"`
	RegularChangePct  *float64  `json:"regular_change_pct,omitempty"`
	QuotePrice        *float64  `json:"quote_price,omitempty"`
	QuotePriceSource  string    `json:"quote_price_source,omitempty"`
	QuotePriceAt      time.Time `json:"quote_price_at,omitzero"`
	QuotePriceAsOf    string    `json:"quote_price_as_of,omitempty"`
	QuoteChange       *float64  `json:"quote_change,omitempty"`
	QuoteChangePct    *float64  `json:"quote_change_pct,omitempty"`
	PrevClose         *float64  `json:"prev_close,omitempty"`
	Bid               *float64  `json:"bid,omitempty"`
	Ask               *float64  `json:"ask,omitempty"`
	// DayChange is per-share for stocks (Mark − stock prev close); for
	// options it stays nil because we don't track contract-level prev
	// close on the underlying-grouped path. DayChangePct is the same
	// ratio expressed as a percent. DayChangeMoney is the *position*-level
	// dollar impact: quantity × DayChange for stocks; quantity × multiplier
	// × (Mark − OptionPrevClose) for options when OptionPrevClose is
	// populated. nil when any input is missing — never fabricated.
	DayChange      *float64      `json:"day_change,omitempty"`
	DayChangePct   *float64      `json:"day_change_pct,omitempty"`
	DayChangeMoney *float64      `json:"day_change_money,omitempty"`
	DayHigh        *float64      `json:"day_high,omitempty"`
	DayLow         *float64      `json:"day_low,omitempty"`
	Week52High     *float64      `json:"week_52_high,omitempty"`
	Week52Low      *float64      `json:"week_52_low,omitempty"`
	Volume         *int64        `json:"volume,omitempty"`
	AvgVolume      *int64        `json:"avg_volume,omitempty"`
	PriceAt        time.Time     `json:"price_at,omitzero"`
	PriceAsOf      string        `json:"price_as_of,omitempty"`
	FeedType       string        `json:"feed_type,omitempty"`
	SpreadPct      *float64      `json:"spread_pct,omitempty"`
	QuoteQuality   string        `json:"quote_quality,omitempty"`
	Indicative     bool          `json:"indicative,omitempty"`
	VolumePhase    string        `json:"volume_phase,omitempty"`
	Stale          bool          `json:"stale,omitempty"`
	StaleReason    string        `json:"stale_reason,omitempty"`
	WarningDetails []DataWarning `json:"warning_details,omitempty"`
	// QuoteExpectation classifies whether market data should exist for this
	// contract at all. QuoteExpectationNone means a missing quote, mark, or
	// market-event flag is the expected and correct state, so consumers must
	// not render it as a data-quality defect or as exposure of unknown size.
	// The position stays account truth either way.
	QuoteExpectation       string `json:"quote_expectation,omitempty"`
	QuoteExpectationReason string `json:"quote_expectation_reason,omitempty"`
	// SessionContext explains the trading-calendar state behind PriceAt.
	// Populated when the quote context needs interpretation (closed,
	// pre-market, frozen/stale/missing), matching Quote.SessionContext.
	SessionContext    *MarketSession `json:"session_context,omitempty"`
	MarketValue       float64        `json:"market_value_ccy"`
	MarketValueBase   *float64       `json:"market_value_base,omitempty"`
	FXRate            *float64       `json:"fx_rate,omitempty"`
	UnrealizedPnL     float64        `json:"unrealized_pnl_ccy"`
	UnrealizedPnLBase *float64       `json:"unrealized_pnl_base,omitempty"`
	RealizedPnL       float64        `json:"realized_pnl_ccy"`
	RealizedPnLBase   *float64       `json:"realized_pnl_base,omitempty"`

	// DailyPnL is the start-of-trading-day to now P&L for this single
	// contract, sourced from IBKR's reqPnLSingle stream (TWS msg 95).
	// Distinct from UnrealizedPnL above, which is session-running.
	// nil means "no subscription yet" (daemon hasn't pre-warmed this
	// conId), "no frame received yet", "no entitlement", or "DBL_MAX
	// sentinel". Never zero-substituted. For options, the daily figure
	// can swing dramatically on small underlying moves; consumers
	// rendering a per-leg value should pair it with the option's
	// effective delta to interpret responsibly.
	DailyPnL     *float64 `json:"daily_pnl_ccy,omitempty"`
	DailyPnLBase *float64 `json:"daily_pnl_base,omitempty"`

	// Option-only fields (zero values when not applicable).
	Expiry string  `json:"expiry,omitempty"`
	Strike float64 `json:"strike,omitempty"`
	Right  string  `json:"right,omitempty"`

	Delta *float64 `json:"delta,omitempty"`
	Gamma *float64 `json:"gamma,omitempty"`
	Theta *float64 `json:"theta,omitempty"`
	Vega  *float64 `json:"vega,omitempty"`

	// Option-only contract-level fields populated from the per-leg
	// market-data subscription that captures Greeks (msg 21 tickType 13)
	// plus tick 1/2/9 for the option itself. Nil when the subscription
	// budget expired without delivering the tick — never zero-substituted.
	//
	// OptionBid / OptionAsk let callers detect a wide spread on illiquid
	// contracts where the mark is a midpoint that may not be tradable.
	// OptionPrevClose is the option contract's own prior settle (NOT the
	// underlying's PrevClose above); required for option-level daily P&L
	// without the underlying-vs-option confusion the agent-feedback flagged.
	// IV is the model-computation implied volatility for this leg.
	OptionBid         *float64 `json:"option_bid,omitempty"`
	OptionAsk         *float64 `json:"option_ask,omitempty"`
	OptionPrevClose   *float64 `json:"option_prev_close,omitempty"`
	IV                *float64 `json:"iv,omitempty"`
	MarkOutsideBidAsk bool     `json:"mark_outside_bid_ask,omitempty"`

	// Underlying is the model-computation underlying spot IBKR sent alongside
	// the Greeks (msg 21 tickType 13). The portfolio aggregator pairs delta
	// with this spot to compute dollar delta, so the dollar figure stays
	// consistent with the delta it was modelled against — pairing today's
	// delta with the underlying's prior close gives an apples-and-oranges
	// answer that lies by the size of any overnight gap. nil when the per-
	// leg Greeks tick didn't carry a spot (illiquid leg, model abstention)
	// — never zero-substituted.
	Underlying *float64 `json:"underlying,omitempty"`
}

PositionView is the wire shape of one position returned to adapters.

DayChange / DayChangePct describe how far the account valuation mark sits from RegularClose. Pointers so "no data" (no daily bar yet, options where we don't track contract-level prev close) is distinct from "exactly flat". The daemon caches close anchors per underlying so the first call pre-warms and subsequent ones are instant — no fabrication.

MarketValue is serialized as market_value_ccy: the broker's own market value for the position, in the contract currency named by the row's Currency field. It is NOT derived from Mark and Quantity. A bond quotes as a percentage of par against a face-value quantity, so the product overstates such a row by roughly 100×; the two agree only for equities and options, which is what made the old identity look like a definition. MarketValueBase / UnrealizedPnLBase / RealizedPnLBase / DailyPnLBase are populated when the daemon knows the account base currency and either the row is already in base currency or FXRate is available. nil = conversion unavailable, never zero-substituted.

FXRate is the gateway-reported BASE/CCY conversion. It stays nil on same-currency books because the conversion is implicitly 1.0.

Delta/Gamma/Theta/Vega populate on option positions when the daemon captured a valid model-computation tick within budget. nil = unavailable (illiquid leg, OOH model abstention, subscribe slot churn) — never zero- substituted.

type PositionsListParams

type PositionsListParams struct {
	Symbol string `json:"symbol,omitempty"`
	Type   string `json:"type,omitempty"` // stk | opt
}

PositionsListParams filters the positions response. Both fields are honoured by the daemon (`internal/daemon/handlers.go::handlePositionsList`). Symbol matches the underlying (or the synthetic option key); empty returns every position. Type narrows to stocks ("stk") or options ("opt"); empty returns both. Filters are applied before the FX / Greeks decoration, so a narrowed query is also faster.

type PositionsPortfolio

type PositionsPortfolio struct {
	EffectiveDelta          *float64             `json:"effective_delta,omitempty"`
	DollarDelta             *float64             `json:"dollar_delta_ccy,omitempty"`
	DollarDeltaCurrency     string               `json:"dollar_delta_ccy_currency,omitempty"`
	DollarDeltaBase         *float64             `json:"dollar_delta_base,omitempty"`
	DollarDeltaBaseCurrency string               `json:"dollar_delta_base_currency,omitempty"`
	DailyTheta              *float64             `json:"daily_theta_ccy,omitempty"`
	DailyThetaCurrency      string               `json:"daily_theta_ccy_currency,omitempty"`
	DailyThetaBase          *float64             `json:"daily_theta_base,omitempty"`
	DailyThetaBaseCurrency  string               `json:"daily_theta_base_currency,omitempty"`
	Gamma                   *float64             `json:"gamma,omitempty"`
	Vega                    *float64             `json:"vega,omitempty"`
	GreeksCoverage          int                  `json:"greeks_coverage"`
	GreeksTotal             int                  `json:"greeks_total"`
	BaseCurrency            string               `json:"base_currency,omitempty"`
	NetLiquidationBase      *float64             `json:"net_liquidation_base,omitempty"`
	ExposureBase            []UnderlyingExposure `json:"exposure_base,omitempty"`

	// ExposureUnmeasured names the held underlyings absent from ExposureBase:
	// no base-currency market value could be computed for the group, so it
	// carries no row at all rather than a zero one. A consumer that compares an
	// ExposureBase subtotal against a threshold must read a non-empty list as
	// proof the subtotal is partial — the sum understates, and understatement
	// is the quiet direction. Empty on a fully measured book.
	ExposureUnmeasured []string `json:"exposure_unmeasured,omitempty"`

	// FXSensitivityPerPct estimates the change in base-currency P&L for a 1%
	// move in the non-base contract currency, holding everything else
	// constant. Computed as Σ (non-base market value in base) × 0.01.
	// Useful as a quick answer to "how much of my book is FX-exposed?".
	FXSensitivityPerPct *float64 `json:"fx_sensitivity_per_pct,omitempty"`
	FXBaseCurrency      string   `json:"fx_base_currency,omitempty"`
}

PositionsPortfolio is the daemon-side aggregator across all open legs.

EffectiveDelta sums per-leg signed share-equivalent exposure:

  • stocks contribute their signed quantity (long 100 sh => +100)
  • options contribute delta × signed contract qty × multiplier

DollarDelta multiplies each leg's share-equivalent exposure by the leg's contract-currency spot and sums; result is reported in DollarDeltaCurrency. For a mixed-currency book this is the dominant contract currency (e.g. USD when every option references a USD underlying); callers that need a single base-currency rollup combine it with the AccountResult.CurrencyExposure FX rate.

DailyTheta is Σ (theta × signed contract qty × multiplier). IBKR already reports theta as daily decay, so the sum is the daily P&L from time decay assuming everything else holds. The value is in DailyThetaCurrency, computed with the same single-ccy-or-"MIX" convention as DollarDeltaCurrency: a single ISO code when every contributing option leg agrees, "MIX" when not. Renderers should surface "MIX" rather than picking a symbol — the sum is genuinely undefined in mixed-currency books.

GreeksCoverage is the count of option legs whose Greeks were captured over the total — useful for the renderer to flag partial coverage when the model tick didn't arrive for some legs.

type PositionsResult

type PositionsResult struct {
	// DataType reflects the per-position mark-price feed when the daemon
	// can summarise it; left empty (omitted) when positions arrive purely
	// from the portfolio update stream without per-symbol feed state.
	DataType           string                     `json:"data_type,omitempty"`
	AsOf               time.Time                  `json:"as_of"`
	Stocks             []PositionView             `json:"stocks"`
	Options            []PositionView             `json:"options"`
	ByUnderlying       []PositionGroup            `json:"by_underlying"`
	Portfolio          *PositionsPortfolio        `json:"portfolio,omitempty"`
	ProtectionCoverage *ProtectionCoverageSummary `json:"protection_coverage,omitempty"`
	AccountID          string                     `json:"account_id,omitempty"`
	// Authority is the account scope and portfolio-stream receipt contract.
	// It is additive so older stored/test payloads remain readable; current
	// daemon responses always populate it.
	Authority *AccountDataAuthority `json:"authority,omitempty"`
}

PositionsResult wraps the array so the daemon can attach metadata later. ByUnderlying groups stock + option legs per underlying — always populated so JSON consumers can rely on it. The CLI's `--by underlying` view renders from this; the default view keeps the flat Stocks/Options arrays.

Portfolio is populated when at least one option leg has captured Greeks and/or any non-base currency holding has a known FX rate. Aggregates are computed daemon-side so JSON consumers and the CLI render the same numbers. Always-non-nil pointer; fields inside are nil when their inputs were unavailable — see PositionsPortfolio doc for the contract.

type PositionsRiskResult

type PositionsRiskResult struct {
	DataType           string                     `json:"data_type,omitempty"`
	AsOf               time.Time                  `json:"as_of"`
	AccountID          string                     `json:"account_id,omitempty"`
	Portfolio          *PositionsPortfolio        `json:"portfolio,omitempty"`
	TopExposure        []UnderlyingExposure       `json:"top_exposure,omitempty"`
	OptionHealth       OptionHealthSummary        `json:"option_health"`
	ProtectionCoverage *ProtectionCoverageSummary `json:"protection_coverage,omitempty"`
	SPYHedgeOffsetPct  *float64                   `json:"spy_hedge_offset_pct,omitempty"`
	FlaggedOptionLegs  []OptionRiskLegSummary     `json:"flagged_option_legs,omitempty"`
	Authority          *AccountDataAuthority      `json:"authority,omitempty"`
}

PositionsRiskResult is a bounded portfolio-risk projection. TopRisks is sorted and capped by the requested topN.

func CompactPositionsRisk

func CompactPositionsRisk(p *PositionsResult, topN int) PositionsRiskResult

CompactPositionsRisk builds the bounded portfolio-risk projection. Nonpositive topN uses the package default.

type ProtectionCoverageCounts

type ProtectionCoverageCounts struct {
	Covered           int `json:"covered,omitempty"`
	Partial           int `json:"partial,omitempty"`
	Unprotected       int `json:"unprotected,omitempty"`
	OrphanedOrder     int `json:"orphaned_order,omitempty"`
	ReconcileRequired int `json:"reconcile_required,omitempty"`
	Unknown           int `json:"unknown,omitempty"`
	NotProtectable    int `json:"not_protectable,omitempty"`
}

ProtectionCoverageCounts summarizes the mutually exclusive coverage rows.

type ProtectionCoverageOrder

type ProtectionCoverageOrder struct {
	OrderRef            string    `json:"order_ref,omitempty"`
	Symbol              string    `json:"symbol,omitempty"`
	SecType             string    `json:"sec_type,omitempty"`
	Action              string    `json:"action,omitempty"`
	OrderType           string    `json:"order_type,omitempty"`
	TIF                 string    `json:"tif,omitempty"`
	Remaining           float64   `json:"remaining,omitempty"`
	Quantity            float64   `json:"quantity,omitempty"`
	StopPrice           *float64  `json:"stop_price,omitempty"`
	LimitPrice          *float64  `json:"limit_price,omitempty"`
	LifecycleStatus     string    `json:"lifecycle_status,omitempty"`
	ReconciliationState string    `json:"reconciliation_state,omitempty"`
	UpdatedAt           time.Time `json:"updated_at,omitzero"`
	LastMessage         string    `json:"last_message,omitempty"`
}

ProtectionCoverageOrder is a redacted protective-order observation. Its coverage and reconciliation flags are daemon-derived, not broker authority.

type ProtectionCoverageRow

type ProtectionCoverageRow struct {
	Underlying                      string                    `json:"underlying"`
	State                           string                    `json:"state"`
	PositionQuantity                float64                   `json:"position_quantity,omitempty"`
	ProtectedQuantity               float64                   `json:"protected_quantity,omitempty"`
	UnprotectedQuantity             float64                   `json:"unprotected_quantity,omitempty"`
	MarketValueBase                 *float64                  `json:"market_value_base,omitempty"`
	MarketValuePctNLV               *float64                  `json:"market_value_pct_nlv,omitempty"`
	UnprotectedNotionalBase         *float64                  `json:"unprotected_notional_base,omitempty"`
	UnprotectedNotionalBaseCurrency string                    `json:"unprotected_notional_base_currency,omitempty"`
	Orders                          []ProtectionCoverageOrder `json:"orders,omitempty"`
	WarningCodes                    []string                  `json:"warning_codes,omitempty"`
	Message                         string                    `json:"message,omitempty"`
}

ProtectionCoverageRow reports reconciled coverage for one held underlying. Pointer notionals are nil when base-currency conversion is unavailable.

type ProtectionCoverageSummary

type ProtectionCoverageSummary struct {
	AsOf                            time.Time                 `json:"as_of,omitzero"`
	Status                          string                    `json:"status,omitempty"`
	ByUnderlying                    []ProtectionCoverageRow   `json:"by_underlying,omitempty"`
	Counts                          ProtectionCoverageCounts  `json:"counts,omitzero"`
	UnprotectedNotionalBase         *float64                  `json:"unprotected_notional_base,omitempty"`
	UnprotectedNotionalBaseCurrency string                    `json:"unprotected_notional_base_currency,omitempty"`
	LargestUnprotected              []ProtectionCoverageRow   `json:"largest_unprotected,omitempty"`
	OrphanedOrders                  []ProtectionCoverageOrder `json:"orphaned_orders,omitempty"`
	ReconcileRequiredOrders         []ProtectionCoverageOrder `json:"reconcile_required_orders,omitempty"`
	WarningCodes                    []string                  `json:"warning_codes,omitempty"`
	Message                         string                    `json:"message,omitempty"`
}

ProtectionCoverageSummary is the read-only coverage ledger for stock/ETF protection. Quantities count only open close-protective orders that still reconcile with the current position; stale/orphaned orders are surfaced but never counted as protection.

type ProtectionPolicyStatus

type ProtectionPolicyStatus struct {
	Kind          string           `json:"kind,omitempty"`
	Status        string           `json:"status"`
	PolicyID      string           `json:"policy_id,omitempty"`
	PolicyVersion int              `json:"policy_version,omitempty"`
	Profile       string           `json:"profile,omitempty"`
	Fingerprint   Fingerprint      `json:"fingerprint,omitzero"`
	Source        string           `json:"source,omitempty"`
	Path          string           `json:"path,omitempty"`
	LoadedAt      time.Time        `json:"loaded_at,omitzero"`
	LastCheckedAt time.Time        `json:"last_checked_at,omitzero"`
	Message       string           `json:"message,omitempty"`
	Blockers      []TradingBlocker `json:"blockers,omitempty"`
}

ProtectionPolicyStatus reports the loaded policy identity and blockers.

type PurgeExecuteLeg

type PurgeExecuteLeg struct {
	LegID        string         `json:"leg_id"`
	Symbol       string         `json:"symbol"`
	SecType      string         `json:"sec_type"`
	Contract     ContractParams `json:"contract"`
	OriginalSide string         `json:"original_side"`
	PurgeAction  string         `json:"purge_action"`
	Quantity     float64        `json:"quantity"`
	Multiplier   int            `json:"multiplier,omitempty"`
}

PurgeExecuteLeg identifies one exact position leg selected for purge.

type PurgeExecuteOrder

type PurgeExecuteOrder struct {
	LegID           string             `json:"leg_id"`
	Symbol          string             `json:"symbol"`
	SecType         string             `json:"sec_type"`
	Contract        ContractParams     `json:"contract"`
	Action          string             `json:"action"`
	Quantity        int                `json:"quantity"`
	LimitPrice      float64            `json:"limit_price"`
	OrderRef        string             `json:"order_ref"`
	ReservedOrderID int                `json:"reserved_order_id,omitempty"`
	Status          string             `json:"status,omitempty"`
	LifecycleStatus string             `json:"lifecycle_status,omitempty"`
	SendState       string             `json:"send_state,omitempty"`
	Message         string             `json:"message,omitempty"`
	Quote           OrderQuoteSnapshot `json:"quote"`
}

PurgeExecuteOrder reports the sanitized order state for one submitted leg.

type PurgeExecuteParams

type PurgeExecuteParams struct {
	PurgeID       string            `json:"purge_id"`
	All           bool              `json:"all,omitempty"`
	Symbols       []string          `json:"symbols,omitempty"`
	Legs          []PurgeExecuteLeg `json:"legs,omitempty"`
	BypassPreview *bool             `json:"bypass_preview,omitempty"`
	WaitMs        int               `json:"wait_ms,omitempty"`
	Origin        string            `json:"origin,omitempty"`
}

PurgeExecuteParams selects an explicit purge workflow. It is a broker-write request and remains subject to daemon preview, origin, freeze, and limit gates.

type PurgeExecuteResult

type PurgeExecuteResult struct {
	Kind                 string                   `json:"kind"`
	PurgeID              string                   `json:"purge_id"`
	Status               string                   `json:"status"`
	Mode                 string                   `json:"mode,omitempty"`
	Account              string                   `json:"account,omitempty"`
	Endpoint             string                   `json:"endpoint,omitempty"`
	ClientID             int                      `json:"client_id,omitempty"`
	BypassPreview        bool                     `json:"bypass_preview"`
	SelectedLegs         int                      `json:"selected_legs"`
	SubmittedLegs        int                      `json:"submitted_legs"`
	SkippedLegs          int                      `json:"skipped_legs"`
	ErrorLegs            int                      `json:"error_legs"`
	Orders               []PurgeExecuteOrder      `json:"orders,omitempty"`
	Skipped              []PurgeExecuteSkippedLeg `json:"skipped,omitempty"`
	Warnings             []string                 `json:"warnings,omitempty"`
	Blockers             []TradingBlocker         `json:"blockers,omitempty"`
	Message              string                   `json:"message,omitempty"`
	MonitorCommand       string                   `json:"monitor_command,omitempty"`
	RestoreReviewCommand string                   `json:"restore_review_command,omitempty"`
	AsOf                 time.Time                `json:"as_of"`
}

PurgeExecuteResult reports per-leg submission, skips, blockers, and monitor guidance. Submitted legs are not necessarily filled.

type PurgeExecuteSkippedLeg

type PurgeExecuteSkippedLeg struct {
	LegID    string         `json:"leg_id"`
	Symbol   string         `json:"symbol"`
	SecType  string         `json:"sec_type"`
	Contract ContractParams `json:"contract"`
	Reason   string         `json:"reason"`
}

PurgeExecuteSkippedLeg records a selected leg that was not submitted and its stable reason.

type PurgeLedgerRow

type PurgeLedgerRow struct {
	LegID               string         `json:"leg_id"`
	PurgeID             string         `json:"purge_id,omitempty"`
	Symbol              string         `json:"symbol"`
	SecType             string         `json:"sec_type"`
	Contract            ContractParams `json:"contract"`
	Account             string         `json:"account,omitempty"`
	Mode                string         `json:"mode,omitempty"`
	Currency            string         `json:"currency,omitempty"`
	OriginalSide        string         `json:"original_side"`
	OriginalQuantity    float64        `json:"original_quantity"`
	PurgeAction         string         `json:"purge_action"`
	RestoreAction       string         `json:"restore_action"`
	Multiplier          int            `json:"multiplier"`
	PurgedQuantity      float64        `json:"purged_quantity"`
	RestoredQuantity    float64        `json:"restored_quantity"`
	RemainingQuantity   float64        `json:"remaining_quantity"`
	PurgeAvgPrice       float64        `json:"purge_avg_price,omitempty"`
	RestoreAvgPrice     float64        `json:"restore_avg_price,omitempty"`
	PurgeValue          float64        `json:"purge_value,omitempty"`
	RestoreValue        float64        `json:"restore_value,omitempty"`
	ShadowPnL           float64        `json:"shadow_pnl,omitempty"`
	Status              string         `json:"status"`
	LastPurgeOrderRef   string         `json:"last_purge_order_ref,omitempty"`
	LastRestoreOrderRef string         `json:"last_restore_order_ref,omitempty"`
	CreatedAt           time.Time      `json:"created_at,omitzero"`
	UpdatedAt           time.Time      `json:"updated_at,omitzero"`
	Warnings            []string       `json:"warnings,omitempty"`
}

PurgeLedgerRow is one durable leg record reduced from purge, restore, and observed fill events.

type PurgeLedgerTotals

type PurgeLedgerTotals struct {
	ActiveRows        int     `json:"active_rows"`
	RestoredRows      int     `json:"restored_rows"`
	PurgedQuantity    float64 `json:"purged_quantity"`
	RestoredQuantity  float64 `json:"restored_quantity"`
	RemainingQuantity float64 `json:"remaining_quantity"`
	PurgeValue        float64 `json:"purge_value"`
	RestoreValue      float64 `json:"restore_value"`
	ShadowPnL         float64 `json:"shadow_pnl"`
}

PurgeLedgerTotals summarizes durable purge and restore quantities and values.

type PurgeRestoreLeg

type PurgeRestoreLeg struct {
	LegID           string              `json:"leg_id"`
	Symbol          string              `json:"symbol"`
	SecType         string              `json:"sec_type"`
	Contract        ContractParams      `json:"contract"`
	Action          string              `json:"action"`
	Quantity        int                 `json:"quantity"`
	RemainingBefore float64             `json:"remaining_before"`
	LimitPrice      float64             `json:"limit_price,omitempty"`
	EstimatedValue  float64             `json:"estimated_value,omitempty"`
	ShadowPnL       float64             `json:"shadow_pnl,omitempty"`
	Quote           OrderQuoteSnapshot  `json:"quote,omitzero"`
	Position        OrderPositionImpact `json:"position,omitzero"`
	WhatIf          OrderWhatIfResult   `json:"what_if,omitzero"`
	Status          string              `json:"status"`
	Warnings        []string            `json:"warnings,omitempty"`
}

PurgeRestoreLeg reports the modeled preview and outcome for one restore leg. WhatIf remains broker evidence rather than a fill guarantee.

type PurgeRestoreParams

type PurgeRestoreParams struct {
	PurgeID   string   `json:"purge_id,omitempty"`
	All       bool     `json:"all,omitempty"`
	Symbols   []string `json:"symbols,omitempty"`
	Scale     float64  `json:"scale,omitempty"`
	WaitMs    int      `json:"wait_ms,omitempty"`
	TimeoutMs int      `json:"timeout_ms,omitempty"`
	Origin    string   `json:"origin,omitempty"`
}

PurgeRestoreParams selects a proportional restore request. It is a new broker-write request and remains subject to current daemon gates.

type PurgeRestoreResult

type PurgeRestoreResult struct {
	Kind           string                   `json:"kind"`
	PurgeID        string                   `json:"purge_id,omitempty"`
	Status         string                   `json:"status"`
	Mode           string                   `json:"mode,omitempty"`
	Account        string                   `json:"account,omitempty"`
	Endpoint       string                   `json:"endpoint,omitempty"`
	ClientID       int                      `json:"client_id,omitempty"`
	Scale          float64                  `json:"scale"`
	SelectedLegs   int                      `json:"selected_legs"`
	SubmittedLegs  int                      `json:"submitted_legs"`
	SkippedLegs    int                      `json:"skipped_legs"`
	ErrorLegs      int                      `json:"error_legs"`
	EstimatedValue float64                  `json:"estimated_value,omitempty"`
	ShadowPnL      float64                  `json:"shadow_pnl,omitempty"`
	Legs           []PurgeRestoreLeg        `json:"legs,omitempty"`
	Orders         []PurgeExecuteOrder      `json:"orders,omitempty"`
	Skipped        []PurgeExecuteSkippedLeg `json:"skipped,omitempty"`
	Warnings       []string                 `json:"warnings,omitempty"`
	Blockers       []TradingBlocker         `json:"blockers,omitempty"`
	Message        string                   `json:"message,omitempty"`
	LedgerRows     []PurgeLedgerRow         `json:"ledger_rows,omitempty"`
	AsOf           time.Time                `json:"as_of"`
}

PurgeRestoreResult reports modeled legs, submissions, skips, and durable ledger state. Submitted legs are not necessarily filled.

type PurgeRestoreSettings

type PurgeRestoreSettings struct {
	Enabled SettingsBool `json:"enabled"`
}

PurgeRestoreSettings controls purge/restore actions while leaving status readable.

type PurgeStatusParams

type PurgeStatusParams struct {
	PurgeID string `json:"purge_id,omitempty"`
	Account string `json:"account,omitempty"`
	Limit   int    `json:"limit,omitempty"`
}

PurgeStatusParams selects a workflow or account-scoped ledger window. Empty values use daemon defaults and never broaden broker-write authority.

type PurgeStatusResult

type PurgeStatusResult struct {
	Kind            string            `json:"kind"`
	PurgeID         string            `json:"purge_id,omitempty"`
	Status          string            `json:"status"`
	Account         string            `json:"account,omitempty"`
	Rows            []PurgeLedgerRow  `json:"rows,omitempty"`
	Totals          PurgeLedgerTotals `json:"totals"`
	TotalOrders     int               `json:"total_orders"`
	OpenOrders      int               `json:"open_orders"`
	FilledOrders    int               `json:"filled_orders"`
	CancelledOrders int               `json:"cancelled_orders"`
	AttentionOrders int               `json:"attention_orders"`
	Orders          []OrderView       `json:"orders,omitempty"`
	Message         string            `json:"message,omitempty"`
	AsOf            time.Time         `json:"as_of"`
}

PurgeStatusResult is the daemon's durable purge-ledger and observed-order view. It is not a broker statement.

type Quality

type Quality struct {
	AsOf           time.Time `json:"as_of"`
	FreshnessClass string    `json:"freshness_class"`
	Confidence     string    `json:"confidence"`
	// Source is a one-line human-readable provenance description, e.g.
	// "VIX tick", "SPY 252d max(High) fallback", "perfiliev-bs-sweep-v1".
	// Surfaced by --explain; renderers can ignore it for the compact
	// in-row annotation.
	Source string `json:"source,omitempty"`
}

Quality is the provenance + freshness envelope for one scalar regime field. Attached as a sibling pointer to each value pointer; nil Quality means "no provenance recorded" (legacy/migration only). The envelope is purely additive to the row-level Status/DataType — renderers prefer Quality when present.

FreshnessClass values:

  • "live" — gateway live tick observed at AsOf
  • "frozen" — gateway frozen/delayed tick (typically last regular-session close) at AsOf
  • "derived" — computed from historical bars (e.g. max(High) over 252 daily bars)
  • "modelled" — computed from a model with documented caveats (the gamma sweep's perfiliev-bs-sweep-v1)

Confidence values:

  • "firm" — direct gateway measurement
  • "estimate" — derived from historical bars
  • "proxy" — modelled with methodology disclosure (caller's Method/warning_details document the assumptions)

type Quote

type Quote struct {
	Symbol   string         `json:"symbol"`
	Contract ContractParams `json:"contract"`
	Bid      *float64       `json:"bid"`
	Ask      *float64       `json:"ask"`
	Last     *float64       `json:"last"`
	Mark     *float64       `json:"mark,omitempty"`
	// Price is the legacy selected price: QuotePrice when the gateway has a
	// current indication, otherwise RegularClose. PriceSource names the
	// selected input so consumers can avoid treating a close-only fallback
	// as a live last trade.
	Price               *float64  `json:"price,omitempty"`
	PriceSource         string    `json:"price_source,omitempty"`
	RegularClose        *float64  `json:"regular_close,omitempty"`
	RegularCloseAt      time.Time `json:"regular_close_at,omitzero"`
	PriorRegularClose   *float64  `json:"prior_regular_close,omitempty"`
	RegularChange       *float64  `json:"regular_change,omitempty"`
	RegularChangePct    *float64  `json:"regular_change_pct,omitempty"`
	QuotePrice          *float64  `json:"quote_price,omitempty"`
	QuotePriceSource    string    `json:"quote_price_source,omitempty"`
	QuotePriceAt        time.Time `json:"quote_price_at,omitzero"`
	QuotePriceAsOf      string    `json:"quote_price_as_of,omitempty"`
	QuoteChange         *float64  `json:"quote_change,omitempty"`
	QuoteChangePct      *float64  `json:"quote_change_pct,omitempty"`
	PrevClose           *float64  `json:"prev_close"`
	Change              *float64  `json:"change"`
	ChangePct           *float64  `json:"change_pct"`
	DayHigh             *float64  `json:"day_high,omitempty"`
	DayLow              *float64  `json:"day_low,omitempty"`
	Week52High          *float64  `json:"week_52_high,omitempty"`
	Week52Low           *float64  `json:"week_52_low,omitempty"`
	BidSize             *int      `json:"bid_size,omitempty"`
	AskSize             *int      `json:"ask_size,omitempty"`
	Volume              *int64    `json:"volume,omitempty"`
	AvgVolume           *int64    `json:"avg_volume,omitempty"`
	AvgVolume20D        *int64    `json:"avg_volume_20d,omitempty"`
	AvgDollarVolume20D  *float64  `json:"avg_dollar_volume_20d,omitempty"`
	LiquidityStatus     string    `json:"liquidity_status,omitempty"` // ok | partial | unavailable
	LiquiditySource     string    `json:"liquidity_source,omitempty"` // daily_bars
	LiquidityAsOf       time.Time `json:"liquidity_as_of,omitzero"`
	LiquiditySampleDays int       `json:"liquidity_sample_days,omitempty"`
	IV                  *float64  `json:"iv"`
	IVStatus            string    `json:"iv_status"`
	DataType            string    `json:"data_type"`
	FeedType            string    `json:"feed_type,omitempty"`
	SpreadPct           *float64  `json:"spread_pct,omitempty"`
	// QuoteQuality is a compact machine hint: "firm", "indicative",
	// "wide", "prev_close", "stale", or "missing". It summarizes the
	// selected price and spread/session context; WarningDetails carries
	// the explainable reasons.
	QuoteQuality string `json:"quote_quality,omitempty"`
	Indicative   bool   `json:"indicative,omitempty"`
	VolumePhase  string `json:"volume_phase,omitempty"`
	// PriceAt is the best timestamp for Price. For last trades this is
	// IBKR tick-string 45 when delivered; for prev_close fallbacks it is
	// the official prior regular-session close; otherwise it is the local
	// observation time. PriceAsOf is the preformatted human label renderers
	// can show directly ("At close: May 22 at 04:01:02 PM EDT").
	PriceAt        time.Time     `json:"price_at,omitzero"`
	PriceAsOf      string        `json:"price_as_of,omitempty"`
	Stale          bool          `json:"stale,omitempty"`
	StaleReason    string        `json:"stale_reason,omitempty"`
	WarningDetails []DataWarning `json:"warning_details,omitempty"`
	AsOf           time.Time     `json:"as_of"`
	// SessionContext explains whether the relevant market was open at the
	// quote time. Populated when the context is useful for interpreting a
	// stale/frozen/missing quote; omitted on ordinary live in-session rows.
	SessionContext *MarketSession `json:"session_context,omitempty"`
}

Quote is the daemon's snapshot result.

RegularClose is the latest completed regular-session close (daily bars when the market is closed; the gateway close tick during regular hours). QuotePrice is the current live/pre/post/overnight indication selected from last → mark → bid/ask midpoint → bid → ask. Price/PriceSource are retained as the legacy selected-price pair and mirror QuotePrice when an indicative quote exists, otherwise RegularClose. PrevClose is the comparison anchor for Price: usually RegularClose for an indicative/live quote, and PriorRegularClose for a historical-close-only row. No fabrication: missing price families stay nil.

Unit conventions:

  • ChangePct is in PERCENT units (0.70 means 0.70 %, not 70 %). The CLI renderer appends a trailing % without multiplying.
  • IV is a DECIMAL FRACTION (0.247 means 24.7 %). The CLI renderer multiplies by 100 before printing. Same convention across every IV-bearing field in this package (chain expiries, chain strikes, scan rows, position rows).

type QuoteSnapshotParams

type QuoteSnapshotParams struct {
	Contract         ContractParams `json:"contract"`
	TimeoutMs        int            `json:"timeout_ms,omitempty"`
	IncludeLiquidity bool           `json:"include_liquidity,omitempty"`
}

QuoteSnapshotParams is the input for MethodQuoteSnapshot.

type QuoteSubscribeParams

type QuoteSubscribeParams struct {
	Contract ContractParams `json:"contract"`
}

QuoteSubscribeParams is the input for MethodQuoteSubscribe.

type ReconAutomationStatus

type ReconAutomationStatus struct {
	Report     ReconFetchStatus      `json:"report"`
	Evaluation ReconEvaluationStatus `json:"evaluation"`
}

ReconAutomationStatus keeps acquisition and evaluation separate so a report outage is never presented as a policy/evaluation failure (or vice versa).

type ReconBacktestCrossing

type ReconBacktestCrossing struct {
	Tier                string    `json:"tier"` // warn | block
	ReplayedAt          time.Time `json:"replayed_at,omitzero"`
	ReplayedConsumedPct float64   `json:"replayed_consumed_pct"`
	RuntimeAt           time.Time `json:"runtime_at,omitzero"`
}

ReconBacktestCrossing compares the first replayed crossing of one capital tier with the runtime journal observation, when recorded.

type ReconBacktestFlow

type ReconBacktestFlow struct {
	LineID      string    `json:"line_id"`
	Type        string    `json:"type,omitempty"`
	Description string    `json:"description,omitempty"`
	ValueDate   time.Time `json:"value_date,omitzero"`
	AmountBase  *float64  `json:"amount_base,omitempty"`
	PreGenesis  bool      `json:"pre_genesis,omitempty"`
	// Status is "matched", ReconBaseline, or the recon exception category
	// the flow carries on the current report.
	Status    string `json:"status"`
	Dismissed bool   `json:"dismissed,omitempty"`
}

ReconBacktestFlow labels one statement flow for the operator's full-window flow-list review.

type ReconBacktestReplay

type ReconBacktestReplay struct {
	Days                    int                     `json:"days"`
	FirstDay                time.Time               `json:"first_day,omitzero"`
	LastDay                 time.Time               `json:"last_day,omitzero"`
	ReplayedPeakBase        float64                 `json:"replayed_peak_base"`
	ReplayedPeakAt          time.Time               `json:"replayed_peak_at,omitzero"`
	RuntimePeakBase         *float64                `json:"runtime_peak_base,omitempty"`
	RuntimePeakAt           time.Time               `json:"runtime_peak_at,omitzero"`
	PeakDivergencePct       *float64                `json:"peak_divergence_pct,omitempty"`
	Crossings               []ReconBacktestCrossing `json:"crossings,omitempty"`
	SameDayComparisons      int                     `json:"same_day_comparisons"`
	MaxSameDayDivergencePct *float64                `json:"max_same_day_divergence_pct,omitempty"`
	Notes                   []string                `json:"notes,omitempty"`
}

ReconBacktestReplay is the capital-ladder replay over broker statement EOD equity, with the comparable runtime observations disclosed alongside it.

type ReconBacktestResult

type ReconBacktestResult struct {
	AsOf               time.Time            `json:"as_of"`
	Status             string               `json:"status"`
	ReportID           string               `json:"report_id,omitempty"`
	StatementAsOf      time.Time            `json:"statement_as_of,omitzero"`
	CoverageFrom       time.Time            `json:"coverage_from,omitzero"`
	CoverageTo         time.Time            `json:"coverage_to,omitzero"`
	GenesisAt          time.Time            `json:"genesis_at,omitzero"`
	PolicyFingerprint  *Fingerprint         `json:"policy_fingerprint,omitempty"`
	Flows              []ReconBacktestFlow  `json:"flows,omitempty"`
	FlowCounts         map[string]int       `json:"flow_counts,omitempty"`
	ClassifiedCounts   map[string]int       `json:"classified_counts,omitempty"`
	UncategorizedCount int                  `json:"uncategorized_count"`
	EquityDays         int                  `json:"equity_days"`
	Replay             *ReconBacktestReplay `json:"replay,omitempty"`
	Message            string               `json:"message,omitempty"`
	InputHealth        []SourceHealth       `json:"input_health,omitempty"`
}

ReconBacktestResult is the full-window recon backtest payload. It is read-only measurement and changes no matching, sign-off, or enforcement.

type ReconCheckParams

type ReconCheckParams struct{}

ReconCheckParams is deliberately an exact empty object. The paired app cannot smuggle report, account, policy, or trading instructions into this read-only action.

func (ReconCheckParams) MarshalJSON

func (ReconCheckParams) MarshalJSON() ([]byte, error)

MarshalJSON emits the canonical empty-object request.

func (*ReconCheckParams) UnmarshalJSON

func (params *ReconCheckParams) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts only an exact empty object.

type ReconCheckResult

type ReconCheckResult struct {
	Outcome string                `json:"outcome"`
	Status  ReconAutomationStatus `json:"status"`
}

ReconCheckResult is the immediate receipt returned by recon.check. Status is a fresh redacted snapshot; completion is observed by polling status, never inferred from the receipt alone.

func (ReconCheckResult) MarshalJSON

func (result ReconCheckResult) MarshalJSON() ([]byte, error)

MarshalJSON validates the outcome and automation state before encoding.

func (*ReconCheckResult) UnmarshalJSON

func (result *ReconCheckResult) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts only the exact validated check receipt.

type ReconDismissParams

type ReconDismissParams struct {
	LineID string `json:"line_id"`
	Reason string `json:"reason"`
	Origin string `json:"origin,omitempty"`
}

ReconDismissParams records one human resolution.

type ReconEquityCheck

type ReconEquityCheck struct {
	StatementDate      time.Time `json:"statement_date,omitzero"`
	StatementTotalBase float64   `json:"statement_total_base"`
	RuntimeEquityBase  *float64  `json:"runtime_equity_base,omitempty"`
	RuntimeAsOf        time.Time `json:"runtime_as_of,omitzero"`
	DivergencePct      *float64  `json:"divergence_pct,omitempty"`
	SameDay            bool      `json:"same_day"`
}

ReconEquityCheck compares the statement equity series with the runtime capital state — a data-quality disclosure, not an exception. Divergence is computed only from a same-day pair; when SameDay is false, RuntimeEquityBase and RuntimeAsOf are the latest observation for context only and DivergencePct is absent.

type ReconEquityParams

type ReconEquityParams struct {
	Since string `json:"since,omitempty"`
	Until string `json:"until,omitempty"`
	// Limit caps returned days, newest first; default 200, max 1000.
	Limit int `json:"limit,omitempty"`
}

ReconEquityParams selects a window of equity days. Boundary grammar matches RegimeHistoryParams; the default lookback is 90 days because the series is daily-granular.

type ReconEquityResult

type ReconEquityResult struct {
	AsOf            time.Time           `json:"as_of"`
	Since           time.Time           `json:"since"`
	Until           time.Time           `json:"until"`
	Days            []EquityDayEntry    `json:"days"`
	Count           int                 `json:"count"`
	TotalCount      int                 `json:"total_count"`
	Limit           int                 `json:"limit"`
	Truncated       bool                `json:"truncated"`
	Events          []CapitalEventEntry `json:"events"`
	EventsTruncated bool                `json:"events_truncated"`
	Index           HistoryIndexHealth  `json:"index"`
	Statements      HistoryIndexHealth  `json:"statements"`
}

ReconEquityResult is the recon.equity envelope: the equity-day window newest first, capital events over the same window (hard-capped, newest first), and two legacy-shaped health blocks retained for wire compatibility.

type ReconEvaluationStatus

type ReconEvaluationStatus struct {
	State  string `json:"state"`
	Reason string `json:"reason,omitempty"`
}

ReconEvaluationStatus reports what happened after the broker report was acquired. It intentionally does not expose report ids, amounts, or policy thresholds.

type ReconException

type ReconException struct {
	LineID      string    `json:"line_id"`
	Category    string    `json:"category"`
	Type        string    `json:"type,omitempty"`
	Description string    `json:"description,omitempty"`
	ValueDate   time.Time `json:"value_date,omitzero"`
	AmountBase  *float64  `json:"amount_base,omitempty"`
	// EventAt/EventAmountBase reference the declared event side of a
	// mismatch or ledger_only exception.
	EventAt         time.Time `json:"event_at,omitzero"`
	EventAmountBase *float64  `json:"event_amount_base,omitempty"`
	// PreGenesis marks a flow value-dated before the runtime capital
	// state's genesis. Such usable statement flows are returned in
	// ReconResult.Baseline when the runtime state is seeded.
	PreGenesis    bool   `json:"pre_genesis,omitempty"`
	Note          string `json:"note,omitempty"`
	Dismissed     bool   `json:"dismissed,omitempty"`
	DismissReason string `json:"dismiss_reason,omitempty"`
}

ReconException is the shared row shape for an exception or disclosed flow. Amounts are base-currency and stay on this local surface.

type ReconFetchStatus

type ReconFetchStatus struct {
	Configured         bool      `json:"configured"`
	State              string    `json:"state"`
	Reason             string    `json:"reason,omitempty"`
	ExpectedCoverageTo time.Time `json:"expected_coverage_to,omitzero"`
	CoverageTo         time.Time `json:"coverage_to,omitzero"`
	LastSuccess        time.Time `json:"last_success,omitzero"`
	LastAttempt        time.Time `json:"last_attempt,omitzero"`
	NextAttempt        time.Time `json:"next_attempt,omitzero"`
	RetryAutomatic     bool      `json:"retry_automatic"`
	CanCheckNow        bool      `json:"can_check_now"`
	Busy               bool      `json:"busy"`
	// LastError is retained for CLI compatibility, but is now derived only
	// from Reason. It never contains broker prose, paths, URLs, or parser
	// details and is not forwarded by the paired-app DTO.
	LastError string `json:"last_error,omitempty"`
}

ReconFetchStatus reports statement-source health. It never carries the token or any request detail.

type ReconResult

type ReconResult struct {
	AsOf   time.Time `json:"as_of"`
	Status string    `json:"status"`
	// ReportID pins the exact exception and baseline sets; the reconcile
	// verb must reference it and refuses when unresolved exceptions remain.
	ReportID string `json:"report_id,omitempty"`
	// StatementAsOf is when the newest ingested statement was generated
	// by IBKR — the freshness the max_report_age_days policy key bounds.
	StatementAsOf          time.Time             `json:"statement_as_of,omitzero"`
	CoverageFrom           time.Time             `json:"coverage_from,omitzero"`
	CoverageTo             time.Time             `json:"coverage_to,omitzero"`
	GenesisAt              time.Time             `json:"genesis_at,omitzero"`
	Counts                 map[string]int        `json:"counts,omitempty"`
	Exceptions             []ReconException      `json:"exceptions,omitempty"`
	Baseline               []ReconException      `json:"baseline,omitempty"`
	Confirmed              []ReconException      `json:"confirmed,omitempty"`
	Unresolved             int                   `json:"unresolved"`
	StatementCumFlowsBase  *float64              `json:"statement_cum_flows_base,omitempty"`
	LastAutoExtendReportID string                `json:"last_auto_extend_report_id,omitempty"`
	LastAutoExtendedAt     time.Time             `json:"last_auto_extended_at,omitzero"`
	Equity                 *ReconEquityCheck     `json:"equity,omitempty"`
	Fetch                  ReconFetchStatus      `json:"fetch"`
	Automation             ReconAutomationStatus `json:"automation"`
	Message                string                `json:"message,omitempty"`
	InputHealth            []SourceHealth        `json:"input_health,omitempty"`
}

ReconResult is the recon.snapshot payload.

type ReconSnapshotParams

type ReconSnapshotParams struct {
	// Refresh kicks one background statement fetch (single-flight); the
	// returned report is still built from already-retained files.
	Refresh bool `json:"refresh,omitempty"`
}

ReconSnapshotParams tunes one snapshot call.

type ReconStatusParams

type ReconStatusParams struct{}

ReconStatusParams is an exact empty object because status scope is daemon-owned and callers cannot request private report detail.

func (ReconStatusParams) MarshalJSON

func (ReconStatusParams) MarshalJSON() ([]byte, error)

MarshalJSON emits the canonical empty-object request.

func (*ReconStatusParams) UnmarshalJSON

func (params *ReconStatusParams) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts only an exact empty object.

type ReconStatusResult

type ReconStatusResult struct {
	Status ReconAutomationStatus `json:"status"`
}

ReconStatusResult wraps the redacted automation status returned by MethodReconStatus.

func (ReconStatusResult) MarshalJSON

func (result ReconStatusResult) MarshalJSON() ([]byte, error)

MarshalJSON validates automation-state coherence before encoding.

func (*ReconStatusResult) UnmarshalJSON

func (result *ReconStatusResult) UnmarshalJSON(data []byte) error

UnmarshalJSON accepts only the exact validated status wrapper.

type RegimeAsOfSummary

type RegimeAsOfSummary struct {
	Label      string    `json:"label"`
	Time       time.Time `json:"time,omitzero"`
	Date       string    `json:"date,omitempty"`
	Freshness  string    `json:"freshness,omitempty"`
	Source     string    `json:"source,omitempty"`
	AgeSeconds int64     `json:"age_seconds,omitempty"`
}

RegimeAsOfSummary is the row-level freshness badge rendered in the CLI and exposed in JSON/MCP. Label is the user-facing compact form ("live", "15m delayed", "close D-1", "cached 11:42", "2d old", "unavailable"). Time is present when a real timestamp exists; Date is present for official daily files whose observation date is more meaningful than midnight UTC.

type RegimeAuthorityFailureCode

type RegimeAuthorityFailureCode string

RegimeAuthorityFailureCode is a stable, redacted classification of why the authority has no newer complete snapshot. Raw source, broker, path, or persistence error text does not belong on this contract.

const (
	RegimeAuthorityFailureNone                  RegimeAuthorityFailureCode = ""
	RegimeAuthorityFailureNoLastGood            RegimeAuthorityFailureCode = "no_last_good"
	RegimeAuthorityFailureRefreshTimeout        RegimeAuthorityFailureCode = "refresh_timeout"
	RegimeAuthorityFailureRefreshIncomplete     RegimeAuthorityFailureCode = "refresh_incomplete"
	RegimeAuthorityFailureRefreshFailed         RegimeAuthorityFailureCode = "refresh_failed"
	RegimeAuthorityFailurePublishFailed         RegimeAuthorityFailureCode = "publish_failed"
	RegimeAuthorityFailureInvalidPersistedState RegimeAuthorityFailureCode = "invalid_persisted_state"
	// RegimeAuthorityFailureClockInvalid means the authority's last successful
	// commit is ahead of the daemon's current wall clock. The intact snapshot is
	// retained as stale context, but refresh and publication stay fail-closed
	// until the clock catches up.
	RegimeAuthorityFailureClockInvalid RegimeAuthorityFailureCode = "clock_invalid"
)

Regime authority failure codes distinguish absence, refresh failure, publish failure, invalid persistence, and invalid wall-clock evidence.

type RegimeAuthorityHealth

type RegimeAuthorityHealth struct {
	Status                RegimeAuthorityStatus      `json:"status"`
	Refreshing            bool                       `json:"refreshing"`
	LastSuccessAt         *time.Time                 `json:"last_success_at,omitempty"`
	LastSuccessAgeSeconds *int64                     `json:"last_success_age_seconds,omitempty"`
	FailureCode           RegimeAuthorityFailureCode `json:"failure_code,omitempty"`
}

RegimeAuthorityHealth is the source-neutral projection of the daemon's regime snapshot authority. LastSuccessAgeSeconds is a pointer because zero is meaningful immediately after a successful publish, while nil means no last-good snapshot has ever been accepted.

Refreshing reports an authority-owned refresh. It is not tied to the lifetime of the request that observed it. FailureCode classifies the latest failed attempt or the reason no last-good snapshot exists; it does not invalidate an existing last-good snapshot.

func (RegimeAuthorityHealth) MarshalJSON

func (health RegimeAuthorityHealth) MarshalJSON() ([]byte, error)

MarshalJSON validates authority-state coherence before encoding.

func (*RegimeAuthorityHealth) UnmarshalJSON

func (health *RegimeAuthorityHealth) UnmarshalJSON(data []byte) error

UnmarshalJSON rejects unknown, missing, null, trailing, or incoherent data.

type RegimeAuthorityStatus

type RegimeAuthorityStatus string

RegimeAuthorityStatus classifies the availability of the daemon-owned last-good regime snapshot. It is intentionally independent of any one indicator or upstream source.

const (
	// RegimeAuthorityUnavailable means no complete last-good snapshot exists.
	// A regime.snapshot request in this state fails with CodeRegimeUnavailable;
	// the value is retained for typed diagnostics and cache-state tests.
	RegimeAuthorityUnavailable RegimeAuthorityStatus = "unavailable"
	// RegimeAuthorityFresh means the response is the current last-good snapshot
	// and remains within the daemon's configured freshness window.
	RegimeAuthorityFresh RegimeAuthorityStatus = "fresh"
	// RegimeAuthorityStale means the daemon served an intact last-good snapshot
	// outside its freshness window. It must never mean a partial refresh.
	RegimeAuthorityStale RegimeAuthorityStatus = "stale"
)

Regime authority failure codes identify why a complete last-good snapshot is unavailable or why a refresh could not be published.

type RegimeBreadth

type RegimeBreadth struct {
	RegimeIndicatorMeta
	Status        string           `json:"status"`
	Envelope      BreadthSPXResult `json:"envelope"`
	Notes         string           `json:"notes,omitempty"`
	FieldsMissing []string         `json:"fields_missing,omitempty"`
	// PctAbove50DMA / PctAbove200DMA / NewHighsToday / NewLowsToday /
	// NetNewHighsPct are surfaced directly on the regime row so a
	// consumer doesn't have to dig into Envelope for the four-number
	// breadth view that informs the band. Echoed from Envelope; same
	// values, same units.
	PctAbove50DMA  float64 `json:"pct_above_50dma,omitempty"`
	PctAbove200DMA float64 `json:"pct_above_200dma,omitempty"`
	NewHighsToday  int     `json:"new_highs_today,omitempty"`
	NewLowsToday   int     `json:"new_lows_today,omitempty"`
	NetNewHighsPct float64 `json:"net_new_highs_pct,omitempty"`
	// Per-scalar provenance for the breadth percentage. firm-live or
	// firm-frozen when ranked, depending on the envelope's DataType;
	// nil during cold start or when the engine refused to persist
	// because constituent coverage fell below the safety threshold.
	ValueQuality *Quality `json:"value_quality,omitempty"`
	// Streak counts consecutive sessions in the current band. See
	// RegimeVIXTerm.Streak for the semantics.
	Streak *StreakInfo `json:"streak,omitempty"`
}

RegimeBreadth is Indicator 5: the existing breadth.spx envelope embedded inline. The daemon's local 50-DMA engine computes S5FI from constituent daily closes (see BreadthSPXResult.Method). On the first call against a fresh daemon the cold-start fan-out runs (~60 min, IBKR-paced), so this row typically surfaces Status="computing" with a notes pointer; subsequent calls return Status="ok" from the persisted cache.

type RegimeClusterBands

type RegimeClusterBands struct {
	Raw       []string
	Confirmed []string
	Eligible  []bool
}

RegimeClusterBands is the shared cluster combination: Raw worst-of row bands per cluster, Confirmed after the isolated-red downgrades, and Eligible flagging clusters whose red evidence passed the confirmation gates. Eligible[i] is only meaningful where Raw[i] == "red".

func BuildRegimeClusterBands

func BuildRegimeClusterBands(r *RegimeSnapshotResult) RegimeClusterBands

BuildRegimeClusterBands combines served row bands into the six cluster bands. Row banding (classification + hysteresis) happens daemon-side once; every consumer of this function reads the served result. Independence rescue counts ELIGIBLE reds only — a marginal or stale red can no longer rescue another cluster from its isolated-red downgrade.

func (RegimeClusterBands) EligibleRedCount

func (b RegimeClusterBands) EligibleRedCount() int

EligibleRedCount counts clusters that survive downgrades as red AND carry eligible evidence — the only reds that may confirm stress.

func (RegimeClusterBands) ProvisionalRedCount

func (b RegimeClusterBands) ProvisionalRedCount() int

ProvisionalRedCount counts raw reds that may NOT confirm: either the row evidence failed the eligibility gates or the cluster was downgraded.

type RegimeComposite

type RegimeComposite struct {
	Verdict              string `json:"verdict"`
	GreenCount           int    `json:"green_count"`
	YellowCount          int    `json:"yellow_count"`
	RedCount             int    `json:"red_count"`
	RankedCount          int    `json:"ranked_count"`
	UnrankedCount        int    `json:"unranked_count"`
	ClusterGreenCount    int    `json:"cluster_green_count"`
	ClusterYellowCount   int    `json:"cluster_yellow_count"`
	ClusterRedCount      int    `json:"cluster_red_count"`
	ClusterRankedCount   int    `json:"cluster_ranked_count"`
	ClusterUnrankedCount int    `json:"cluster_unranked_count"`
	// ClusterEligibleRedCount counts red clusters whose evidence passed the
	// confirmation-eligibility gates (depth + persistence + freshness) and
	// survived the isolated-red downgrades. Only these reds may confirm
	// stress. ClusterProvisionalRedCount counts the remaining raw reds —
	// visible, early-warning evidence, never confirmation.
	ClusterEligibleRedCount    int `json:"cluster_eligible_red_count"`
	ClusterProvisionalRedCount int `json:"cluster_provisional_red_count,omitempty"`
}

RegimeComposite is the daemon-side rollup of the regime rows. Verdict mirrors the CLI's text rendering verbatim ("Normal regime", "Stress signal present", etc.) so consumers can show the same non-advisory headline without re-implementing the band logic. The raw row counts are exposed alongside cluster counts so related signals (e.g. VIX term structure + VVIX, HYG proxy + cash credit spreads) do not double-count as independent macro confirmations.

RankedCount + UnrankedCount sum to the indicator count; cluster counts sum to the cluster count. Verdict is based on clusters, not raw rows.

type RegimeCreditSpreads

type RegimeCreditSpreads struct {
	RegimeIndicatorMeta
	Status        string      `json:"status"`
	HYOAS         *float64    `json:"hy_oas"`
	IGOAS         *float64    `json:"ig_oas"`
	HYIGSpread    *float64    `json:"hy_ig_spread,omitempty"`
	HY20DChange   *float64    `json:"hy_oas_20d_change,omitempty"` // percentage points
	AsOfDate      string      `json:"as_of_date,omitempty"`
	Source        string      `json:"source,omitempty"`
	Notes         string      `json:"notes,omitempty"`
	ErrorMessage  string      `json:"error_message,omitempty"`
	FieldsMissing []string    `json:"fields_missing,omitempty"`
	HYOASQuality  *Quality    `json:"hy_oas_quality,omitempty"`
	IGOASQuality  *Quality    `json:"ig_oas_quality,omitempty"`
	SpreadQuality *Quality    `json:"spread_quality,omitempty"`
	Streak        *StreakInfo `json:"streak,omitempty"`
}

RegimeCreditSpreads is the official cash-credit companion to the HYG ETF proxy. Values are ICE BofA option-adjusted spread series retrieved via FRED/St. Louis Fed. Units are percentage points; e.g. 4.25 means 425 bp.

type RegimeEligibility

type RegimeEligibility struct {
	Eligible bool     `json:"eligible"`
	Latched  bool     `json:"latched,omitempty"`
	Reasons  []string `json:"reasons,omitempty"`
}

RegimeEligibility is the confirmation-eligibility verdict for a red row. Eligible reds may confirm stress (count toward confirmed_stress/panic, rescue other clusters, appear in confirmed_by); provisional reds stay visible and drive early_warning only. Latched reports that eligibility is held by the streak-lifetime latch even though the measurement wobbled back inside the minimum depth. Reasons name the failed gates when not eligible: "depth_below_min", "streak_N_of_M", "data_not_due", "data_overdue".

func EvaluateRegimeEligibility

func EvaluateRegimeEligibility(in RegimeEligibilityInput) *RegimeEligibility

EvaluateRegimeEligibility applies the depth/persistence/freshness gates to one red row. Returns nil for non-red bands — eligibility is a property of red evidence only. The latch holds eligibility for the life of the red streak once earned, but never overrides freshness: overdue data drops eligibility mid-streak.

type RegimeEligibilityInput

type RegimeEligibilityInput struct {
	Indicator      string
	Band           string
	Depth          *float64
	StreakSessions int
	Fresh          bool
	FreshnessClass string
	Latched        bool
}

RegimeEligibilityInput is one red row's gate evidence. Depth is in the indicator's gate units; nil means the indicator has no separate depth metric (the band threshold is the depth gate). StreakSessions <= 0 is treated as 1 (fresh install / deleted store).

type RegimeFreshness

type RegimeFreshness struct {
	Class         string `json:"class"`
	MaxAgeSeconds int64  `json:"max_age_seconds,omitempty"`
}

RegimeFreshness is the cadence-relative freshness verdict plus the served staleness policy for one regime row. No wall-clock age field by design — ages tick every poll and would churn fingerprints and SSE hashes; clients derive age from the row's as_of.

type RegimeFundingStress

type RegimeFundingStress struct {
	RegimeIndicatorMeta
	Status         string      `json:"status"`
	CP3M           *float64    `json:"cp_3m_rate"`
	TBill3M        *float64    `json:"tbill_3m_rate"`
	SpreadBps      *float64    `json:"spread_bps"`
	AsOfDate       string      `json:"as_of_date,omitempty"`
	Source         string      `json:"source,omitempty"`
	Notes          string      `json:"notes,omitempty"`
	ErrorMessage   string      `json:"error_message,omitempty"`
	FieldsMissing  []string    `json:"fields_missing,omitempty"`
	CP3MQuality    *Quality    `json:"cp_3m_quality,omitempty"`
	TBill3MQuality *Quality    `json:"tbill_3m_quality,omitempty"`
	SpreadQuality  *Quality    `json:"spread_quality,omitempty"`
	Streak         *StreakInfo `json:"streak,omitempty"`
}

RegimeFundingStress is the OFR-style U.S. funding spread row: 90-day AA financial commercial paper rate minus 3-month Treasury bill rate, both from official Federal Reserve/FRED series. Units are basis points.

type RegimeGammaZero

type RegimeGammaZero struct {
	RegimeIndicatorMeta
	Status        string             `json:"status"`
	Envelope      GammaZeroSPXResult `json:"envelope"`
	Notes         string             `json:"notes,omitempty"`
	FieldsMissing []string           `json:"fields_missing,omitempty"`
	// Per-scalar provenance for the two values the renderer prints:
	// ZeroGamma is proxy-modelled (carries the perfiliev-bs-sweep
	// methodology); GammaTotalAbs is estimate-derived (sign-agnostic
	// notional summed over observed OI+IV).
	ZeroGammaQuality     *Quality `json:"zero_gamma_quality,omitempty"`
	GammaTotalAbsQuality *Quality `json:"gamma_total_abs_quality,omitempty"`
	// HorizonAgreement names how a single-underlying envelope's three
	// horizon-bucketed γ-zero readings (0DTE, 1-7, term) relate. Empty
	// for combined SPY+SPX results, where horizon buckets live under
	// per_index.SPY / per_index.SPX. One of:
	//
	//   - "all_long"             every usable bucket is long-γ
	//   - "all_short"            every usable bucket is short-γ
	//   - "all_transition"       every usable bucket is within ±2% of
	//                            its γ-zero
	//   - "diverge:0dte_vs_term"  0DTE and term buckets disagree
	//                            (highest-information case — short-fuse
	//                            flow disagrees with monthly positioning)
	//   - "diverge:partial"       other mixed cases (1-7 alone disagrees,
	//                            only two usable buckets disagree, etc.)
	//   - "0dte_only" / "1to7_only" / "term_only" — only one bucket is
	//                            usable
	//   - ""                     no bucket has a usable signal
	//
	// The renderer annotates the row whenever the value starts with
	// "diverge:" or ends in "_only" — those are the cases where the
	// combined headline doesn't tell the full story.
	HorizonAgreement string `json:"horizon_agreement,omitempty"`
	// Streak counts consecutive sessions in the current band. See
	// RegimeVIXTerm.Streak for the semantics.
	Streak *StreakInfo `json:"streak,omitempty"`
}

RegimeGammaZero is the existing gamma.zero_spx envelope embedded inline. Auto-kicked by regime.snapshot on first call of an NY trading day; subsequent calls return the cached result. Method token + warning_details carry methodology disclosures.

type RegimeGate

type RegimeGate struct {
	MinSessions int
	MinDepth    float64
	FastDepth   float64
}

RegimeGate is one indicator's confirmation-eligibility policy. Depth units are per-indicator (documented at each table entry). A zero MinDepth means the red band threshold itself is the depth gate (already-deep bands). FastDepth, when non-zero, makes a red eligible on day one regardless of streak — the crash-day escape hatch that keeps persistence gates safe.

These values are heuristic noise floors, pending_backtest like the band thresholds themselves. They stay code constants (not settings) until the decisions journal provides promotion evidence — user-tunable gates would fork the journal's comparability.

func RegimeGateFor

func RegimeGateFor(indicator string) (RegimeGate, bool)

RegimeGateFor exposes the eligibility gate table for renderers (--explain) and the spec-doc generator. The bool reports whether the indicator is known.

type RegimeHYGSPYDivergence

type RegimeHYGSPYDivergence struct {
	RegimeIndicatorMeta
	Status     string   `json:"status"`
	HYGPrice   *float64 `json:"hyg_price"`
	HYG50DMA   *float64 `json:"hyg_50dma"` // 50-day SMA of HYG daily close
	SPYPrice   *float64 `json:"spy_price"`
	SPY52WHigh *float64 `json:"spy_52w_high"`
	// SPY previous regular-session close plus the day's dollar and
	// percent change. Trading dates: tick 9, emitted automatically
	// alongside the price triple. Official non-trading dates: pinned to
	// the official daily closes of the last two completed sessions,
	// because the gateway's tick-9 anchor and last print can each reset
	// independently while the market is closed. All three nil when no
	// anchor was resolvable.
	SPYPrevClose *float64 `json:"spy_prev_close,omitempty"`
	SPYChange    *float64 `json:"spy_change,omitempty"`     // last − prev_close (dollars)
	SPYChangePct *float64 `json:"spy_change_pct,omitempty"` // (last − prev_close) / prev_close × 100
	// SPYChangeBasis is the day-change provenance on closed dates. Empty on
	// trading dates (live print vs tick-9 close).
	SPYChangeBasis string   `json:"spy_change_basis,omitempty"`
	HYGDataType    string   `json:"hyg_data_type,omitempty"`
	Notes          string   `json:"notes,omitempty"`
	ErrorMessage   string   `json:"error_message,omitempty"`
	FieldsMissing  []string `json:"fields_missing,omitempty"`
	// Per-scalar provenance. SPY52WHigh has two paths (live tick 165 vs
	// history fallback); the Quality field is what the renderer reads to
	// distinguish firm-tick from derived-fallback.
	HYGQuality        *Quality `json:"hyg_quality,omitempty"`
	HYG50DMAQuality   *Quality `json:"hyg_50dma_quality,omitempty"`
	SPYQuality        *Quality `json:"spy_quality,omitempty"`
	SPY52WHighQuality *Quality `json:"spy_52w_high_quality,omitempty"`
	// Streak counts consecutive sessions in the current band. See
	// RegimeVIXTerm.Streak for the semantics.
	Streak *StreakInfo `json:"streak,omitempty"`
}

RegimeHYGSPYDivergence is Indicator 2: HYG vs SPY context. The daemon surfaces raw measurements; the consumer compares HYG's current to its 50-day SMA and SPY's current to its 52-week high.

FieldsMissing carries optional sub-fields ("spy_52w_high", "hyg_50dma") that didn't land — both are best-effort and don't downgrade the row's primary status.

type RegimeHistoryEntry

type RegimeHistoryEntry struct {
	At                 time.Time `json:"at"`
	SessionKey         string    `json:"session_key,omitempty"`
	TapeSession        string    `json:"tape_session,omitempty"`
	Stage              string    `json:"stage"`
	Severity           string    `json:"severity,omitempty"`
	Readiness          string    `json:"readiness,omitempty"`
	Confidence         string    `json:"confidence,omitempty"`
	Verdict            string    `json:"verdict,omitempty"`
	ClusterRed         int       `json:"cluster_red_count"`
	ClusterYellow      int       `json:"cluster_yellow_count"`
	ClusterEligibleRed int       `json:"cluster_eligible_red_count"`
	Fingerprint        string    `json:"fingerprint,omitempty"`
}

RegimeHistoryEntry is one persisted regime decision. Free-text fields (Verdict) are event data for display, never parsed into authority.

type RegimeHistoryParams

type RegimeHistoryParams struct {
	// Since is the inclusive lower boundary: RFC3339, or YYYY-MM-DD
	// meaning the start of that UTC day. Empty = 7 days before Until.
	Since string `json:"since,omitempty"`
	// Until is the upper boundary: RFC3339 (exclusive), or YYYY-MM-DD
	// meaning that whole UTC day stays included. Empty = now.
	Until string `json:"until,omitempty"`
	// Stage filters on the exact lifecycle stage word (for example
	// early_warning). Empty matches all stages.
	Stage string `json:"stage,omitempty"`
	// Limit caps returned rows, newest first; default 50, max 500.
	Limit int `json:"limit,omitempty"`
}

RegimeHistoryParams selects a window of persisted regime decisions. Boundary grammar mirrors orders.history: RFC3339 timestamps or YYYY-MM-DD UTC days.

type RegimeHistoryResult

type RegimeHistoryResult struct {
	AsOf       time.Time            `json:"as_of"`
	Since      time.Time            `json:"since"`
	Until      time.Time            `json:"until"`
	Entries    []RegimeHistoryEntry `json:"entries"`
	Count      int                  `json:"count"`
	TotalCount int                  `json:"total_count"`
	Limit      int                  `json:"limit"`
	Truncated  bool                 `json:"truncated"`
	Index      HistoryIndexHealth   `json:"index"`
}

RegimeHistoryResult is the regime.history envelope: the filtered window, newest first, with total-vs-returned counts and a legacy-shaped compatibility health block.

type RegimeIndicatorMeta

type RegimeIndicatorMeta struct {
	Band       string             `json:"band,omitempty"`
	BandReason string             `json:"band_reason,omitempty"`
	Thresholds *RegimeThresholds  `json:"thresholds,omitempty"`
	AsOf       *RegimeAsOfSummary `json:"as_of,omitempty"`
	// Freshness is the cadence-relative freshness verdict for the row's
	// banding input: "fresh" when no newer observation should exist under
	// the indicator's native cadence, "not_due" when the source's native
	// publication window has not opened yet, and "overdue" otherwise.
	// Neither not-due nor overdue evidence can make a red confirmation-
	// eligible. MaxAgeSeconds documents the
	// served staleness policy so renderers never hardcode a twin.
	Freshness *RegimeFreshness `json:"freshness,omitempty"`
	// Eligibility says whether a red band may CONFIRM stress (depth +
	// persistence + freshness gates) or is provisional. A provisional red is
	// visible and can warn only while the required input set is usable; broken
	// or overdue inputs produce lifecycle=data_quality. Nil on non-red rows.
	Eligibility *RegimeEligibility `json:"eligibility,omitempty"`
}

RegimeIndicatorMeta is the compact interpretation/provenance layer shared by every regime row. The fields are embedded into each indicator's JSON so agents do not have to derive bands, thresholds, or freshness from prose.

type RegimeJournalSettings

type RegimeJournalSettings struct {
	Enabled SettingsBool `json:"enabled"`
}

RegimeJournalSettings retains its public name while controlling forward collection of typed regime-decision events in daemon.db.

type RegimeMonitorIndicator

type RegimeMonitorIndicator struct {
	Name   string `json:"name"`
	Status string `json:"status"`
	// Cluster is the indicator's wire cluster name (RegimeClusterNames), so a
	// monitor consumer can group readings without re-deriving the mapping.
	Cluster string             `json:"cluster,omitempty"`
	Band    string             `json:"band,omitempty"`
	AsOf    *RegimeAsOfSummary `json:"as_of,omitempty"`
	Reading string             `json:"reading,omitempty"`
	// Thresholds carries the served worded bands and their compact trip so a
	// monitor face can print the trigger beside the reading. Passed through
	// verbatim from the row's own metadata; this projection authors none of
	// it.
	Thresholds *RegimeThresholds `json:"thresholds,omitempty"`
	// Eligibility and FreshnessClass mirror the detail view's
	// confirmation-eligibility verdict so monitor consumers can tell an
	// eligible red from a provisional one without fetching the full
	// snapshot. Semantic values only — no ticking ages (SSE-hash
	// stability).
	Eligibility    *RegimeEligibility `json:"eligibility,omitempty"`
	FreshnessClass string             `json:"freshness_class,omitempty"`
}

RegimeMonitorIndicator is a compact indicator reading and its data quality.

type RegimeMonitorResult

type RegimeMonitorResult struct {
	AsOf            time.Time                `json:"as_of"`
	AuthorityHealth *RegimeAuthorityHealth   `json:"authority_health,omitempty"`
	Fingerprint     Fingerprint              `json:"fingerprint"`
	Lifecycle       LifecycleState           `json:"lifecycle,omitzero"`
	Summary         RegimeSummary            `json:"summary"`
	Posture         RegimePosture            `json:"posture,omitzero"`
	Composite       RegimeComposite          `json:"composite"`
	WarningDetails  []RegimeWarning          `json:"warning_details,omitempty"`
	DataQuality     []DataQualityHealth      `json:"data_quality,omitempty"`
	SourceHealth    []CompactSourceHealth    `json:"source_health,omitempty"`
	Indicators      []RegimeMonitorIndicator `json:"indicators"`
}

RegimeMonitorResult is the compact regime lifecycle and indicator projection.

func CompactRegimeMonitor

func CompactRegimeMonitor(r *RegimeSnapshotResult) RegimeMonitorResult

CompactRegimeMonitor builds the bounded monitor projection from a regime snapshot. A nil input yields an unavailable zero-value result.

type RegimePosture

type RegimePosture struct {
	Label      string `json:"label,omitempty"`
	Tone       string `json:"tone,omitempty"`
	Stage      string `json:"stage,omitempty"`
	Severity   string `json:"severity,omitempty"`
	Readiness  string `json:"readiness,omitempty"`
	Confidence string `json:"confidence,omitempty"`
	Evidence   string `json:"evidence,omitempty"`
}

RegimePosture is the canonical display/policy read for market-regime consumers. UIs should render this instead of deriving their own tone from raw cluster counts.

func BuildRegimePosture

func BuildRegimePosture(r *RegimeSnapshotResult) RegimePosture

BuildRegimePosture derives a stable display posture from the daemon-authored snapshot. A nil snapshot produces a blocked data-quality posture.

type RegimeSnapshotParams

type RegimeSnapshotParams struct{}

RegimeSnapshotParams is the input for MethodRegimeSnapshot. Empty body means "fetch all regime indicators with default parameters." A future caller could trim to a subset, but v1 always returns all rows — partial responses are surfaced via per-indicator Status.

type RegimeSnapshotResult

type RegimeSnapshotResult struct {
	AsOf time.Time `json:"as_of"`
	// AuthorityHealth describes how the daemon obtained this response. It is
	// response/cache metadata, not classified market evidence: semantic regime
	// fingerprints must ignore it. Nil preserves compatibility with older
	// daemons; the Phase 1 authority populates it on every served last-good
	// snapshot. Cold authorities fail with CodeRegimeUnavailable instead of
	// manufacturing an empty or partial RegimeSnapshotResult.
	AuthorityHealth *RegimeAuthorityHealth `json:"authority_health,omitempty"`
	// TapeSessionState classifies the official US cash-equity calendar date
	// this snapshot was taken on (TapeSessionFor). On a closed date
	// (weekend/holiday) the direct SPY/VIX day-change prints are frozen
	// last-session values — the anchors can even reset independently while
	// closed — so they carry evidence but cannot enter or hold tape-driven
	// lifecycle stages. Empty means outside embedded calendar coverage:
	// tape terms keep full effect (fail-open). Excluded from the regime
	// fingerprint projection so weekday/weekend tickover alone never
	// re-fires alerts.
	TapeSessionState  string                 `json:"tape_session_state,omitempty"`
	TapeSessionReason string                 `json:"tape_session_reason,omitempty"`
	TapeNextOpen      *time.Time             `json:"tape_next_open,omitempty"`
	Fingerprint       Fingerprint            `json:"fingerprint"`
	Lifecycle         LifecycleState         `json:"lifecycle,omitzero"`
	Summary           RegimeSummary          `json:"summary"`
	Posture           RegimePosture          `json:"posture,omitzero"`
	VIXTermStructure  RegimeVIXTerm          `json:"vix_term_structure"`
	VolOfVol          RegimeVolOfVol         `json:"vol_of_vol"`
	HYGSPYDivergence  RegimeHYGSPYDivergence `json:"hyg_spy_divergence"`
	CreditSpreads     RegimeCreditSpreads    `json:"credit_spreads"`
	FundingStress     RegimeFundingStress    `json:"funding_stress"`
	USDJPY            RegimeUSDJPY           `json:"usd_jpy"`
	GammaZero         RegimeGammaZero        `json:"gamma_zero"`
	Breadth           RegimeBreadth          `json:"breadth"`
	// Composite carries the daemon-side rollup the CLI shows above the
	// indicator rows (verdict + ranked/unranked counts), so MCP consumers
	// don't have to recompute it from per-row Status fields. Populated on
	// every response.
	Composite RegimeComposite `json:"composite"`
	// WarningDetails carries structured, row-scoped data-quality issues
	// that affected this snapshot but did not make the whole RPC fail.
	// Agent surfaces should prefer these over parsing ErrorMessage strings:
	// each warning states what happened, what it changes in the composite,
	// and the next useful action.
	WarningDetails []RegimeWarning `json:"warning_details,omitempty"`
	// DataQuality carries the same high-level data-quality summary used by
	// status.health: degraded gamma and stale regime clusters. It is coarser
	// than WarningDetails by design, so humans and agents can decide whether
	// to interpret the regime read carefully without walking every row.
	DataQuality []DataQualityHealth `json:"data_quality,omitempty"`
	// SourceHealth is the orchestration-facing freshness/readiness summary
	// for each broad-market source cluster. It avoids timestamp-sensitive
	// alert churn: fingerprints hash the classified status, not age.
	SourceHealth []SourceHealth `json:"source_health,omitempty"`
	// SpecDoc points consumers (especially LLM-driven ones) at the
	// canonical methodology + threshold reference so they don't
	// hallucinate band edges. It is the published URL rather than a
	// repository path: a remote MCP client can fetch the former and
	// cannot open the latter. Same value on every response.
	SpecDoc string `json:"spec_doc"`
}

RegimeSnapshotResult is the wire payload for the dashboard generator and the MCP natural-language interface. One JSON envelope, all rows. Each row carries:

  • raw measurements plus compact band/as-of metadata for agents
  • a `notes` field embedding the full methodology prose for explain-mode consumers
  • a structured Status the renderer branches on for UI state

Compatibility note for renderers: the daemon never returns nil for any indicator field — empty / unavailable indicators surface Status="unavailable" with populated Notes. Numerical fields are pointers so "not arrived yet" vs "exactly zero" stays distinguishable.

type RegimeSummary

type RegimeSummary struct {
	Label             string   `json:"label"`
	Evidence          string   `json:"evidence"` // cluster-level balance
	IndicatorEvidence string   `json:"indicator_evidence,omitempty"`
	PunchLine         string   `json:"punch_line"`
	Confidence        string   `json:"confidence"`
	DominantRisks     []string `json:"dominant_risks,omitempty"`
	NotAdvice         string   `json:"not_advice,omitempty"`
}

RegimeSummary is the compact, agent-first reading of a regime snapshot. It deliberately avoids probabilities or trade instructions: the fields describe the evidence balance, coverage, and current condition only.

type RegimeThresholds

type RegimeThresholds struct {
	Label  string `json:"label,omitempty"`
	Green  string `json:"green,omitempty"`
	Yellow string `json:"yellow,omitempty"`
	Red    string `json:"red,omitempty"`
	// Trip is the compact display form of Red: the trigger a gauge face
	// prints beside its reading ("trips <40% (50d)"). It restates Red's own
	// threshold in fewer words and never introduces a second number — the
	// two are authored together at the single call site that owns this
	// indicator's bands, so a renderer never has to parse Red or invent a
	// cutoff of its own.
	Trip            string `json:"trip,omitempty"`
	Heuristic       bool   `json:"heuristic,omitempty"`
	PendingBacktest bool   `json:"pending_backtest,omitempty"`
}

RegimeThresholds names the heuristic threshold set used to classify an indicator. The string bands are intentionally compact and heterogeneous: each row has different units, so a label plus per-band text is friendlier than forcing everything into one numeric schema.

func HeuristicThresholds

func HeuristicThresholds(label, green, yellow, red, trip string) *RegimeThresholds

HeuristicThresholds builds the heuristic/pending-backtest threshold metadata shared by the daemon regime rows and the backtest builder. The Heuristic and PendingBacktest bits are policy: they mark bands whose values have not yet earned promotion through the decisions journal. Trip is the compact display form of red and is authored here beside it, so a gauge face can print a trigger without any renderer parsing the worded band.

func RegimeThresholdsFor added in v2.8.0

func RegimeThresholdsFor(indicator string) *RegimeThresholds

RegimeThresholdsFor returns the published band prose for an indicator, or nil when the indicator is unknown. Each call builds a fresh value: the result is embedded per-snapshot and must not be shared across them.

type RegimeUSDJPY

type RegimeUSDJPY struct {
	RegimeIndicatorMeta
	Status        string   `json:"status"`
	Symbol        string   `json:"symbol"` // "USD.JPY" canonical form
	Last          *float64 `json:"last"`
	Close7DAgo    *float64 `json:"close_7d_ago"`      // close from 7 trading days ago
	WeeklyChange  *float64 `json:"weekly_change_pct"` // (last − close_7d_ago) / close_7d_ago × 100
	DataType      string   `json:"data_type,omitempty"`
	Notes         string   `json:"notes,omitempty"`
	ErrorMessage  string   `json:"error_message,omitempty"`
	FieldsMissing []string `json:"fields_missing,omitempty"`
	// Per-scalar provenance. Last is firm-live (or firm-frozen);
	// Close7DAgo is always estimate-derived (MIDPOINT historical bar).
	LastQuality       *Quality `json:"last_quality,omitempty"`
	Close7DAgoQuality *Quality `json:"close_7d_ago_quality,omitempty"`
	// Streak counts consecutive sessions in the current band. See
	// RegimeVIXTerm.Streak for the semantics.
	Streak *StreakInfo `json:"streak,omitempty"`
}

RegimeUSDJPY is the FX-carry stress row: USD/JPY exchange rate. Spec measures "weekly move" — daemon surfaces last and 7-trading-days-ago close so the consumer can compute the change. Source is FX-pair routing (CASH/IDEALPRO); routing arrives in a sibling commit.

type RegimeVIXTerm

type RegimeVIXTerm struct {
	RegimeIndicatorMeta
	Status        string   `json:"status"`
	VIX           *float64 `json:"vix"`
	VIX3M         *float64 `json:"vix3m"`
	Ratio         *float64 `json:"ratio"` // VIX / VIX3M
	DataType      string   `json:"data_type,omitempty"`
	Notes         string   `json:"notes,omitempty"`
	ErrorMessage  string   `json:"error_message,omitempty"`
	FieldsMissing []string `json:"fields_missing,omitempty"`
	// VIX previous regular-session close and the day's percent change.
	// Trading dates: tick 9 alongside the price tick — pre-open this is
	// typically the only useful daily anchor since VIX itself doesn't
	// trade. Official non-trading dates: pinned to the official daily
	// closes of the last two completed sessions, because the gateway's
	// tick-9 anchor and last print can each reset independently while
	// the market is closed. Both value fields nil when no anchor was
	// resolvable.
	VIXPrevClose *float64 `json:"vix_prev_close,omitempty"`
	VIXChangePct *float64 `json:"vix_change_pct,omitempty"` // (vix − prev_close) / prev_close × 100
	// VIXChangeBasis is the day-change provenance on closed dates. Empty on
	// trading dates (live print vs tick-9 close).
	VIXChangeBasis string `json:"vix_change_basis,omitempty"`
	// Per-scalar provenance. Each *Quality is nil when the corresponding
	// value pointer is nil; otherwise the daemon populates it at the
	// fetch site so renderers can show "firm live", "frozen", or
	// "estimate · 18s" without re-deriving from DataType.
	VIXQuality   *Quality `json:"vix_quality,omitempty"`
	VIX3MQuality *Quality `json:"vix3m_quality,omitempty"`
	// Cboe's published VIX3M daily close, read independently of the broker,
	// and what comparing it against the broker leg established. VIX3MSource
	// names which of the two observations the served VIX3M came from. The
	// broker keeps answering with a value off-window whatever its real
	// vintage; only a dated official close can settle that, so these fields
	// are what an off-window age bound and a stuck-subscription check read.
	// VIX3MGatewayLast retains the broker's own reading when the official close
	// supersedes it, so a disagreement carries both numbers rather than an
	// unevidenced claim.
	VIX3MSource       string   `json:"vix3m_source,omitempty"`
	VIX3MGatewayLast  *float64 `json:"vix3m_gateway_last,omitempty"`
	VIX3MOfficial     *float64 `json:"vix3m_official,omitempty"`
	VIX3MOfficialDate string   `json:"vix3m_official_date,omitempty"`
	VIX3MCrossCheck   string   `json:"vix3m_cross_check,omitempty"`
	// VIX3MAnchorVIX is the VIX print observed together with the served VIX3M
	// leg, and travels with it when the leg is carried across a missed poll.
	// Without the anchor, "how far has VIX moved since this VIX3M was
	// observed" is unanswerable after the first carry, and the in-session
	// carry tolerance degrades to a bare timer. Nil unless both legs were
	// observed live together.
	VIX3MAnchorVIX *float64 `json:"vix3m_anchor_vix,omitempty"`
	// Streak counts how many consecutive sessions this row's value has
	// been in its current band. Persisted across daemon restarts in daemon.db.
	// Nil when the band can't
	// be determined (computing / unavailable / error) — the streak
	// freezes rather than resets.
	Streak *StreakInfo `json:"streak,omitempty"`
}

RegimeVIXTerm is Indicator 1: VIX/VIX3M ratio. Watch for sustained inversion (ratio > 1.0) over 2-3 sessions, not a single spike.

FieldsMissing is an advisory list of pointer-typed fields above (e.g. "vix3m", "ratio") that did NOT land within the fetch budget even though the row's primary measurement succeeded. Absent when nothing is missing. Use it to dim a sub-cell without re-classifying the whole row as `error`.

type RegimeVolOfVol

type RegimeVolOfVol struct {
	RegimeIndicatorMeta
	Status       string      `json:"status"`
	Symbol       string      `json:"symbol,omitempty"` // "VVIX"
	Last         *float64    `json:"last"`
	Change20D    *float64    `json:"change_20d_pct,omitempty"` // (last − t-20) / t-20 × 100
	AsOfDate     string      `json:"as_of_date,omitempty"`     // YYYY-MM-DD observation date
	Source       string      `json:"source,omitempty"`
	Notes        string      `json:"notes,omitempty"`
	ErrorMessage string      `json:"error_message,omitempty"`
	ValueQuality *Quality    `json:"value_quality,omitempty"`
	Streak       *StreakInfo `json:"streak,omitempty"`
}

RegimeVolOfVol is the VVIX vol-of-vol row. It uses Cboe's official daily VVIX time series rather than a retail-gateway quote, because VVIX is itself an index calculation and end-of-day source quality is better than pretending there is a continuously tradable instrument.

type RegimeWarning

type RegimeWarning struct {
	Code     string `json:"code"`
	Scope    string `json:"scope"`
	Severity string `json:"severity"`
	Message  string `json:"message"`
	Impact   string `json:"impact"`
	Action   string `json:"action"`
}

RegimeWarning is a structured data-quality or availability issue scoped to one regime indicator. Severity is "info", "warning", or "error" from the point of view of interpreting the snapshot, not the RPC transport.

type Request

type Request struct {
	ID     string          `json:"id"`
	Method string          `json:"method"`
	Params json.RawMessage `json:"params,omitempty"`
}

Request is one custom daemon-protocol request. Params contains the typed method payload; an absent Params value is distinct only where that method's decoder says so.

type ResetDrawdownParams

type ResetDrawdownParams struct {
	Reason string `json:"reason"`
	Origin string `json:"origin,omitempty"`
}

ResetDrawdownParams clears the latch with a mandatory reason. The reset re-bases the adjusted peak to the current observation; reducing declared risk capital afterwards is a policy revision, and the result message says so.

type Response

type Response struct {
	ID     string          `json:"id"`
	Ok     bool            `json:"ok"`
	Result json.RawMessage `json:"result,omitempty"`
	Frame  json.RawMessage `json:"frame,omitempty"`
	Stream bool            `json:"stream,omitempty"`
	End    bool            `json:"end,omitempty"`
	Error  *Error          `json:"error,omitempty"`
}

Response is one custom daemon-protocol response. Unary success uses Result; streams emit Frame values and terminate with End. Error is terminal when Ok is false.

type RiskPolicyResult

type RiskPolicyResult struct {
	AsOf time.Time `json:"as_of"`
	// Status is the manager state: active | absent | drift | error.
	Status  string `json:"status"`
	Source  string `json:"source,omitempty"` // file | none
	Path    string `json:"path,omitempty"`
	Message string `json:"message,omitempty"`

	PolicyID          string       `json:"policy_id,omitempty"`
	PolicyVersion     int          `json:"policy_version,omitempty"`
	PolicyFingerprint *Fingerprint `json:"policy_fingerprint,omitempty"`

	// Unapproved lists material keys the operator has not chosen; every
	// dependent control renders unapproved until they exist in the file.
	Unapproved []string `json:"unapproved,omitempty"`

	Capital   CapitalStateReport       `json:"capital"`
	Limits    []risk.ConstitutionLimit `json:"limits,omitempty"`
	Overrides []OverrideRecord         `json:"overrides,omitempty"`
	Cadence   []ArtefactRecord         `json:"cadence,omitempty"`
	Inventory []PolicyPinStatus        `json:"inventory,omitempty"`

	InputHealth []SourceHealth `json:"input_health,omitempty"`
}

RiskPolicyResult is the policy.snapshot payload.

type RiskPolicyWriteResult

type RiskPolicyWriteResult struct {
	OK       bool            `json:"ok"`
	At       time.Time       `json:"at"`
	Message  string          `json:"message,omitempty"`
	Override *OverrideRecord `json:"override,omitempty"`
}

RiskPolicyWriteResult acknowledges one governance write.

type RuleTransitionEntry

type RuleTransitionEntry struct {
	At                time.Time `json:"at"`
	Rule              string    `json:"rule"`
	Status            string    `json:"status"`
	Was               string    `json:"was,omitempty"`
	Evidence          string    `json:"evidence,omitempty"`
	PolicyID          string    `json:"policy_id,omitempty"`
	PolicyVersion     int       `json:"policy_version,omitempty"`
	PolicyFingerprint string    `json:"policy_fingerprint,omitempty"`
}

RuleTransitionEntry is one persisted rule status transition. Evidence is event free text for display, never parsed into authority.

type RulebookSettings

type RulebookSettings struct {
	Enabled SettingsBool `json:"enabled"`
	// EarningsOverrides maps SYMBOL → "YYYY-MM-DD" (optional "Tamc"/"Tbmo"
	// suffix). Overrides are authoritative over fetched dates for rules
	// 6-8; set a symbol to null to clear it.
	EarningsOverrides SettingsStringMap `json:"earnings_overrides"`
}

RulebookSettings controls the advisory trading rulebook (internal-docs/design/trading-rulebook.md): the 14-rule daily checklist plus its manual earnings-date overrides. Disabling hides the SPA card, empties rules.snapshot, and stops advisory rule_* preview warnings; it cannot affect broker-write gating in either direction.

type RulesHistoryParams

type RulesHistoryParams struct {
	Since string `json:"since,omitempty"`
	Until string `json:"until,omitempty"`
	// Rule filters on the exact rule id (for example
	// single_name_exposure). Empty matches all rules.
	Rule  string `json:"rule,omitempty"`
	Limit int    `json:"limit,omitempty"`
}

RulesHistoryParams selects a window of persisted rulebook transitions; boundary and limit semantics match RegimeHistoryParams.

type RulesHistoryResult

type RulesHistoryResult struct {
	AsOf       time.Time             `json:"as_of"`
	Since      time.Time             `json:"since"`
	Until      time.Time             `json:"until"`
	Entries    []RuleTransitionEntry `json:"entries"`
	Count      int                   `json:"count"`
	TotalCount int                   `json:"total_count"`
	Limit      int                   `json:"limit"`
	Truncated  bool                  `json:"truncated"`
	Index      HistoryIndexHealth    `json:"index"`
}

RulesHistoryResult is the rules.history envelope — the same shape as RegimeHistoryResult with rule-transition entries.

type RulesResult

type RulesResult struct {
	AsOf time.Time `json:"as_of"`
	// Enabled mirrors features.rulebook.enabled; when false Rules is empty
	// and Status says disabled.
	Enabled bool   `json:"enabled"`
	Status  string `json:"status"` // ok | degraded | disabled
	// Rules holds all rows in rulebook order; Ranked holds indexes into
	// Rules sorted hardest-first so renderers agree on ordering without
	// re-deriving it.
	Rules  []risk.RuleRow `json:"rules"`
	Ranked []int          `json:"ranked,omitempty"`
	// BreachCounts summarizes row counts by status for compact surfaces.
	BreachCounts map[string]int `json:"breach_counts,omitempty"`
	// InputHealth is the result-level gate: when positions or account are
	// pending/stale/absent every portfolio-dependent row is unknown, never
	// pass. Canonical snapshots carry exactly one entry for account,
	// positions, earnings, regime_stage, and tape.
	InputHealth []SourceHealth `json:"input_health,omitempty"`
	Earnings    []EarningsInfo `json:"earnings,omitempty"`
	// Policy provenance, mirroring proposals/Stress.
	PolicyID          string       `json:"policy_id"`
	PolicyVersion     int          `json:"policy_version"`
	PolicyFingerprint *Fingerprint `json:"policy_fingerprint,omitempty"`
	// BaseCurrency scopes every *_base impact figure.
	BaseCurrency string `json:"base_currency,omitempty"`
}

RulesResult is the rules.snapshot payload. Rows come from the pure internal/risk evaluator; this envelope adds provenance and input health.

type RulesSnapshotParams

type RulesSnapshotParams struct {
	// Symbol narrows per-name offender lists to one underlying; portfolio
	// rules still evaluate portfolio-wide.
	Symbol string `json:"symbol,omitempty"`
}

RulesSnapshotParams selects optional evaluation scope. Zero value means the full 14-rule checklist over all held names.

type ScanListResult

type ScanListResult struct {
	Presets []ScanPresetSummary `json:"presets"`
}

ScanListResult enumerates configured presets.

type ScanParamInstrument

type ScanParamInstrument struct {
	Name string `json:"name"`
	Type string `json:"type"`
}

ScanParamInstrument is one row in ScanParamsResult.Instruments.

type ScanParamLocation

type ScanParamLocation struct {
	Code        string `json:"code"`
	DisplayName string `json:"display_name"`
}

ScanParamLocation is one row in ScanParamsResult.Locations.

type ScanParamScanType

type ScanParamScanType struct {
	Code        string   `json:"code"`
	DisplayName string   `json:"display_name"`
	Instruments []string `json:"instruments,omitempty"`
}

ScanParamScanType is one row in ScanParamsResult.ScanTypes. Instruments is the list of instrument-type tokens this scan is valid for (e.g. ["STK", "ETF"]); empty means "all".

type ScanParamsParams

type ScanParamsParams struct {
	Instrument    string `json:"instrument,omitempty"`
	IncludeRawXML bool   `json:"include_raw_xml,omitempty"`
}

ScanParamsParams requests the gateway's full scanner catalog. Instrument filters the ScanTypes list to those valid for the given instrument (e.g. "STK"); empty returns every type. IncludeRawXML attaches the raw XML payload to the response for callers that want to grep for fields not surfaced in the parsed struct (filter values, instrument flags, etc.). The XML is typically ~200 KB on a US Pro gateway.

type ScanParamsResult

type ScanParamsResult struct {
	Instruments []ScanParamInstrument `json:"instruments"`
	Locations   []ScanParamLocation   `json:"locations"`
	ScanTypes   []ScanParamScanType   `json:"scan_types"`
	RawXML      string                `json:"raw_xml,omitempty"`
	AsOf        time.Time             `json:"as_of"`
}

ScanParamsResult mirrors pkg/ibkr.ScannerParameters but stays in the rpc package so consumers (CLI, MCP) don't need to import pkg/ibkr. Code comments on the wire-level types live with the parser.

type ScanPresetSummary

type ScanPresetSummary struct {
	Name       string `json:"name"`
	Type       string `json:"type"`
	Exchange   string `json:"exchange"`
	Instrument string `json:"instrument,omitempty"`
	Limit      int    `json:"limit"`
}

ScanPresetSummary describes a single preset entry in scan list.

type ScanResult

type ScanResult struct {
	Preset string    `json:"preset"`
	Type   string    `json:"type"`
	Rows   []ScanRow `json:"rows"`
	AsOf   time.Time `json:"as_of"`
}

ScanResult wraps the rows.

type ScanRow

type ScanRow struct {
	Rank               int           `json:"rank"`
	Symbol             string        `json:"symbol"`
	SecType            string        `json:"sec_type,omitempty"`
	Exchange           string        `json:"exchange,omitempty"`
	Currency           string        `json:"currency,omitempty"`
	LocalSymbol        string        `json:"local_symbol,omitempty"`
	TradingClass       string        `json:"trading_class,omitempty"`
	InstrumentTags     []string      `json:"instrument_tags,omitempty"`
	Last               *float64      `json:"last,omitempty"`
	PrevClose          *float64      `json:"prev_close,omitempty"`
	Change             *float64      `json:"change,omitempty"`
	ChangePct          *float64      `json:"change_pct,omitempty"`
	Volume             *int64        `json:"volume,omitempty"`
	AvgVolume20D       *int64        `json:"avg_volume_20d,omitempty"`
	AvgDollarVolume20D *float64      `json:"avg_dollar_volume_20d,omitempty"`
	IV                 *float64      `json:"iv,omitempty"`
	Week52High         *float64      `json:"week_52_high,omitempty"`
	Week52Low          *float64      `json:"week_52_low,omitempty"`
	DataType           string        `json:"data_type,omitempty"`
	FeedType           string        `json:"feed_type,omitempty"`
	PriceAt            time.Time     `json:"price_at,omitzero"`
	PriceAsOf          string        `json:"price_as_of,omitempty"`
	AsOf               time.Time     `json:"as_of,omitzero"`
	VolumePhase        string        `json:"volume_phase,omitempty"`
	WarningDetails     []DataWarning `json:"warning_details,omitempty"`
	Comment            string        `json:"comment,omitempty"`
}

ScanRow is one row of a scanner result. The IBKR scanner subscription only returns rank+symbol+three-mostly-empty-comment-fields per row, so every numeric field below is populated by the daemon via a follow-up snapshot subscribe on the symbol. Pointers (not scalars) so consumers can distinguish "the gateway didn't deliver this tick within the enrichment window" from "the value is genuinely zero" — the no-fabrication invariant. Comment carries the raw scanner-side text when non-empty (rare; most scan types leave it blank).

Currency is the ISO-4217 code for Last / PrevClose / Change / Week52* — needed so non-US ad-hoc scans (e.g. --exchange STK.EU.IBIS) render with the right symbol instead of a hardcoded $. Empty string means "the daemon couldn't resolve a currency for this row"; renderers should fall back to $ in that case for back-compat with old daemons.

Unit conventions follow Quote: ChangePct is in PERCENT units (5.41 means 5.41 %), IV is a DECIMAL FRACTION (0.342 means 34.2 %).

type ScanRunParams

type ScanRunParams struct {
	Preset          string  `json:"preset,omitempty"`
	Type            string  `json:"type,omitempty"`
	Exchange        string  `json:"exchange,omitempty"`
	Instrument      string  `json:"instrument,omitempty"`
	Limit           int     `json:"limit,omitempty"`
	MinPrice        float64 `json:"min_price,omitempty"`
	MinVolume       int64   `json:"min_volume,omitempty"`
	MinDollarVolume float64 `json:"min_dollar_volume,omitempty"`
	RequireLive     bool    `json:"require_live,omitempty"`
	ExcludePenny    bool    `json:"exclude_penny,omitempty"`
}

ScanRunParams runs a scanner. Two modes:

  1. Preset shorthand: set Preset to the name of a [scans.<name>] block from config.toml (or one of the built-in defaults). Type/Exchange are ignored.
  2. Ad-hoc: leave Preset empty and set Type (scanCode), Exchange (locationCode), and optionally Instrument directly. Useful for agents that don't want to persist a preset to the user's config file.

Exactly one of Preset or Type is required. Limit is optional in both modes; <=0 falls back to the preset's configured Limit (mode 1) or the daemon's hard cap of 50 (mode 2).

type SessionClass

type SessionClass int

SessionClass classifies an instant by its U.S. equity-options session phase. Callers that need different cadence in pre vs RTH vs post vs closed (most prominently the gamma cache's session-aware soft-TTL) branch on this rather than re-deriving the boundaries themselves.

Boundaries (America/New_York):

  • Pre : weekdays 04:00–09:30
  • RTH : weekdays 09:30–16:00
  • Post : weekdays 16:00–20:00
  • Closed: everything else (overnight + weekends)

Holidays are NOT modeled — same fall-through policy as IsOptionRTH.

const (
	SessionClosed SessionClass = iota
	SessionPre
	SessionRTH
	SessionPost
)

Session classes partition the U.S. equity-options day using the boundaries documented on SessionClass.

func ClassifySession

func ClassifySession(now time.Time) SessionClass

ClassifySession returns the SessionClass containing now. Fail-safe: if America/New_York can't be loaded (minimal container, missing tzdata), returns SessionRTH — the broadest "treat as active" answer so refresh cadence isn't accidentally disabled under degraded zone data. Mirrors IsOptionRTH's fail-open policy.

func (SessionClass) String

func (c SessionClass) String() string

String renders the session class for log lines and debug output. Not load-bearing on the wire (the gamma cache holds the enum value directly), but used in test failure messages and warning logs.

type SettingsBool

type SettingsBool struct {
	Value  bool   `json:"value"`
	Access string `json:"access"`
	Source string `json:"source"`
	Reason string `json:"reason,omitempty"`
}

SettingsBool is a boolean value annotated with access and source authority.

type SettingsFloat

type SettingsFloat struct {
	Value  float64 `json:"value"`
	Access string  `json:"access"`
	Source string  `json:"source"`
	Reason string  `json:"reason,omitempty"`
}

SettingsFloat is a floating-point value annotated with access and source authority.

type SettingsInt

type SettingsInt struct {
	Value  int    `json:"value"`
	Access string `json:"access"`
	Source string `json:"source"`
	Reason string `json:"reason,omitempty"`
}

SettingsInt is an integer value annotated with access and source authority.

type SettingsKeyKind

type SettingsKeyKind string

SettingsKeyKind is the value grammar of a writable runtime setting.

const (
	// SettingsKindBool accepts true, false, or null (clear the override).
	SettingsKindBool SettingsKeyKind = "bool"
	// SettingsKindFloat accepts a positive number or null.
	SettingsKindFloat SettingsKeyKind = "float"
	// SettingsKindInt accepts a positive integer or null.
	SettingsKindInt SettingsKeyKind = "int"
	// SettingsKindDateMap accepts an object of SYMBOL → "YYYY-MM-DD" (optional
	// Tamc/Tbmo suffix) entries; a null entry clears that symbol, a null map
	// clears all of them, and patches merge per symbol.
	SettingsKindDateMap SettingsKeyKind = "date-map"
)

type SettingsKeySpec

type SettingsKeySpec struct {
	// Key is the dotted path used by the CLI, the JSON patch body, and the
	// generated docs, e.g. "features.rulebook.enabled".
	Key string
	// Kind selects the value grammar.
	Kind SettingsKeyKind
	// Class selects the writability gate.
	Class string
	// Doc is the one-sentence plain-English description rendered in
	// `canary settings set --help` and the generated configuration reference.
	Doc string
}

SettingsKeySpec declares one writable runtime setting.

func SettingsKeys

func SettingsKeys() []SettingsKeySpec

SettingsKeys returns the registry in stable display order.

type SettingsString

type SettingsString struct {
	Value  string `json:"value"`
	Access string `json:"access"`
	Source string `json:"source"`
	Reason string `json:"reason,omitempty"`
}

SettingsString is a string value annotated with access and source authority.

type SettingsStringMap

type SettingsStringMap struct {
	Value  map[string]string `json:"value,omitempty"`
	Access string            `json:"access"`
	Source string            `json:"source"`
	Reason string            `json:"reason,omitempty"`
}

SettingsStringMap is a map-valued setting with the standard access/source/reason contract.

type SkewFitInfo

type SkewFitInfo struct {
	Points   int     `json:"points"`
	RSquared float64 `json:"r_squared"`
	// ResidualRMS is the root-mean-square fit residual in IV (vol)
	// units over the fitted legs. R² is amplitude-relative — a flat
	// smile reads as a poor fit even when residuals are tiny, and a
	// steep one as a good fit despite large absolute errors — so the
	// RMS is the number that actually bounds the repricing error the
	// sticky-moneyness sweep consumes. Zero means no residual was recorded.
	ResidualRMS float64    `json:"residual_rms,omitempty"`
	Range       [2]float64 `json:"range"`
}

SkewFitInfo is the per-expiry diagnostic for the sticky-moneyness skew curve fitted at snapshot time. Populated only when SkewModel reports a fitted model (e.g. "sticky-moneyness-v1"); a renderer can surface it as "skew fit: 12 pts · R² 0.94 · m ∈ [-0.12, +0.09]" so the reader can audit how well the curve actually fit the observed IVs before acting on the zero-gamma level it implies.

Range is the moneyness window m = ln(K/S) the curve was fitted over; scenario spots that push a leg's moneyness outside the window are clamped to the boundary during the sweep.

type SourceFailure

type SourceFailure struct {
	Code      string    `json:"code"`
	Stage     string    `json:"stage"`
	FailedAt  time.Time `json:"failed_at"`
	Retryable bool      `json:"retryable"`
}

SourceFailure identifies where and how the most recent source attempt failed without carrying untrusted upstream text. FailedAt and Retryable are scheduling context; Code and Stage are stable semantic values suitable for persistence, rendering, and fingerprints.

type SourceHealth

type SourceHealth struct {
	Source               string       `json:"source"`
	Status               string       `json:"status"`
	AsOf                 time.Time    `json:"as_of,omitzero"`
	AgeSeconds           int64        `json:"age_seconds,omitempty"`
	MaxAgeSeconds        int64        `json:"max_age_seconds,omitempty"`
	Confidence           string       `json:"confidence,omitempty"`
	Fingerprint          *Fingerprint `json:"fingerprint,omitempty"`
	FingerprintStability string       `json:"fingerprint_stability,omitempty"`
	// RefreshState separates source scheduling from evidence quality. A
	// source can be not_due with no current negative, or stale because a due
	// fetch failed and is waiting for its bounded retry.
	RefreshState string     `json:"refresh_state,omitempty"`
	NextAttempt  *time.Time `json:"next_attempt,omitempty"`
	// LastFailure is a redacted, allowlisted machine-readable failure. Raw
	// transport, provider, and parser text must never cross the RPC boundary.
	LastFailure *SourceFailure `json:"last_failure,omitempty"`
	Notes       []string       `json:"notes,omitempty"`
}

SourceHealth is the source-level freshness and confidence contract for scheduled monitors. FingerprintStability says why downstream dedupe should key off Fingerprint rather than wall-clock AsOf churn.

func BuildRegimeSourceHealth

func BuildRegimeSourceHealth(r *RegimeSnapshotResult, now time.Time) []SourceHealth

BuildRegimeSourceHealth derives per-cluster freshness and confidence. It returns nil for a nil snapshot; nil therefore means unavailable, not healthy.

type StockProtectionSettings

type StockProtectionSettings struct {
	Enabled SettingsBool `json:"enabled"`
}

StockProtectionSettings controls stock-protection proposal actions without enabling broker writes.

type StreakInfo

type StreakInfo struct {
	Band     string `json:"band"`
	Sessions int    `json:"sessions"`
	Since    string `json:"since"`
}

StreakInfo tells a consumer how many consecutive trading sessions an indicator has been in its current band. Closes the wire-shape gap with the spec's repeated "sustained 2-3 days, not single spikes" language — a single snapshot can't distinguish day 1 of a stress regime from day 5, but the streak counter makes that difference visible inline ("yellow · day 3").

Band classification IS done daemon-side for streak purposes (a small violation of the "daemon doesn't derive bands" principle the spec states for the wire surface — but necessary for streak persistence). The bands used here mirror the spec's default cutoffs verbatim; a renderer that wants to apply a different threshold can still ignore Band and compute its own coloring from the row's raw measurement.

Since is the YYYY-MM-DD NY-tz session key for when the current streak began. Sessions ≥ 1; the first session in a band is day 1. Indicator unavailable/computing/error states freeze the counter rather than reset it — a stale data point shouldn't end a streak.

type StressAlertFlag

type StressAlertFlag struct {
	Title     string               `json:"title"`
	Direction risk.SignalDirection `json:"direction,omitempty"`
	Severity  risk.SignalSeverity  `json:"severity"`
}

StressAlertFlag is one compact advisory finding.

type StressAlertResult

type StressAlertResult struct {
	AsOf               time.Time                `json:"as_of"`
	Fingerprint        Fingerprint              `json:"fingerprint"`
	SourceFingerprints StressSourceFingerprints `json:"source_fingerprints,omitzero"`
	SourceHealth       []CompactSourceHealth    `json:"source_health,omitempty"`
	Action             string                   `json:"action,omitempty"`
	MarketConfirmation string                   `json:"market_confirmation,omitempty"`
	PortfolioFit       string                   `json:"portfolio_fit,omitempty"`
	// PortfolioAlertRelevant carries the producer-stamped relevance verdict
	// through the alert view; see StressResult.PortfolioAlertRelevant.
	PortfolioAlertRelevant *bool                      `json:"portfolio_alert_relevant,omitempty"`
	InputHealth            string                     `json:"input_health,omitempty"`
	Direction              risk.SignalDirection       `json:"direction,omitempty"`
	Severity               risk.SignalSeverity        `json:"severity"`
	PlannerModeHint        risk.PlannerMode           `json:"planner_mode_hint,omitempty"`
	PlannerReadiness       risk.PlannerReadiness      `json:"planner_readiness,omitempty"`
	Summary                string                     `json:"summary"`
	PrimaryDrivers         []risk.SignalID            `json:"primary_drivers,omitempty"`
	Portfolio              StressPortfolioSummary     `json:"portfolio"`
	Market                 StressMarketSummary        `json:"market"`
	OptionHealth           OptionHealthSummary        `json:"option_health"`
	ProtectionCoverage     *ProtectionCoverageSummary `json:"protection_coverage,omitempty"`
	SPYHedgeOffsetPct      *float64                   `json:"spy_hedge_offset_pct,omitempty"`
	Flags                  []StressAlertFlag          `json:"flags,omitempty"`
	Warnings               []string                   `json:"warnings,omitempty"`
	NotExecution           string                     `json:"not_execution"`
}

StressAlertResult is a bounded, alert-safe projection of Stress state. Empty flags are not reassuring unless the carried source health is conclusive.

func CompactStressAlert

func CompactStressAlert(c *StressResult, positions *PositionsResult) StressAlertResult

CompactStressAlert builds an alert-safe projection without changing the authority or freshness of its source snapshots.

type StressHistoryEntry

type StressHistoryEntry struct {
	At          time.Time `json:"at"`
	SessionKey  string    `json:"session_key,omitempty"`
	Fingerprint string    `json:"fingerprint,omitempty"`
	Account     string    `json:"account,omitempty"`
	AccountMode string    `json:"account_mode,omitempty"`
	Action      string    `json:"action,omitempty"`
	Severity    string    `json:"severity"`
	Direction   string    `json:"direction,omitempty"`
	MarketStage string    `json:"market_stage,omitempty"`
	// PortfolioAlertRelevant mirrors the producer-stamped verdict; nil
	// means the event predates the stamp.
	PortfolioAlertRelevant *bool  `json:"portfolio_alert_relevant,omitempty"`
	InputHealth            string `json:"input_health,omitempty"`
	Summary                string `json:"summary,omitempty"`
}

StressHistoryEntry is one persisted stress decision. Summary is event free text for display, never parsed into authority.

type StressHistoryParams

type StressHistoryParams struct {
	Since string `json:"since,omitempty"`
	Until string `json:"until,omitempty"`
	// Severity filters on the exact decision severity word (for example
	// watch, act). Empty matches all severities.
	Severity string `json:"severity,omitempty"`
	// Action filters on the exact decision action word (for example defend,
	// watch). Empty matches all actions.
	Action string `json:"action,omitempty"`
	Limit  int    `json:"limit,omitempty"`
}

StressHistoryParams selects a window of persisted stress decisions; boundary and limit semantics match RegimeHistoryParams.

type StressHistoryResult

type StressHistoryResult struct {
	AsOf       time.Time            `json:"as_of"`
	Since      time.Time            `json:"since"`
	Until      time.Time            `json:"until"`
	Entries    []StressHistoryEntry `json:"entries"`
	Count      int                  `json:"count"`
	TotalCount int                  `json:"total_count"`
	Limit      int                  `json:"limit"`
	Truncated  bool                 `json:"truncated"`
	Index      HistoryIndexHealth   `json:"index"`
}

StressHistoryResult is the stress.history envelope — the phase-1 history envelope with stress entries.

type StressInput

type StressInput struct {
	Account      AccountResult
	Positions    PositionsResult
	Regime       RegimeSnapshotResult
	MarketEvents MarketEventsResult
	Now          time.Time
}

StressInput is the pure state input shared by the CLI and MCP tool. It deliberately consumes existing daemon snapshots instead of adding a second risk-data path: account margin, portfolio exposure, and market regime stay single-source-of-truth.

type StressJournalSettings

type StressJournalSettings struct {
	Enabled SettingsBool `json:"enabled"`
}

StressJournalSettings controls typed stress-decision event collection in daemon.db, mirroring RegimeJournalSettings.

type StressMarketIndicator

type StressMarketIndicator struct {
	Name    string `json:"name"`
	Status  string `json:"status"` // green | amber | red | context | n/a
	AsOf    string `json:"as_of,omitempty"`
	Reading string `json:"reading,omitempty"`
	Comment string `json:"comment,omitempty"`
	// Trip is the served trigger anchor a gauge face prints beside Reading:
	// the indicator's compact red-band wording, or — where the trigger is a
	// measured level rather than a fixed band, as with dealer gamma — the
	// served level itself. Empty means this indicator has no served trigger
	// and its face stays reading-only; a renderer must never supply one.
	Trip string `json:"trip,omitempty"`
}

StressMarketIndicator is a display-ready market observation; its status is advisory evidence rather than execution authority.

type StressMarketSummary

type StressMarketSummary struct {
	RegimeVerdict string        `json:"regime_verdict,omitempty"`
	RegimePosture RegimePosture `json:"regime_posture,omitzero"`
	RedClusters   int           `json:"red_clusters"`
	// EligibleRedClusters counts reds that passed the confirmation gates
	// (depth + persistence + freshness) — the only reds used by
	// Stress act/urgent-grade decisions. RedClusters keeps the visible
	// (confirmed-band) reds for watch-grade evidence; the difference is
	// disclosed in UnconfirmedRedClusterNames.
	EligibleRedClusters        int      `json:"eligible_red_clusters"`
	EligibleRedClusterNames    []string `json:"eligible_red_cluster_names,omitempty"`
	YellowClusters             int      `json:"yellow_clusters"`
	RankedClusters             int      `json:"ranked_clusters"`
	UnrankedClusters           int      `json:"unranked_clusters"`
	RedClusterNames            []string `json:"red_cluster_names,omitempty"`
	YellowClusterNames         []string `json:"yellow_cluster_names,omitempty"`
	UnconfirmedRedClusterNames []string `json:"unconfirmed_red_cluster_names,omitempty"`
	AmbiguousClusters          []string `json:"ambiguous_clusters,omitempty"`
	PartialClusters            []string `json:"partial_clusters,omitempty"`
	ComputingClusters          []string `json:"computing_clusters,omitempty"`
	DegradedClusters           []string `json:"degraded_clusters,omitempty"`
	StaleClusters              []string `json:"stale_clusters,omitempty"`
	SPYPrice                   *float64 `json:"spy_price,omitempty"`
	SPYChangePct               *float64 `json:"spy_change_pct,omitempty"`
	VIX                        *float64 `json:"vix,omitempty"`
	VIXChangePct               *float64 `json:"vix_change_pct,omitempty"`
	// TapeSessionState classifies the official US cash-equity calendar date
	// the stress read ran on. On a closed date (weekend/holiday) the direct
	// SPY/VIX day-change prints are frozen last-session values — the anchors
	// can even reset independently while closed — so they carry evidence but
	// cannot confirm severity. Empty means outside embedded calendar
	// coverage: severity behaves as before (fail-open).
	TapeSessionState  string     `json:"tape_session_state,omitempty"`
	TapeSessionReason string     `json:"tape_session_reason,omitempty"`
	TapeNextOpen      *time.Time `json:"tape_next_open,omitempty"`
}

StressMarketSummary combines regime, tape, and source-quality context used by Stress. Its cluster counts retain rankability and confirmation distinctions.

type StressPortfolioSummary

type StressPortfolioSummary struct {
	BaseCurrency        string   `json:"base_currency,omitempty"`
	NetLiquidation      float64  `json:"net_liquidation,omitempty"`
	CushionPct          *float64 `json:"cushion_pct,omitempty"`
	LookAheadCushionPct *float64 `json:"look_ahead_cushion_pct,omitempty"`
	// CushionTripPct is the stress policy's margin-cushion watch floor: the
	// level at which either cushion reading leaves observe. It is served so a
	// gauge face can print "cushion 64% · trips <35%" without a renderer
	// keeping a twin of the policy number. Nil when no cushion was observed.
	CushionTripPct       *float64                   `json:"cushion_trip_pct,omitempty"`
	GrossExposurePctNLV  *float64                   `json:"gross_exposure_pct_nlv,omitempty"`
	NetDeltaPctNLV       *float64                   `json:"net_delta_pct_nlv,omitempty"`
	GrossDeltaPctNLV     *float64                   `json:"gross_delta_pct_nlv,omitempty"`
	LargestExposure      string                     `json:"largest_exposure,omitempty"`
	LargestExposurePct   *float64                   `json:"largest_exposure_pct_nlv,omitempty"`
	LargestDeltaExposure string                     `json:"largest_delta_exposure,omitempty"`
	LargestDeltaPctNLV   *float64                   `json:"largest_delta_pct_nlv,omitempty"`
	DailyPnLPct          *float64                   `json:"daily_pnl_pct,omitempty"`
	OptionGreeks         string                     `json:"option_greeks,omitempty"`
	ProtectionCoverage   *ProtectionCoverageSummary `json:"protection_coverage,omitempty"`
	HeldStress           []HeldStress               `json:"held_stress,omitempty"`

	// ExposureUnmeasured names the held underlyings that contributed nothing to
	// the exposure and concentration readings above: either the aggregator could
	// not value the group in the base currency at all, or it carried no
	// base-currency delta. Every figure beside it is a subtotal over the rest of
	// the book, so a threshold comparison against them can only prove a breach,
	// never a clean pass. Empty on a fully measured book.
	ExposureUnmeasured []string `json:"exposure_unmeasured,omitempty"`
}

StressPortfolioSummary is a redacted portfolio-risk projection. Pointer metrics distinguish unavailable observations from measured zero values.

type StressResult

type StressResult struct {
	AsOf               time.Time                `json:"as_of"`
	SourceAsOf         StressSourceAsOf         `json:"source_as_of,omitzero"`
	Fingerprint        Fingerprint              `json:"fingerprint"`
	SourceFingerprints StressSourceFingerprints `json:"source_fingerprints,omitzero"`
	SourceHealth       []SourceHealth           `json:"source_health,omitempty"`
	Policy             string                   `json:"policy,omitempty"`
	PolicyProfile      string                   `json:"policy_profile,omitempty"`
	PolicyVersion      string                   `json:"policy_version,omitempty"`
	PolicyFingerprint  Fingerprint              `json:"policy_fingerprint,omitzero"`
	Action             string                   `json:"action,omitempty"`
	MarketConfirmation string                   `json:"market_confirmation,omitempty"`
	PortfolioFit       string                   `json:"portfolio_fit,omitempty"`
	// PortfolioAlertRelevant is the producer-stamped verdict for "does this
	// snapshot concern the live portfolio enough to alert on". The policy has
	// exactly one copy, in internal/stress; the app alert gate and the SPA
	// preview gate read this field instead of re-deriving fit/exposure edge
	// cases. Nil means the producer predates the stamp — consumers fail open
	// to relevant, so version skew can add market-weather noise but never
	// suppress alert delivery.
	PortfolioAlertRelevant *bool                   `json:"portfolio_alert_relevant,omitempty"`
	InputHealth            string                  `json:"input_health,omitempty"`
	Direction              risk.SignalDirection    `json:"direction,omitempty"`
	Severity               risk.SignalSeverity     `json:"severity"`
	PlannerModeHint        risk.PlannerMode        `json:"planner_mode_hint,omitempty"`
	PlannerReadiness       risk.PlannerReadiness   `json:"planner_readiness,omitempty"`
	Summary                string                  `json:"summary"`
	PrimaryDrivers         []risk.SignalID         `json:"primary_drivers,omitempty"`
	Signals                []risk.Signal           `json:"signals,omitempty"`
	Rows                   []StressRow             `json:"rows"`
	Portfolio              StressPortfolioSummary  `json:"portfolio"`
	Market                 StressMarketSummary     `json:"market"`
	MarketIndicators       []StressMarketIndicator `json:"market_indicators,omitempty"`
	Warnings               []string                `json:"warnings,omitempty"`
	NotExecution           string                  `json:"not_execution"`
	// EstablishedAlertProjection is the producer-authored compatibility
	// contract for the Canary delivery behavior that existed at ad5b77b. It
	// does not grant any new delivery or pageability: consumers may use it only
	// to preserve that established occurrence and mode eligibility while the
	// main result truthfully adopts newer advisory health semantics.
	//
	// Nil means the producer predates this projection. A present projection is
	// strict and self-validating so consumers can fail closed on malformed
	// new-daemon data without treating version skew as corruption.
	EstablishedAlertProjection *EstablishedAlertProjection `json:"established_alert_projection,omitempty"`
}

StressResult is the compact scheduled-monitor payload. The stress read is stateless: it combines current broad-market regime with the current portfolio shape, then emits a fresh action snapshot. Fingerprint is the canonical alert identity for monitors; SourceFingerprints records the classified upstream state the stress read consumed.

type StressRow

type StressRow struct {
	Title     string               `json:"title"`
	Direction risk.SignalDirection `json:"direction,omitempty"`
	Severity  risk.SignalSeverity  `json:"severity"`
	Guidance  string               `json:"guidance"`
	Evidence  string               `json:"evidence,omitempty"`
}

StressRow is one bounded, daemon-derived advisory finding.

type StressSourceAsOf

type StressSourceAsOf struct {
	Account      time.Time `json:"account,omitzero"`
	Positions    time.Time `json:"positions,omitzero"`
	Regime       time.Time `json:"regime,omitzero"`
	MarketEvents time.Time `json:"market_events,omitzero"`
}

StressSourceAsOf records each source snapshot's observation time. Zero times mean the source timestamp is unavailable, not current.

type StressSourceFingerprints

type StressSourceFingerprints struct {
	Account      *Fingerprint `json:"account,omitempty"`
	Positions    *Fingerprint `json:"positions,omitempty"`
	Regime       *Fingerprint `json:"regime,omitempty"`
	MarketEvents *Fingerprint `json:"market_events,omitempty"`
}

StressSourceFingerprints carries optional semantic source identities. Nil means the source did not provide an identity.

type StrikeConcentration

type StrikeConcentration struct {
	// Underlying identifies which index this strike belongs to —
	// "SPY" or "SPX" today. Populated by single-underlying computes
	// with that compute's sym, and carried through the combined-scope
	// merge so the renderer can label per-row in the top-strikes
	// table without re-deriving from the trading class. Empty means
	// the only underlying in scope.
	Underlying string `json:"underlying,omitempty"`
	// TradingClass is the listed class on the contract — "SPY",
	// "SPX" (AM-settled monthly), "SPXW" (PM-settled weekly).
	// Distinct from Underlying for SPX which lists both classes.
	// Empty in single-class results that don't need disambiguation.
	TradingClass string  `json:"trading_class,omitempty"`
	Strike       float64 `json:"strike"`
	Expiry       string  `json:"expiry"` // YYYY-MM-DD
	Right        string  `json:"right"`  // "C" | "P"
	AbsGEX       float64 `json:"abs_gex"`
	OI           int64   `json:"open_interest"`
}

StrikeConcentration is one row of the "where dealer hedging concentrates" table — the top strikes ranked by sign-agnostic gamma notional |Γ| × OI × multiplier × spot² × 0.01. This is the more robust signal in regimes where the Perfiliev dealer-sign assumption can invert (covered-call ETF flow, autocall barrier proximity); the renderer can present it alongside ZeroGamma as a "call wall / put wall" view that's sign-convention agnostic.

type SubsystemHealth

type SubsystemHealth struct {
	Name        string    `json:"name"`
	Status      string    `json:"status"`
	Message     string    `json:"message,omitempty"`
	LastError   string    `json:"last_error,omitempty"`
	LastErrorAt time.Time `json:"last_error_at,omitzero"`
	StartedAt   time.Time `json:"started_at,omitzero"`
	EtaSeconds  int       `json:"eta_seconds,omitempty"`
	Progress    int       `json:"progress,omitempty"`
}

SubsystemHealth is a compact status.health diagnostic for tool families that can degrade independently while the gateway remains connected.

type TechnicalParams

type TechnicalParams struct {
	Symbols      []string `json:"symbols"`
	Benchmark    string   `json:"benchmark,omitempty"`     // default SPY
	LookbackDays int      `json:"lookback_days,omitempty"` // calendar days, default 420
	Market       string   `json:"market,omitempty"`        // us | de; applies to Symbols, not Benchmark
	Exchange     string   `json:"exchange,omitempty"`
	PrimaryExch  string   `json:"primary_exchange,omitempty"`
	Currency     string   `json:"currency,omitempty"`
	LocalSymbol  string   `json:"local_symbol,omitempty"`
	TradingClass string   `json:"trading_class,omitempty"`
}

TechnicalParams asks the daemon to compute weekly-screening indicators from daily bars. Symbols may be passed as a comma-separated string by the CLI or as an array by MCP after normalisation.

type TechnicalResult

type TechnicalResult struct {
	Benchmark      string         `json:"benchmark"`
	LookbackDays   int            `json:"lookback_days"`
	Market         string         `json:"market,omitempty"`
	Exchange       string         `json:"exchange,omitempty"`
	PrimaryExch    string         `json:"primary_exchange,omitempty"`
	Currency       string         `json:"currency,omitempty"`
	Rows           []TechnicalRow `json:"rows"`
	WarningDetails []DataWarning  `json:"warning_details,omitempty"`
	AsOf           time.Time      `json:"as_of"`
}

TechnicalResult is MethodTechnical's payload.

type TechnicalRow

type TechnicalRow struct {
	Symbol              string    `json:"symbol"`
	Price               *float64  `json:"price,omitempty"`
	PriceAsOf           string    `json:"price_as_of,omitempty"`
	Bars                int       `json:"bars"`
	SMA50               *float64  `json:"sma_50,omitempty"`
	SMA200              *float64  `json:"sma_200,omitempty"`
	PctAbove50DMA       *float64  `json:"pct_above_50dma,omitempty"`
	PctAbove200DMA      *float64  `json:"pct_above_200dma,omitempty"`
	Return21D           *float64  `json:"return_21d,omitempty"`
	Return63D           *float64  `json:"return_63d,omitempty"`
	Return126D          *float64  `json:"return_126d,omitempty"`
	BenchmarkReturn63D  *float64  `json:"benchmark_return_63d,omitempty"`
	BenchmarkReturn126D *float64  `json:"benchmark_return_126d,omitempty"`
	RS63D               *float64  `json:"rs_63d,omitempty"`
	RS126D              *float64  `json:"rs_126d,omitempty"`
	ATR14               *float64  `json:"atr_14,omitempty"`
	ATRPct              *float64  `json:"atr_pct,omitempty"`
	AvgVolume20D        *int64    `json:"avg_volume_20d,omitempty"`
	AvgDollarVolume20D  *float64  `json:"avg_dollar_volume_20d,omitempty"`
	LiquiditySampleDays int       `json:"liquidity_sample_days,omitempty"`
	TrendState          string    `json:"trend_state,omitempty"`
	DataQuality         string    `json:"data_quality,omitempty"` // ok | partial | insufficient_data | error
	MissingReasons      []string  `json:"missing_reasons,omitempty"`
	Error               string    `json:"error,omitempty"`
	AsOf                time.Time `json:"as_of,omitzero"`
}

TechnicalRow is one symbol's trend, relative-strength, volatility, and liquidity summary. Percentage-like fields are decimal fractions: 0.10 means +10%. RS is symbol return minus benchmark return over the same trading-bar window.

type TradeProposal

type TradeProposal struct {
	Key                string                           `json:"key"`
	Revision           string                           `json:"revision"`
	State              string                           `json:"state"`
	Bucket             string                           `json:"bucket"`
	Rank               int                              `json:"rank"`
	Symbol             string                           `json:"symbol"`
	SecType            string                           `json:"sec_type"`
	Action             string                           `json:"action"`
	Quantity           int                              `json:"quantity"`
	MaxQuantity        int                              `json:"max_quantity"`
	PositionQuantity   float64                          `json:"position_quantity"`
	PositionEffect     string                           `json:"position_effect"`
	OrderType          string                           `json:"order_type"`
	Trail              *OrderTrailSpec                  `json:"trail,omitempty"`
	TrailSizing        *TradeProposalTrailSizing        `json:"trail_sizing,omitempty"`
	ExecutionSemantics *TradeProposalExecutionSemantics `json:"execution_semantics,omitempty"`
	StopRisk           *TradeProposalStopRisk           `json:"stop_risk,omitempty"`
	StopLadder         []TradeProposalStopLadderStep    `json:"stop_ladder,omitempty"`
	TriggerMethod      int                              `json:"trigger_method,omitempty"`
	TIF                string                           `json:"tif"`
	OutsideRTH         bool                             `json:"outside_rth"`
	Contract           ContractParams                   `json:"contract"`
	Reason             string                           `json:"reason"`
	Details            []string                         `json:"details,omitempty"`
	Score              float64                          `json:"score,omitempty"`
	ThetaPerDay        float64                          `json:"theta_per_day,omitempty"`
	Notional           float64                          `json:"notional,omitempty"`
	RiskExcessNotional float64                          `json:"risk_excess_notional,omitempty"`
	RiskExcessCurrency string                           `json:"risk_excess_currency,omitempty"`
	// Base-currency twins of ThetaPerDay / RiskExcessNotional, converted
	// from the position row's FX rate at build time. Nil means the FX rate
	// was unavailable, never zero.
	ThetaPerDayBase        *float64 `json:"theta_per_day_base,omitempty"`
	RiskExcessNotionalBase *float64 `json:"risk_excess_notional_base,omitempty"`
	MarketValuePctNLV      *float64 `json:"market_value_pct_nlv,omitempty"`
	// Holding-level decision context: the full exposure being acted on, not
	// the order size. PositionMarketValue is in Contract.Currency;
	// MarketValuePctNLV is its share of net liquidation. PositionDayChange* is
	// today's P&L move on the held position (money in PositionDayChangeCurrency,
	// plus a percent) so a human can see whether the name is up or down today.
	PositionMarketValue       float64                         `json:"position_market_value,omitempty"`
	PositionDayChangeMoney    *float64                        `json:"position_day_change_money,omitempty"`
	PositionDayChangeCurrency string                          `json:"position_day_change_currency,omitempty"`
	PositionDayChangePct      *float64                        `json:"position_day_change_pct,omitempty"`
	MarketFlags               []MarketEventFlag               `json:"market_flags,omitempty"`
	LimitPrice                *float64                        `json:"limit_price,omitempty"`
	PolicyID                  string                          `json:"policy_id,omitempty"`
	PolicyVersion             int                             `json:"policy_version,omitempty"`
	PolicyFingerprint         Fingerprint                     `json:"policy_fingerprint,omitzero"`
	SourceFingerprints        TradeProposalSourceFingerprints `json:"source_fingerprints,omitzero"`
	Blockers                  []TradingBlocker                `json:"blockers,omitempty"`
	CreatedAt                 time.Time                       `json:"created_at,omitzero"`
}

TradeProposal is an advisory action bound to a key and revision. It is not a preview token or submit authorization.

type TradeProposalCounts

type TradeProposalCounts struct {
	Total                       int     `json:"total"`
	Actionable                  int     `json:"actionable"`
	ThetaHygiene                int     `json:"theta_hygiene"`
	RiskReduction               int     `json:"risk_reduction"`
	TrailingStop                int     `json:"trailing_stop"`
	MarketFlags                 int     `json:"market_flags,omitempty"`
	ThetaPerDay                 float64 `json:"theta_per_day"`
	RiskReductionExcessNotional float64 `json:"risk_reduction_excess_notional,omitempty"`
	RiskReductionExcessCurrency string  `json:"risk_reduction_excess_currency,omitempty"`
	// ThetaPerDayCurrency labels the ThetaPerDay sum. Omitted when the
	// contributing proposals span more than one contract currency — the raw
	// sum is kept for legacy renderers, but a currency label would lie.
	ThetaPerDayCurrency string `json:"theta_per_day_currency,omitempty"`
	// Base-currency twins of the money aggregates, converted per proposal
	// at build time. Nil means unavailable (some contributor lacked an FX
	// rate), never zero. BaseCurrency labels both.
	ThetaPerDayBase                 *float64 `json:"theta_per_day_base,omitempty"`
	RiskReductionExcessNotionalBase *float64 `json:"risk_reduction_excess_notional_base,omitempty"`
	BaseCurrency                    string   `json:"base_currency,omitempty"`
}

TradeProposalCounts summarizes proposals and their currency-qualified money values for the enclosing snapshot.

type TradeProposalExecutionSemantics

type TradeProposalExecutionSemantics struct {
	ReferenceSide      string    `json:"reference_side,omitempty"`
	ReferencePrice     *float64  `json:"reference_price,omitempty"`
	ReferenceAsOf      time.Time `json:"reference_as_of,omitzero"`
	TriggerMethod      int       `json:"trigger_method,omitempty"`
	TriggerMethodLabel string    `json:"trigger_method_label,omitempty"`
	TriggerSource      string    `json:"trigger_source,omitempty"`
	TriggerEffect      string    `json:"trigger_effect,omitempty"`
	PriceGuarantee     string    `json:"price_guarantee,omitempty"`
}

TradeProposalExecutionSemantics explains how a protective stop is expected to behave at the broker. It is disclosure only; broker WhatIf/order status remains authoritative for placement and lifecycle state.

type TradeProposalIgnoreParams

type TradeProposalIgnoreParams struct {
	Key      string `json:"key"`
	Revision string `json:"revision,omitempty"`
	Reason   string `json:"reason,omitempty"`
}

TradeProposalIgnoreParams dismisses an advisory revision without touching broker orders or positions.

type TradeProposalIgnoreResult

type TradeProposalIgnoreResult struct {
	Accepted bool      `json:"accepted"`
	Key      string    `json:"key"`
	Revision string    `json:"revision,omitempty"`
	Message  string    `json:"message,omitempty"`
	AsOf     time.Time `json:"as_of"`
}

TradeProposalIgnoreResult reports whether the advisory dismissal was accepted.

type TradeProposalOrderPreview

type TradeProposalOrderPreview struct {
	PreviewTokenID        string                           `json:"preview_token_id,omitempty"`
	PreviewTokenScope     string                           `json:"preview_token_scope,omitempty"`
	PreviewTokenExpiresAt time.Time                        `json:"preview_token_expires_at,omitzero"`
	TokenMinted           bool                             `json:"token_minted"`
	SubmitEligible        bool                             `json:"submit_eligible"`
	Mode                  string                           `json:"mode"`
	Account               string                           `json:"account"`
	Endpoint              string                           `json:"endpoint"`
	ClientID              int                              `json:"client_id"`
	Draft                 OrderDraft                       `json:"draft"`
	Quote                 OrderQuoteSnapshot               `json:"quote"`
	Position              OrderPositionImpact              `json:"position"`
	ExecutionSemantics    *TradeProposalExecutionSemantics `json:"execution_semantics,omitempty"`
	StopRisk              *TradeProposalStopRisk           `json:"stop_risk,omitempty"`
	Notional              float64                          `json:"notional"`
	MaxNotional           float64                          `json:"max_notional,omitempty"`
	WhatIf                OrderWhatIfResult                `json:"what_if"`
	Warnings              []DataWarning                    `json:"warnings,omitempty"`
	AsOf                  time.Time                        `json:"as_of"`
}

TradeProposalOrderPreview is the sanitized broker WhatIf and order preview. SubmitEligible is informative until the daemon revalidates at submission.

type TradeProposalPreviewParams

type TradeProposalPreviewParams struct {
	Key       string `json:"key"`
	Revision  string `json:"revision"`
	Quantity  int    `json:"quantity,omitempty"`
	TimeoutMs int    `json:"timeout_ms,omitempty"`
	FastPath  bool   `json:"fast_path,omitempty"`
}

TradeProposalPreviewParams identifies an exact candidate revision for gated broker preview.

type TradeProposalPreviewResult

type TradeProposalPreviewResult struct {
	Accepted              bool                       `json:"accepted"`
	Proposal              TradeProposal              `json:"proposal"`
	PreviewTokenID        string                     `json:"preview_token_id,omitempty"`
	PreviewTokenExpiresAt time.Time                  `json:"preview_token_expires_at,omitzero"`
	SubmitEligible        bool                       `json:"submit_eligible"`
	Preview               *TradeProposalOrderPreview `json:"preview,omitempty"`
	Blockers              []TradingBlocker           `json:"blockers,omitempty"`
	AsOf                  time.Time                  `json:"as_of"`
}

TradeProposalPreviewResult reports broker and daemon eligibility. A token ID is an audit identifier; the raw authorizing token remains private.

type TradeProposalReduceLeg

type TradeProposalReduceLeg struct {
	ConID                     int                        `json:"con_id,omitempty"`
	Symbol                    string                     `json:"symbol,omitempty"`
	SecType                   string                     `json:"sec_type,omitempty"`
	Action                    string                     `json:"action,omitempty"`
	PositionQuantity          float64                    `json:"position_quantity"`
	ReduceQuantity            int                        `json:"reduce_quantity"`
	DollarDelta               float64                    `json:"dollar_delta,omitempty"`
	RiskContributionCut       float64                    `json:"risk_contribution_cut,omitempty"`
	Notional                  float64                    `json:"notional,omitempty"`
	NotionalCurrency          string                     `json:"notional_currency,omitempty"`
	NotionalBase              *float64                   `json:"notional_base,omitempty"`
	PositionUnrealizedPnL     float64                    `json:"position_unrealized_pnl_ccy,omitempty"`
	PositionUnrealizedPnLBase *float64                   `json:"position_unrealized_pnl_base,omitempty"`
	PreviewTokenID            string                     `json:"preview_token_id,omitempty"`
	SubmitEligible            bool                       `json:"submit_eligible"`
	Preview                   *TradeProposalOrderPreview `json:"preview,omitempty"`
	Place                     *OrderPlaceResult          `json:"place,omitempty"`
	Placed                    bool                       `json:"placed,omitempty"`
	OrderRef                  string                     `json:"order_ref,omitempty"`
	Blockers                  []TradingBlocker           `json:"blockers,omitempty"`
	Message                   string                     `json:"message,omitempty"`
}

TradeProposalReduceLeg is one position's slice of a portfolio sweep. On preview it carries the sized order + per-leg eligibility; on submit it adds Place/OrderRef/Placed. DollarDelta is this leg's signed delta-adjusted exposure before the trim; RiskContributionCut is the (always positive) dollar-delta this leg's ReduceQuantity removes. PositionUnrealizedPnL(Base) is basis context only — annotation, never an input to sizing or selection. Notional is in the contract currency; NotionalBase is nil when no FX rate was available.

type TradeProposalReduceParams

type TradeProposalReduceParams struct {
	ConID         int    `json:"con_id,omitempty"`
	Symbol        string `json:"symbol,omitempty"`
	Percent       int    `json:"percent"`
	IncludeHedges bool   `json:"include_hedges,omitempty"`
	TimeoutMs     int    `json:"timeout_ms,omitempty"`
	// Origin identifies who is asking (OrderOrigin*) for audit and the
	// live-origin write gate; submit only.
	Origin string `json:"origin,omitempty"`
}

TradeProposalReduceParams is a discretionary partial reduce of an existing holding by a chosen percentage (the SPA offers 25/50/75/100). The holding is identified by ConID; Symbol is a convenience for a unique stock when ConID is unknown. SELL reduces a long; BUY-to-cover reduces a short. The percentage is resolved to an integer quantity server-side and is always clamped to the held size, so the order is close/reduce-only and can never flip or open exposure.

IncludeHedges defaults false: a holding that carries short (bearish) delta — a long put, short call, or short stock used as a protective hedge — is excluded from the reduce workflow so the user cannot accidentally trim a hedge. Set IncludeHedges true to act on such a holding deliberately.

type TradeProposalReducePortfolioParams

type TradeProposalReducePortfolioParams struct {
	Percent    int    `json:"percent"`
	TimeoutMs  int    `json:"timeout_ms,omitempty"`
	Origin     string `json:"origin,omitempty"`
	RequestRef string `json:"request_ref,omitempty"`
}

TradeProposalReducePortfolioParams is the one-tap portfolio risk-off sweep: trim positions by Percent, where Percent is the share of NET portfolio delta-adjusted risk to remove (not a flat per-position quantity cut). The daemon computes net portfolio dollar-delta, derives a target dollar amount from Percent, then sizes each contributing position proportionally to its own share of that risk. Positions whose delta is opposite-signed to net exposure (protective hedges — long puts, short calls, short stock) are never selected: trimming them would increase net risk, not reduce it, so the sign-matched ranking structurally excludes them. There is no opt-out flag because none is needed. RequestRef is a client-generated idempotency key: a repeat submit with the same ref places nothing and replays the prior result.

type TradeProposalReducePortfolioResult

type TradeProposalReducePortfolioResult struct {
	Accepted             bool                     `json:"accepted"`
	Percent              int                      `json:"percent"`
	NetDollarDeltaBefore float64                  `json:"net_dollar_delta_before,omitempty"`
	NetDeltaIncomplete   bool                     `json:"net_delta_incomplete,omitempty"`
	TargetDollarDelta    float64                  `json:"target_dollar_delta,omitempty"`
	AchievedDollarDelta  float64                  `json:"achieved_dollar_delta,omitempty"`
	AchievedPctOfTarget  *float64                 `json:"achieved_pct_of_target,omitempty"`
	Legs                 []TradeProposalReduceLeg `json:"legs"`
	LegCount             int                      `json:"leg_count"`
	EligibleCount        int                      `json:"eligible_count"`
	BlockedCount         int                      `json:"blocked_count"`
	TotalNotional        float64                  `json:"total_notional,omitempty"`
	BaseCurrency         string                   `json:"base_currency,omitempty"`
	FXIncomplete         bool                     `json:"fx_incomplete,omitempty"`
	Replayed             bool                     `json:"replayed,omitempty"`
	Blockers             []TradingBlocker         `json:"blockers,omitempty"`
	Message              string                   `json:"message,omitempty"`
	AsOf                 time.Time                `json:"as_of"`
}

TradeProposalReducePortfolioResult is the basket preview/submit envelope. Accepted means (preview) every eligible leg is submit-eligible, or (submit) at least one leg placed and none were blocked. NetDollarDeltaBefore is the signed net portfolio dollar-delta the target was derived from; NetDeltaIncomplete is true when one or more non-stale positions had no computable delta and were excluded from that sum. TargetDollarDelta is abs(NetDollarDeltaBefore)*Percent/100; AchievedDollarDelta is the sum of RiskContributionCut over legs that are eligible (preview) or placed (submit) — it can be less than TargetDollarDelta when the eligible same-sign book can't fully supply the target (disclosed via AchievedPctOfTarget, not an error). TotalNotional is the base-currency sum over eligible legs; FXIncomplete flags any eligible leg whose notional could not be converted (never fabricated). Replayed marks a dedupe hit. Basket-level Blockers (write-gate, positions_unavailable, too_many_legs, net_delta_immaterial) mean zero legs were touched.

type TradeProposalReduceResult

type TradeProposalReduceResult struct {
	Accepted              bool                       `json:"accepted"`
	ConID                 int                        `json:"con_id,omitempty"`
	Symbol                string                     `json:"symbol,omitempty"`
	SecType               string                     `json:"sec_type,omitempty"`
	Action                string                     `json:"action,omitempty"`
	Percent               int                        `json:"percent"`
	PositionQuantity      float64                    `json:"position_quantity"`
	ReduceQuantity        int                        `json:"reduce_quantity"`
	HedgeLike             bool                       `json:"hedge_like,omitempty"`
	PreviewTokenID        string                     `json:"preview_token_id,omitempty"`
	PreviewTokenExpiresAt time.Time                  `json:"preview_token_expires_at,omitzero"`
	SubmitEligible        bool                       `json:"submit_eligible"`
	Preview               *TradeProposalOrderPreview `json:"preview,omitempty"`
	Place                 *OrderPlaceResult          `json:"place,omitempty"`
	OrderRef              string                     `json:"order_ref,omitempty"`
	Blockers              []TradingBlocker           `json:"blockers,omitempty"`
	Message               string                     `json:"message,omitempty"`
	AsOf                  time.Time                  `json:"as_of"`
}

TradeProposalReduceResult is returned by both reduce_preview and reduce_submit. Preview carries the sanitized order preview (the raw token never leaves the daemon; PreviewTokenID is for audit only) and SubmitEligible. Submit additionally fills Place/OrderRef/Message. HedgeLike reports whether the resolved holding is a protective short; when true and the action was not opted into hedges, Blockers carries hedge_excluded and no token is minted.

type TradeProposalRefreshParams

type TradeProposalRefreshParams struct {
	Show bool `json:"show,omitempty"`
}

TradeProposalRefreshParams requests daemon recomputation; Show affects only the returned presentation.

type TradeProposalSnapshot

type TradeProposalSnapshot struct {
	Kind               string                          `json:"kind"`
	SchemaVersion      string                          `json:"schema_version"`
	AsOf               time.Time                       `json:"as_of"`
	Revision           string                          `json:"revision"`
	AccountID          string                          `json:"account_id,omitempty"`
	AccountMode        string                          `json:"account_mode,omitempty"`
	PolicyID           string                          `json:"policy_id,omitempty"`
	PolicyVersion      int                             `json:"policy_version,omitempty"`
	PolicyFingerprint  Fingerprint                     `json:"policy_fingerprint,omitzero"`
	PolicyStatus       ProtectionPolicyStatus          `json:"policy_status"`
	AutoTrade          AutoTradeStatus                 `json:"auto_trade"`
	Trading            TradingStatus                   `json:"trading"`
	SourceFingerprints TradeProposalSourceFingerprints `json:"source_fingerprints,omitzero"`
	MarketEvents       *MarketEventsResult             `json:"market_events,omitempty"`
	Proposals          []TradeProposal                 `json:"proposals"`
	Counts             TradeProposalCounts             `json:"counts"`
	Blockers           []TradingBlocker                `json:"blockers,omitempty"`
	LoadedFromState    bool                            `json:"loaded_from_state,omitempty"`
}

TradeProposalSnapshot is one daemon-authored, account-and-mode-scoped revision. LoadedFromState does not imply that the snapshot is fresh.

type TradeProposalSnapshotParams

type TradeProposalSnapshotParams struct {
	Show bool `json:"show,omitempty"`
}

TradeProposalSnapshotParams controls rendering of the current revision.

type TradeProposalSourceFingerprints

type TradeProposalSourceFingerprints struct {
	Account      *Fingerprint `json:"account,omitempty"`
	Positions    *Fingerprint `json:"positions,omitempty"`
	Regime       *Fingerprint `json:"regime,omitempty"`
	MarketEvents *Fingerprint `json:"market_events,omitempty"`
}

TradeProposalSourceFingerprints identifies the snapshots used to derive a proposal revision. Nil members mean that source supplied no identity.

type TradeProposalStopLadderStep

type TradeProposalStopLadderStep struct {
	Label               string   `json:"label"`
	Kind                string   `json:"kind,omitempty"`
	Percent             *float64 `json:"percent,omitempty"`
	StopPrice           *float64 `json:"stop_price,omitempty"`
	EstimatedLoss       *float64 `json:"estimated_loss_ccy,omitempty"`
	EstimatedLossBase   *float64 `json:"estimated_loss_base,omitempty"`
	EstimatedLossPctNLV *float64 `json:"estimated_loss_pct_nlv,omitempty"`
	ReferencePrice      *float64 `json:"reference_price,omitempty"`
}

TradeProposalStopLadderStep is one modeled stop-distance scenario and is not a broker fill guarantee.

type TradeProposalStopRisk

type TradeProposalStopRisk struct {
	ReferencePrice      *float64                  `json:"reference_price,omitempty"`
	StopPrice           *float64                  `json:"stop_price,omitempty"`
	Distance            *float64                  `json:"distance,omitempty"`
	DistancePct         *float64                  `json:"distance_pct,omitempty"`
	Quantity            int                       `json:"quantity,omitempty"`
	Multiplier          int                       `json:"multiplier,omitempty"`
	EstimatedLoss       *float64                  `json:"estimated_loss_ccy,omitempty"`
	Currency            string                    `json:"currency,omitempty"`
	EstimatedLossBase   *float64                  `json:"estimated_loss_base,omitempty"`
	BaseCurrency        string                    `json:"base_currency,omitempty"`
	EstimatedLossPctNLV *float64                  `json:"estimated_loss_pct_nlv,omitempty"`
	GapScenario         *TradeProposalStopRiskGap `json:"gap_scenario,omitempty"`
	WarningCodes        []string                  `json:"warning_codes,omitempty"`
}

TradeProposalStopRisk estimates the near-stop account impact from the proposal's current reference price. It is not a fill guarantee and must not be treated as a broker promise: stop orders can gap or slip.

type TradeProposalStopRiskGap

type TradeProposalStopRiskGap struct {
	Label                 string   `json:"label,omitempty"`
	GapPct                float64  `json:"gap_pct,omitempty"`
	AssumedExecutionPrice *float64 `json:"assumed_execution_price,omitempty"`
	EstimatedLoss         *float64 `json:"estimated_loss_ccy,omitempty"`
	EstimatedLossBase     *float64 `json:"estimated_loss_base,omitempty"`
	EstimatedLossPctNLV   *float64 `json:"estimated_loss_pct_nlv,omitempty"`
}

TradeProposalStopRiskGap describes one modeled gap scenario. Pointer values remain nil when the estimate is unavailable rather than meaning zero loss.

type TradeProposalSubmitParams

type TradeProposalSubmitParams struct {
	Key       string `json:"key"`
	Revision  string `json:"revision"`
	Quantity  int    `json:"quantity,omitempty"`
	FastPath  bool   `json:"fast_path,omitempty"`
	TimeoutMs int    `json:"timeout_ms,omitempty"`
	Origin    string `json:"origin,omitempty"`
}

TradeProposalSubmitParams requests gated submission of an exact revision. Origin and any earlier preview are evidence, not submit authority by themselves.

type TradeProposalSubmitResult

type TradeProposalSubmitResult struct {
	Accepted       bool                       `json:"accepted"`
	Proposal       TradeProposal              `json:"proposal"`
	Preview        *TradeProposalOrderPreview `json:"preview,omitempty"`
	Place          *OrderPlaceResult          `json:"place,omitempty"`
	PreviewTokenID string                     `json:"preview_token_id,omitempty"`
	OrderRef       string                     `json:"order_ref,omitempty"`
	Blockers       []TradingBlocker           `json:"blockers,omitempty"`
	Message        string                     `json:"message,omitempty"`
	AsOf           time.Time                  `json:"as_of"`
}

TradeProposalSubmitResult reports the outcome of a gated submission request.

type TradeProposalTrailSizing

type TradeProposalTrailSizing struct {
	Method            string    `json:"method,omitempty"`
	Version           string    `json:"version,omitempty"`
	DataQuality       string    `json:"data_quality,omitempty"`
	SelectedBy        string    `json:"selected_by,omitempty"`
	Fallback          bool      `json:"fallback,omitempty"`
	Capped            bool      `json:"capped,omitempty"`
	ReferencePrice    *float64  `json:"reference_price,omitempty"`
	ReferenceSource   string    `json:"reference_source,omitempty"`
	ReferenceAsOf     time.Time `json:"reference_as_of,omitzero"`
	PolicyMinPct      float64   `json:"policy_min_pct,omitempty"`
	PolicyDefaultPct  float64   `json:"policy_default_pct,omitempty"`
	PolicyFallbackPct float64   `json:"policy_fallback_pct,omitempty"`
	PolicyMaxPct      float64   `json:"policy_max_pct,omitempty"`
	ChosenPct         float64   `json:"chosen_pct,omitempty"`
	ChosenAmount      *float64  `json:"chosen_amount,omitempty"`
	InitialStopPrice  *float64  `json:"initial_stop_price,omitempty"`
	ATR14             *float64  `json:"atr_14,omitempty"`
	ATRPct            *float64  `json:"atr_pct,omitempty"`
	ATRMultiplier     *float64  `json:"atr_multiplier,omitempty"`
	ATRCandidatePct   *float64  `json:"atr_candidate_pct,omitempty"`
	SpreadPct         *float64  `json:"spread_pct,omitempty"`
	SpreadMultiplier  *float64  `json:"spread_multiplier,omitempty"`
	SpreadFloorPct    *float64  `json:"spread_floor_pct,omitempty"`
	MissingReasons    []string  `json:"missing_reasons,omitempty"`
	AsOf              time.Time `json:"as_of,omitzero"`
}

TradeProposalTrailSizing is the daemon-owned explanation for a protective trail. Percent fields use human units (10.0 means 10%), matching the protection policy TOML and OrderTrailSpec's broker percent convention.

type TradingBlocker

type TradingBlocker struct {
	Code    string `json:"code"`
	Message string `json:"message"`
	Action  string `json:"action,omitempty"`
}

TradingBlocker explains one local reason an order write cannot proceed.

type TradingLimitSettings

type TradingLimitSettings struct {
	MaxNotional           SettingsFloat `json:"max_notional"`
	MaxOptionContracts    SettingsInt   `json:"max_option_contracts"`
	AllowStockShort       SettingsBool  `json:"allow_stock_short"`
	AllowOptionSellToOpen SettingsBool  `json:"allow_option_sell_to_open"`
}

TradingLimitSettings reports effective safety limits with per-field access and source metadata.

type TradingPaperSmokeParams

type TradingPaperSmokeParams struct {
	// TimeoutMs caps the wait for broker acknowledgement. 0 means the
	// daemon default (30 s); values are capped daemon-side (60 s) so the
	// whole round-trip stays under the per-method deadline.
	TimeoutMs int `json:"timeout_ms,omitempty"`
	// Origin identifies who is asking (OrderOrigin*). Paper-smoke mints
	// the last live precondition, so non-human origins are refused even
	// though the order itself transmits on the paper route.
	Origin string `json:"origin,omitempty"`
}

TradingPaperSmokeParams is the input for MethodTradingPaperSmoke: a daemon-observed paper order round-trip (place a 1-share far-off-market LMT, wait for broker acknowledgement, cancel, wait for the cancel to confirm) that produces the MAC'd evidence the live gate requires.

type TradingPaperSmokeResult

type TradingPaperSmokeResult struct {
	Passed                bool          `json:"passed"`
	Result                string        `json:"result"`
	Mode                  string        `json:"mode"`
	Account               string        `json:"account,omitempty"`
	Endpoint              string        `json:"endpoint,omitempty"`
	ClientID              int           `json:"client_id,omitempty"`
	Version               string        `json:"version,omitempty"`
	Symbol                string        `json:"symbol,omitempty"`
	OrderRef              string        `json:"order_ref,omitempty"`
	ReservedOrderID       int           `json:"reserved_order_id,omitempty"`
	LimitPrice            float64       `json:"limit_price,omitempty"`
	Quantity              int           `json:"quantity,omitempty"`
	AckLifecycleStatus    string        `json:"ack_lifecycle_status,omitempty"`
	CancelLifecycleStatus string        `json:"cancel_lifecycle_status,omitempty"`
	EvidenceSaved         bool          `json:"evidence_saved"`
	EvidenceAt            *time.Time    `json:"evidence_at,omitempty"`
	EvidenceMaxAge        string        `json:"evidence_max_age,omitempty"`
	Message               string        `json:"message,omitempty"`
	Warnings              []DataWarning `json:"warnings,omitempty"`
	AsOf                  time.Time     `json:"as_of"`
}

TradingPaperSmokeResult reports the round-trip outcome. Passed means the daemon observed both the broker acknowledgement and the cancel confirmation and saved signed evidence; any other outcome after a transmit attempt saves result=failed evidence, deliberately revoking prior valid evidence (fail closed).

type TradingStatus

type TradingStatus struct {
	Mode               string           `json:"mode"`
	Endpoint           string           `json:"endpoint,omitempty"`
	GatewayHost        string           `json:"gateway_host,omitempty"`
	GatewayPort        int              `json:"gateway_port,omitempty"`
	PortOrigin         string           `json:"port_origin,omitempty"`
	Account            string           `json:"account,omitempty"`
	AccountOrigin      string           `json:"account_origin,omitempty"`
	ClientID           int              `json:"client_id,omitempty"`
	ClientIDOrigin     string           `json:"client_id_origin,omitempty"`
	MCPTrading         string           `json:"mcp_trading"`
	CanPreview         bool             `json:"can_preview"`
	CanWrite           bool             `json:"can_write"`
	WriteBlockers      []TradingBlocker `json:"write_blockers,omitempty"`
	OpenOrders         int              `json:"open_orders,omitempty"`
	LastOrderEvent     string           `json:"last_order_event,omitempty"`
	PaperSmoke         string           `json:"paper_smoke,omitempty"`
	PaperSmokeAt       *time.Time       `json:"paper_smoke_at,omitempty"`
	PaperSmokeMaxAge   string           `json:"paper_smoke_max_age,omitempty"`
	PaperSmokeAccount  string           `json:"paper_smoke_account,omitempty"`
	PaperSmokeEndpoint string           `json:"paper_smoke_endpoint,omitempty"`
	PaperSmokeClientID int              `json:"paper_smoke_client_id,omitempty"`
	PaperSmokeVersion  string           `json:"paper_smoke_version,omitempty"`
	LiveOverride       string           `json:"live_override,omitempty"`
	Blocked            bool             `json:"blocked"`
	Blockers           []TradingBlocker `json:"blockers,omitempty"`
}

TradingStatus is the local order-entry readiness surface. It is deliberately separate from broker permission: TWS / IB Gateway can still reject writes after all local gates pass.

type UnderlyingExposure

type UnderlyingExposure struct {
	Underlying        string   `json:"underlying"`
	MarketValueBase   float64  `json:"market_value_base"`
	MarketValuePctNLV *float64 `json:"market_value_pct_nlv,omitempty"`
	EffectiveDelta    *float64 `json:"effective_delta,omitempty"`
	DollarDeltaBase   *float64 `json:"dollar_delta_base,omitempty"`
	UnrealizedPnLBase *float64 `json:"unrealized_pnl_base,omitempty"`
	DailyPnLBase      *float64 `json:"daily_pnl_base,omitempty"`
	BaseCurrency      string   `json:"base_currency,omitempty"`
}

UnderlyingExposure is the compact base-currency exposure table embedded in PositionsPortfolio. Rows are sorted by absolute MarketValueBase descending so agents can read the dominant exposures without re-aggregating.

type WatchlistHolding

type WatchlistHolding struct {
	Quantity      float64  `json:"quantity"`
	AvgCost       float64  `json:"avg_cost"`
	Mark          float64  `json:"mark"`
	MarketValue   float64  `json:"market_value_ccy"`
	UnrealizedPnL float64  `json:"unrealized_pnl_ccy"`
	DailyPnL      *float64 `json:"daily_pnl_ccy,omitempty"`
	Exchange      string   `json:"exchange,omitempty"`
	Currency      string   `json:"currency,omitempty"`
}

WatchlistHolding is intentionally compact and stock-focused so watchlist refreshes can reuse the cheap `positions.list type=stk` path instead of the full option-Greeks prewarm.

type WatchlistResult

type WatchlistResult struct {
	Name    string         `json:"name"`
	Symbols []string       `json:"symbols"`
	Rows    []WatchlistRow `json:"rows"`
	AsOf    time.Time      `json:"as_of"`
}

WatchlistResult is the daemon-backed rich watchlist surface used by `canary watch --quotes --json` and MCP `canary_watch` when include_quotes is true. The persisted local watchlist remains [watchlist.Snapshot]; this type is a read-only market-data view over those saved symbols.

type WatchlistRow

type WatchlistRow struct {
	Quote
	Holding *WatchlistHolding `json:"holding,omitempty"`
	Error   string            `json:"error,omitempty"`
}

WatchlistRow flattens the Quote fields and optionally annotates a saved symbol with the user's held stock position. Error is per-row so one dead symbol does not hide the rest of a watchlist.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL