# Preferreds Portfolio Updater

> Run the daily update cycle of a rotation engine for BTC-treasury preferred stocks (STRC, STRD, SATA + cash). Use this skill whenever the user says "run an update", "update the dashboard", "add new price data", "refresh the model", provides new price screenshots for STRC/STRD/SATA, asks for today's allocation or rotation signal across preferred shares, or asks anything about the portfolio engine's coefficients, drop zones, ex-div timing, or QC status. Covers price ingestion, regression rebuild, widget refresh, the full QC battery, and snapshot persistence between sessions.

- Skill: `davidsanz21/preferreds-portfolio-updater` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add davidsanz21/preferreds-portfolio-updater`
- Raw SKILL.md: https://api.skillmd.com/api/skills/davidsanz21/preferreds-portfolio-updater/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: davidsanz21 (https://skillmd.com/u/davidsanz21)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/davidsanz21/preferreds-portfolio-updater

---


# Preferreds Portfolio Updater

This skill governs all updates to a BTC Treasury Preferred Portfolio Rotation Engine:
a quantitative system that rotates capital daily across three preferred-stock
instruments (STRC, STRD, SATA) plus cash, driven by per-instrument OLS return models,
Sharpe-ratio softmax allocation, an ex-dividend drop playbook, and a BTC power-law
cash overlay. The user is the **CEO** — the final decision-maker. Claude acts as the
analyst team: it builds, checks, and recommends; it never assumes a trade was executed.

**Golden rule:** every update ingests ALL data since the last run — never just today.
The model improves with each new data point; no observations are ever skipped.

**Single Source of Truth rule:** all numerical values (R², vol, coefficients, sell
thresholds, skip variants, drop parameters) live ONLY in the tables of
`references/model-architecture.md`. Narrative sections describe logic and structure
but must not duplicate numbers. If narrative and table disagree, the table wins.
After a regression run, update only the tables.

---

## Files in this system

| File | Canonical name | Purpose |
|---|---|---|
| `portfolio_price_database.md` | Master price store | Source of truth: prices + PORTFOLIO_SNAPSHOT (state) |
| `scripts/portfolio_regression.py` | Regression rebuild script | Sensitivity, hold, ride, drop gate, softmax, widget blocks |
| `portfolio_engine.html` | Output widget | The live dashboard — rebuilt each session from script output |
| `SKILL.md` + `references/` | This skill | Protocol, formulas, calibration tables, QC |

**File resolution:** the user's project may use versioned filenames (e.g. `*_v2_1.md`).
If a canonical name is not found, look for the highest-versioned variant. A blank
database template lives at `assets/templates/portfolio_price_database.template.md`.

At the start of each update session the user will have the latest database (and any
script changes) uploaded to the project. Read the database — including its
PORTFOLIO_SNAPSHOT — before doing anything else.

---

## Instrument reference

| | STRC | STRD | SATA |
|---|---|---|---|
| Issuer | Strategy | Strategy | Strive |
| Par | $100 | $100 | $100 |
| Div/period | $0.9583/mo | $2.50/qtr | $1.0625/mo |
| Annual rate | 11.50% variable | 10.00% fixed | 12.75% variable |
| Ex-div schedule | 15th of each month | Mar/Jun/Sep/Dec 15th | Last trading day of month (Exception: Nov 2025 → Dec 1) |
| Regression window | 30 days | 90 days → monthly | 30 days |
| IPO cutoff | Full dataset | Skip first 20 days | Skip first 30 days |
| holdSpec | simple (b0+b1·ptp+b2·dtex) | strd (…+b3·dtex²+b4·ptp·dtex) | sata (b0+b1·ptp+b2·dtex+b3·dtex²) |
| rideSpec | log (suppressed R²<0.50) | log (active) | log (active) |
| rideMaxDtex | 30d (monthly cycle) | 91d (quarterly cycle) | 30d (monthly cycle) |

Exact coefficients, R², vol, sell thresholds and drop parameters: see the tables in
`references/model-architecture.md` (single source of truth).

---

## Workflow — the seven steps

Follow `references/update-protocol.md` step by step. Overview:

1. **Read database + snapshot** — lifecycle checks L1–L3, M6 on the drop state.
2. **Fetch new data** — prices (web first, screenshots as backup) + EUR/USD rate.
   Collection rules and column layouts: `references/data-collection.md`.
3. **Append to database** (never modify existing rows) and validate (D1–D5; hard stops).
4. **Run the regression** (`scripts/portfolio_regression.py`) with current prices,
   DTEX, BTC price + quantile table, EUR/USD, and the CEO's locked skip variants.
   Post-regression checks D7, M1–M7. Then present the model comparison (Step 4b).
5. **Update the widget** — paste MODELS, T1_REFS, all nine widget defaults, and
   pre-populate positions + drop state from the snapshot. Run S/DM/O checks.
6. **Deliver, then confirm holdings** — the CEO trades (or doesn't), then types the
   confirmed positions in chat. Anti-target guard applies. Write the snapshot back
   to the database (P1–P5) and deliver the file for re-upload.
7. **Present the QC summary** — a report of everything already checked.
   Severity doctrine and the full check index: `references/qc-checklist.md`.

Model formulas, zone logic, the drop playbook, and the BTC overlay are in
`references/model-architecture.md`. Read it before touching coefficients or zones.

---

## State protocol (this skill is stateless between sessions)

Nothing persists in Claude's memory. All session state flows through one mechanism:

```
database PORTFOLIO_SNAPSHOT → read at session start → lifecycle check →
widget pre-populated → CEO adjusts & trades → CEO confirms in chat →
snapshot written back → database delivered → user re-uploads to project
```

- The snapshot holds: shares per instrument, cash EUR, B_SOLD per instrument,
  original shares, previous B%, in-drop flags, drop entry dates, T-1 refs.
- Claude cannot read the widget's live DOM. The CEO must type confirmed values.
- **Anti-target guard:** never save the model's TGT shares as the confirmed position
  unless the CEO explicitly confirms those exact trades were executed.
- The session is not complete until the updated database has been delivered for
  re-upload. Without it, the next session starts from stale state.

---

## Hard rules

- Never modify existing database rows — append only.
- `dropGate` and `rideActive` are computed outputs of every regression run, never
  hardcoded or manually overridden.
- Any 🔴 HARD STOP in QC halts delivery: the CEO must not trade on a widget that
  failed QC. Flag the failure, diagnose, fix or mark "NOT CLEARED".
- All warnings (🟡) are reported to the CEO with cause and a sign-off request.
- This system informs the CEO's decisions. It does not execute trades, and nothing
  it outputs is investment advice.

