feat: dealer flow, mirror portfolio (M21), options convexity, FINRA short interest, alert producers, vendor gate
CI / Test & Type-Check (push) Canceled after 0s
CI / Test & Type-Check (push) Canceled after 0s
Snapshot of in-progress module work across multiple slices: - Dealer Flow: dealerExposureEngine, dealerMapService, dealerMapExplain, dealerMapIntegrity, dealerMapReplay, dealerStudyEngine, hanStyleLevels - Mirror Portfolio (M21): fundRepository, captureIngest, mirrorAlertProducers, fund holdings strip, live book, position capture ingest - Options: BSM, NormalizedOptionSurface types, OptionsChainRouter, ConvexityGate, option legs panel - Alert producers: vixLevel, rotation, thesis, unlock, portfolioRisk, mirror (fund_capture, fund_13f, mirror_diff) - FINRA short interest adapter + queue integration - SEC company tickers adapter + ingest (symbol search index seed) - Vendor gate (rate-limit-first data plane, ADR-0009) - CUSIP registry, reverse 13F refresh, stock float service - LRU cache, portfolio backtest engine - Frontend: dealer-flow, funds, journal, lab, monitor, plan, portfolio, reports, screener, strategies, theses, guided-start, exits, more pages - Volume profile, workspace profile, visibility-aware poll - ADRs 0010 (mirror math not advice), 0011 (symbol search index) - VENDOR_INTEGRATIONS.md, END_USER_TEST.md - .gitignore: exclude DBs, .DS_Store, local config, agent scratch
This commit is contained in:
+45
-1
@@ -6,7 +6,7 @@ This file is the ubiquitous language for the Investor Flow project. It is a glos
|
||||
|
||||
## Product
|
||||
|
||||
**Investor Flow** — A beginner-first, multi-tenant investment research terminal for retail investors with some stock experience, focused on conviction-based investing (not trading). Local-first: SPA + Bun/SQLite backend, Docker Compose deployment. Voice: convex in process, soft in presentation.
|
||||
**Investor Flow** — A multi-tenant investment **management** workbench for retail investors (positions, risk, market awareness, decision process). Helps users become better at awareness and risk management while managing - not a course/education app. Legal voice: educational publisher (ADR-0007). Local-first: Next SPA + Node/SQLite backend, Docker Compose. Voice: convex in process, soft in presentation. **Workspace density** (`focused` | `standard` | `full`) adapts nav and research detail from a short setup interview.
|
||||
|
||||
**Primary Rule — Education, not investment advice.** Investor Flow is an educational research terminal, not an investment adviser. It teaches *how a disciplined investor reasons* about a position; it never says "buy/sell/hold this." Every recommendation is a **consideration + a question**. RiskEngine `recommendedActions` are reworded (cut_to_cash → consider_reducing_position; trim_cluster → consider_rebalancing_cluster). SizingEngine outputs *math*, not instructions. Journal asks "what's your reasoning?" Alerts say "something changed," not "action needed." Every report closes with: *"Educational analysis, not investment advice. Verify the underlying data; you are responsible for your own decisions."* Legal posture: educational publisher. Formalized in ADR-0007. Every LLM prompt template and UI string reviewed against this rule ("Primary Rule lint"). When this conflicts with another principle, this wins.
|
||||
|
||||
@@ -76,6 +76,20 @@ This file is the ubiquitous language for the Investor Flow project. It is a glos
|
||||
|
||||
**Ticker Kind** — `equity` | `crypto` | `etf` | `index`. Gates which modules apply (e.g., crypto excluded from SEC/13F/insider modules). BTC kept for price/sentiment only.
|
||||
|
||||
**Symbol** — A ticker as a first-class identity (e.g., IREN). Carries a `Ticker Kind`, display name, sector/industry, exchange, and — for equities — an **Issuer CIK**. The canonical record is the `symbols` table; it is what autocomplete resolves against when a user adds a symbol to a watchlist or searches at the top.
|
||||
|
||||
**Issuer** — The company a Symbol represents (e.g., the company behind IREN). Identified by the SEC **Issuer CIK** (the company's own SEC identity — files its own 10-Ks, insider Form 4s, 13D/G). Distinct from a **Filer CIK**, which identifies a fund that files 13Fs. Same CIK identifier space, two roles: issuer = the company the symbol stands for; filer = the fund that reports holdings.
|
||||
|
||||
**Symbol Search Index** — The autocomplete corpus for adding symbols and top-bar search. Sources: the `symbols` table (issuer CIK, name, sector, ticker kind) joined with fund-holdings edges (`fund_position_records`) so a result can surface "also held by [Tracked Fund]" from the fund side. Local-first per ADR-0009: no live vendor search on the request path. **Scope: search results are symbol-only** — the fund-holdings edge is NOT shown inline in autocomplete; it surfaces on the symbol's overview page after the symbol is added.
|
||||
|
||||
**Add-Symbol Resolve Rule** — How watchlist add behaves when a typed string does/doesn't match the Symbol Search Index (hybrid): a known-symbol match adds instantly with confidence; an unmatched string is a **soft-block** — the app asks "this symbol isn't in the SEC registry — add anyway?" before adding, then hydrates metadata in the background via the adapter queue (quote, issuer CIK if findable). The row appears immediately, marked "resolving…" until hydration lands. Strictness is a question, not a wall.
|
||||
|
||||
**Fund-Holdings Strip** — The symbol-page section answering "who holds this?" Two tiers: **(1) tracked funds first** — the M21 `fund_position_records` edge, each with its weight in the fund's disclosed book (e.g., "Alpine Fox — 3.2% of book"); **(2) all institutions second** — an expandable "N other institutions report holding this (13F)" line sourced from the shared `institution_filings` cache (M4). Tier 1 is curated and deliberate; tier 2 is broad and noisy — order encodes trust.
|
||||
|
||||
**Issuer CIK Seed (company_tickers.json)** — The SEC's `company_tickers.json` bulk file (https://www.sec.gov/files/company_tickers.json) is the canonical seed for the Symbol Search Index: ~12k+ US tickers, each paired with issuer CIK, name, and exchange. SEC overwrites the file **in place daily** (start of trading day, ~5:30am ET; no historical versions). Refresh cadence = once per trading day, scheduled, never on the request path (ADR-0009 stale-while-revalidate pattern). Materialization = a scheduled queue job (`sec-company-tickers` source kind) that upserts into the `symbols` table.
|
||||
|
||||
**Symbol-Metadata Merge Policy** — Two writers on the `symbols` table, two ownership domains, no overwrite war. The SEC seed **fills** only what it's authoritative for: `cik`, `name`, `exchange`. It **never touches** yfinance-hydrated `sector`, `industry`, `peers` (absent from the SEC file), and **never downgrades** an existing `ticker_kind` (etf/crypto/index preserved — kind gates module applicability). Rows absent from the SEC file (crypto, some ETFs, indexes) are **never purged** — the SEC universe is a subset, not the whole. Background hydration (Q1) owns classification/descriptive metadata; the SEC seed owns issuer identity.
|
||||
|
||||
## Screener (two modules)
|
||||
|
||||
**Filter Screener (M15a)** — A TradingView/Finviz-style screener: user writes ad-hoc filter expressions (descriptive, technical, fundamental, events, ownership, sentiment) over a universe; outputs matching symbols with "why matched." Beginner-immediate. No Strategy required. Saved filter sets are per-user (Tier C). Not backtested. Universe: tiered (watchlist first, opt-in broader scan scoped by sector).
|
||||
@@ -100,6 +114,36 @@ Screener output policy (both modules): symbol + "why matched" + one-tap "open in
|
||||
|
||||
**IV Regime Gate (within M17)** — Modulates allowed overlays by IV Percentile: covered calls when IV high (juicy premium); protective puts / LEAPS when IV low (cheap insurance). Never buy convexity when it's expensive.
|
||||
|
||||
## Mirror Portfolio (M21)
|
||||
|
||||
**Tracked Fund** — A specific fund (e.g., Alpine Fox LLC) the operator follows fund-first: the inverse of the symbol-first Institutional module. Identified by CIK for SEC data (13F) and by the manager's X handle(s) for the live channel. The fund and the person are distinct entities: the 13F is filed by the fund (CIK); X posts come from the manager. Two channels, two authorities, two latencies — official but stale (13F) vs live but self-reported (X).
|
||||
|
||||
**13F Record** — A single SEC-confirmed holding row for a tracked fund: CIK, symbol, shares, market value, reported quarter. Quarterly + ~45-day filing lag; *as of* the quarter end. Shows drift, not decision. Reuses the shared `institution_filings` cache (ADR-0004). _Avoid_: holding (ambiguous across channels).
|
||||
|
||||
**Position Capture** — A self-reported snapshot of the fund's *current total position* in one ticker, with actual numbers: total shares, market value, and **cost basis**. Posted by the manager on X (typically as a screenshot); recorded with post date + evidence link (tweet URL). Dated state on the position's timeline — it supersedes earlier captures for the current view but never overwrites history. _Avoid_: screenshot (implementation detail), position update (ambiguous).
|
||||
|
||||
**Trade Claim** — An X post stating a position *delta* with real numbers ("added n shares at x average price"). Supplementary color, never authoritative state; recorded as a dated delta that should reconcile with the next Position Capture (prev total + delta ≈ new total; avg-cost math must close).
|
||||
|
||||
**Cost Basis** — The average cost per share shown in a Position Capture. The decision-level measure (what the manager deployed), contrasted with market value which is drift. What makes a fund's *construction* readable through captures and invisible in 13Fs alone.
|
||||
|
||||
**Live Book** — The current-state view of a Tracked Fund's holdings: the most recent record per position, mixing 13F Records and Position Captures, each labeled with its source and as-of date. "Estimated/live" for captures, "SEC-confirmed (quarter-end)" for 13F.
|
||||
|
||||
**X Post Classes (fund feed)** — Every manager post splits into exactly two classes: **Position Captures / Trade Claims** (actual numbers → become records) and **commentary** (thesis talk, macro takes, no numbers → never a record, no matter how strongly worded). Classification is per-post; the app already LLM-classifies posts (sentiment) so there's a precedent.
|
||||
|
||||
**Disclosed Book** — The fund's visible holdings: 13F Records + Position Captures. Weights are computed over the disclosed book only — cash, hedges, and non-disclosed assets are unknown and labeled as such. _Avoid_: portfolio (implies the whole fund, which we can't see).
|
||||
|
||||
**Mirror Portfolio** — The module's core job: the user's stated goal of replicating a Tracked Fund's book. The target = the fund's Disclosed Book expressed as weights; applied to the user's own equity it answers what to buy, when (the X edge: captures are live, 13F lags ~45 days), and how many shares to match each weight. Per-user math over shared fund data; never advice (ADR-0007 line: "to match this weight, buy N shares" is a calculation for a user-stated goal, not a recommendation). Whole-book scope: the mirror converges the user's entire portfolio to the fund's weights, scaled to a user-entered capital base (suggested default ~$200k; accepts ~$20k accounts). The fund's AUM never enters the math — only the user's base does.
|
||||
|
||||
**Mirror Floor** — The minimum position threshold in the Practical Mirror: positions below ~$500 or ~0.5% weight (whichever is larger) are excluded from the mirror and reported as one "excluded (below minimum)" line. Fractional shares allowed but rounded to a sensible tick. The floor is a setup choice, shown honestly.
|
||||
|
||||
**Mirror Target Rule** — The mirror's target per position = the most recent record by as-of date, regardless of source. A Feb capture beats a Dec 31 13F; a Mar 31 13F beats a Feb capture. Captures and 13F Records compete on recency, not authority (no badges, no verdicts — option 2 reconciliation).
|
||||
|
||||
**Mirror Diff** — The delta between the fund's current target weights and the user's current holdings, recomputed on every new 13F Record or Position Capture. The "what to trade to stay matched" view: position, weight change, shares to buy/sell.
|
||||
|
||||
**Fund Performance (mirror)** — The disclosed book marked to market (equity curve, estimated from disclosed holdings) plus position-level unrealized P&L vs Cost Basis from captures. Dataroma-style returns with the unique cost-basis anchor nobody else has. Always labeled "estimated from disclosed holdings."
|
||||
|
||||
**Manager Insider Activity** — Form 4 transactions filed by the manager personally (as officer/director/10% holder), cross-referenced by insider_name against the shared `insider_transactions` cache. Surfaced on the fund page as a conviction-context strip ("fund holds IREN; manager is a director; latest Form 4: informed buy"), alongside 13D/13G events by the fund's CIK. **Never part of the Disclosed Book and never moves the mirror** — the fund's book changes only on fund records (13F Records, Position Captures); the manager's personal account is not the fund's book.
|
||||
|
||||
## Macro Module (M18)
|
||||
|
||||
**Macro Module (M18)** — Fourth pillar module: calendar of high-impact macro events (M18a), current-regime classifier (M18b), portfolio-impact commentary (M18c), and regime history (M18d). The Druckenmiller 25% lens given dedicated surface. Reads macro + connects to portfolio; never recommends a macro trade (the Alfred caution extends to macro-trading). Leaves action to Conviction Tier + Convexity Posture gates.
|
||||
|
||||
Reference in New Issue
Block a user