协作头脑风暴
brainstorming
在实现前澄清需求、探索设计选择,并形成清晰的开发方向。
equity-trading-compliance【开发与工程】Use when checking whether a US equity day trade is permitted, counting day trades, or handling trader tax mechanics — per-account broker-regime detection (legacy PDT vs FINRA risk-based intraday margin, transition window through 2027-10-20), day-trade counting and round-trip identification with broker reconciliation, the day_trade_permitted pre-trade…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
This skill is the KNOWLEDGE OWNER for the US-equity day-trading regulatory and
tax domain: broker day-trade regimes, day-trade counting, the pre-trade guard,
wash sales, the §475(f) election, short-sale rules, and cost-basis
reconciliation. It defines the canonical day_trade_permitted(...) guard;
the enforcement point for that guard lives in trading-risk-management
(the KillSwitch calls it), and order-time regulatory marking lives in
equity-broker-execution. One gate, one knowledge owner.
Educational reference — NOT tax or legal advice. Elections, filings, and account setup belong to the user and their tax professional. This skill explains what the rules ARE and how to compute against them; it does not file anything on the user's behalf.
Routing:
trading-risk-management
(this skill registers its guard there — see the shared contract at
references/guard-contract.md).equity-broker-execution (§7 here owns what the rules ARE; that skill owns
order-time enforcement).trade-journaling-and-review; this skill CONSUMES it for §8 tax views.The day-trade regime is a runtime fact, detected per (broker, account_id, account_type, policy_version) — never a global constant and never a hardcoded rule. Two regimes coexist during the transition:
order_intent (§4).FINRA's rules grant implementation flexibility to member FIRMS — they do NOT contain an express account-by-account migration authorization. Treat per-account regime variation as a defensive engineering assumption (broker policies may in practice differ across accounts, and cash / Reg-T margin / portfolio-margin accounts differ), not a regulatory citation. Detect at the account granularity, never cache at broker/firm level.
Detection sources, in preference order:
Revalidate at session start, before an exposure-increasing order after any staleness interval, and on broker notices / changed account fields — not merely at a window close.
TW-3 — fail closed for NEW exposure, never for exits. When the regime cannot be reliably detected, the guard fails closed for exposure-INCREASING orders (rejects; never guesses) and NEVER blocks exposure-reducing or liquidation-only orders. "Closed" means no new risk, not trapped in a position.
Regulatory anchors: new FINRA rules effective 2026-06-04 (SEC approval order 34-105226); brokers may retain legacy PDT through 2027-10-20.
Broker-authoritative reconciliation (binding). Broker-provided PDT status,
day-trade counts, and order-preview / margin endpoints are AUTHORITATIVE
where available. Local counting is an explainability / reconciliation
layer, never the decision source of record. Example broker fields: Alpaca
pattern_day_trader / daytrade_count / daytrading_buying_power; Schwab and
IBKR expose day-trade counts and preview/margin endpoints.
This skill DEFINES exactly ONE canonical signature. The full input/output
contract and the shared conformance checklist live at
references/guard-contract.md, which is pointed
at by BOTH this skill and trading-risk-management's registration section.
Drift between the two = reopen.
from dataclasses import dataclass
@dataclass
class Verdict:
verdict: str # "permit" | "reject_fail_closed" | "liquidation_only"
reason_code: str
evidence_source: str
evidence_freshness: str
policy_version: str
def day_trade_permitted(order_intent, account_snapshot,
broker_policy_snapshot, as_of) -> Verdict:
"""Canonical pre-trade day-trade guard. Pure decision function.
order_intent carries symbol/side/quantity/order_type/session AND
order_intent.exposure in {"increase", "neutral", "reduce"}.
Returns a STRUCTURED Verdict — never a bare boolean.
"""
reducing = order_intent.exposure in ("reduce", "neutral")
# Exits and cancels are NEVER blocked by an unknown/stale regime.
if broker_policy_snapshot.regime == "unknown":
if reducing:
return Verdict("liquidation_only", "regime_unknown_exit_ok",
broker_policy_snapshot.evidence_source,
broker_policy_snapshot.evidence_as_of,
broker_policy_snapshot.policy_version)
# Exposure-INCREASING order with an unknown regime -> fail closed.
return Verdict("reject_fail_closed", "regime_unknown",
broker_policy_snapshot.evidence_source,
broker_policy_snapshot.evidence_as_of,
broker_policy_snapshot.policy_version)
# Broker-authoritative count is the source of record where present.
broker_count = getattr(account_snapshot, "day_trade_count", None)
if (order_intent.exposure == "increase"
and broker_count is not None
and account_snapshot.would_exceed_day_trade_limit(order_intent)):
return Verdict("reject_fail_closed", "pdt_would_exceed",
"broker_api", broker_policy_snapshot.evidence_as_of,
broker_policy_snapshot.policy_version)
return Verdict("permit", "permitted", broker_policy_snapshot.evidence_source,
broker_policy_snapshot.evidence_as_of,
broker_policy_snapshot.policy_version)
The verdict is structured — permit | reject_fail_closed | liquidation_only with reason code, evidence source, evidence freshness, and
policy version. Never a bare boolean. reject_fail_closed is reachable
ONLY for exposure == "increase"; a reducing order can only return permit
or liquidation_only.
Primary source: IRS Publication 550.
Primary source: IRS Topic 429 (traders in securities).
This section owns what the rules ARE; equity-broker-execution owns order-time
enforcement.
Reconcile the broker-reported 1099-B against the canonical ledger (schema owned
by trade-journaling-and-review §2, consumed here). Reconcile wash-sale
adjustments, corrections/busts, and common mismatch causes (broker vs local
lot selection, corporate actions, wash-sale basis add-backs). The ledger is
the explainability layer; the 1099-B is the filing artifact.
FRESHNESS:v1
date_gated_review: 2027-10-20 # FINRA transition window close — re-verify regime rules
event_triggers:
- session_start
- staleness_interval_before_exposure_increase
- broker_notice_or_changed_account_field
Re-verify the regime rules on the date gate AND on every event trigger — the regime is not a set-and-forget constant. Primary sources to re-check: FINRA transition guidance, SEC approval order 34-105226, IRS Pub 550, IRS Topic 429.
| Anti-Pattern | Why It Fails | Correct Approach |
|---|---|---|
| Hardcoding the "sub-$25k / 4-in-5" PDT constant | The regime is a per-account runtime fact now spanning legacy PDT AND risk-based intraday margin | Detect the regime per (broker, account_id, account_type, policy_version); branch on it |
| Caching the regime at broker/firm level | FINRA permits per-account migration; one firm runs both regimes | Cache (if at all) at account granularity; revalidate on the §2 triggers |
| Duplicating the guard in two skills | The signature silently rots and the two gates disagree | One canonical signature here; trading-risk-management registers, never restates (references/guard-contract.md) |
| Returning a bare boolean verdict | Callers cannot distinguish "no new risk" from "close everything" or see the evidence | Return the structured Verdict (permit / reject_fail_closed / liquidation_only) with reason + evidence |
| Fail-OPEN on an unknown regime | Guessing "probably fine" places unpermitted risk | Fail closed for exposure-increasing orders on any unknown/stale input |
| Fail-CLOSED applied to liquidation | Blocking exits traps the account in a losing position | Reducing orders and cancels are never rejected; unknown/halt states resolve to liquidation_only |
| Local count overriding the broker verdict | The broker is the source of record; local drift causes false permits/rejects | Broker counts/previews are authoritative; local counting only explains/reconciles |
| Treating wash-sale as a year-end-only concern | Intraday re-entries create wash sales continuously; basis is wrong all year | Track the 61-day window per lot as trades happen; flag partial and cross-account cases |
| Writing in a tax-advice voice | This is educational reference; elections/filings are the user's and their pro's | Explain the rules; defer elections, filings, and account setup to the user's tax professional |