Agent SkillsAojdevStudio/Finance-Guru › portfolio-syncing

portfolio-syncing

GitHub

同步 SnapTrade 持仓至本地数据库并校验快照,确保数据新鲜度与安全阈值,支持 Fidelity 等来源的账户更新与差异确认。

.claude/skills/PortfolioSyncing/SKILL.md AojdevStudio/Finance-Guru

Trigger Scenarios

sync portfolio update positions portfolio-sync refresh positions downloaded from Fidelity

Install

npx skills add AojdevStudio/Finance-Guru --skill portfolio-syncing -g -y
More Options

Non-standard path

npx skills add https://github.com/AojdevStudio/Finance-Guru/tree/main/.claude/skills/PortfolioSyncing -g -y

Use without installing

npx skills use AojdevStudio/Finance-Guru@portfolio-syncing

指定 Agent (Claude Code)

npx skills add AojdevStudio/Finance-Guru --skill portfolio-syncing -a claude-code -g -y

安装 repo 全部 skill

npx skills add AojdevStudio/Finance-Guru --all -g -y

预览 repo 内 skill

npx skills add AojdevStudio/Finance-Guru --list

SKILL.md

Frontmatter
{
    "name": "portfolio-syncing",
    "description": "Refresh positions and balances from SnapTrade into family_office.db, then validate the snapshot. Reads live positions, cost basis, SPAXX, and margin from the DB (never a stale CSV). USE WHEN user mentions sync portfolio OR update positions OR portfolio-sync OR refresh positions OR downloaded from Fidelity."
}

PortfolioSyncing

Refresh positions and balances from SnapTrade into family_office.db, then validate the snapshot against safety thresholds before anyone reasons off it.

family_office.db is the system of record. The Google Sheets DataHub was retired 2026-07-31; there is no spreadsheet to push to and no gdrive MCP configured.

Step 0: Refresh (sync-first, mandatory)

Positions and balances come from the local DB, refreshed FIRST so it can never be stale. Follow the shared Sync-First + DB-Read pattern.

uv run python -m src.integrations.snaptrade.sync_db          # writes positions + balances
uv run python -m src.integrations.snaptrade.sync_db --show   # read back the snapshot

Completion criterion: the positions and balances tables carry this run's synced_at. Everything downstream reads the DB, not a CSV.

To refresh positions, transactions, and bank expenses together:

uv run python -m src.integrations.refresh_all

Account Routing

config/snaptrade-accounts.yaml declares each account's role and enabled flag. An account with no declared role refuses to sync rather than guessing. Cash-management accounts belong to SimpleFIN (TransactionSyncing), not here, so brokerage margin math stays clean.

Safety Gates

⚠️ Capture the "before" state first, or these gates cannot fire. sync_db is a current-state store: it deletes each account's prior position rows and overwrites its single balances row (which is keyed on account_id). No history survives the refresh, so read the existing snapshot before running Step 0 and hold it in the session to diff against. There is no position_history table to fall back on.

# BEFORE Step 0 — capture the prior generation
sqlite3 family_office.db \
  "SELECT symbol, quantity, average_purchase_price FROM positions ORDER BY symbol;"
sqlite3 family_office.db "SELECT * FROM balances;"

STOP conditions (require user confirmation):

  1. Fewer tickers than the previous snapshot (possible sales)
  2. Any quantity change > 10%
  3. Any cost basis change > 20%
  4. Margin balance jumped > $5,000 (unintentional draw)
  5. SPAXX discrepancy > $100 against the balances row

FLAG conditions (alert but proceed): SPAXX off by $1-$100; pending activity off by more than $100.

When STOPPED: show a clear diff table, ask the user to confirm, proceed only after explicit approval.

Cash Position Logic

  • Do NOT use the SPAXX position value; it shows only settled money market.
  • Use "Settled cash" from the balances row for the SPAXX figure.
  • If settled cash is 0, SPAXX is $0 (all funds invested or in margin).
  • "Cash market value" is NOT cash; it is the value of positions held in the Cash account rather than the Margin account.

Layer Classification for New Tickers

Dividend funds → Layer 2, growth → Layer 1, hedges → Layer 3. If a new ticker does not clearly match a pattern, mark it UNKNOWN - Manual Review Required and ask the user rather than guessing.

CSV Fallback

CSV import is a fallback and re-verification path only, not the primary flow. The IngestPositions workflow archives Portfolio_Positions_*.csv and Balances_*.csv from ~/Downloads into notebooks/updates/. Use it when a live source is down or the user explicitly wants an archive.

Classifier for Fidelity position exports: a header containing Ex-date is the dividend view; a header containing Average Cost Basis is the regular view. The dividend view and transaction history CSVs are still consumed by dividend-tracking and TransactionSyncing.

Pre-Flight Checklist

  • SnapTrade account is enabled and routed in config/snaptrade-accounts.yaml
  • SNAPTRADE_* keys are present in .env
  • DATABASE_URL is set in .env

Reference Files

  • User Profile: fin-guru/data/user-profile.yaml
  • Account routing: config/snaptrade-accounts.yaml
  • Sync-first pattern: .claude/skills/_shared/SyncFirstDbRead.md

Skill Type: Domain (workflow guidance) Enforcement: BLOCK (data integrity critical) Priority: Critical

Version History

  • d13f5ab Current 2026-08-20 11:51

Same Skill Collection

.claude/skills/dividend-tracking/SKILL.md
.claude/skills/fin-core/SKILL.md
.claude/skills/fin-guru-checklist/SKILL.md
.claude/skills/fin-guru-compliance-review/SKILL.md
.claude/skills/fin-guru-create-doc/SKILL.md
.claude/skills/fin-guru-learner-profile/SKILL.md
.claude/skills/fin-guru-quant-analysis/SKILL.md
.claude/skills/fin-guru-research/SKILL.md
.claude/skills/fin-guru-strategize/SKILL.md
.claude/skills/FinanceReport/SKILL.md
.claude/skills/margin-management/SKILL.md
.claude/skills/MonteCarlo/SKILL.md
.claude/skills/retirement-syncing/SKILL.md
.claude/skills/TransactionSyncing/SKILL.md
.claude/skills/compliance-scan/SKILL.md

Metadata

Files
0
Version
d13f5ab
Hash
3facad0d
Indexed
2026-08-20 11:51

ホーム - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-21 22:06
浙ICP备14020137号-1 $お客様$