| name | portfolio |
| description | Gestisce il Portfolio Intelligence Dashboard 140 Grammi (VPS ~/Portfolio-Claude-Code / GitHub Pages). Usare SEMPRE per: "aggiorna portfolio", "aggiorna insider", "aggiorna dashboard", "aggiorna segnali", "aggiorna news", "aggiorna geopolitica", "aggiorna report intelligence", "aggiungi transazione", "log trade", "check insider", "portfolio status", "/portfolio". Sa: struttura completa VPS, come aggiornare TUTTI i contenuti del sito (data.js, intelligence-reports.js, GEOPOLITICAL_RISKS, NEWS_DB, MARKET_DATA), gestione git con VPS auto-commits, push su GitHub Pages, calcolo P&L reale, insider data SEC/OpenInsider.
|
Portfolio Intelligence Skill โ VPS Edition
Dashboard di investimento personale su GitHub Pages. Leggi tutto prima di agire.
Repo e Paths
VPS: ~/Portfolio-Claude-Code/ โ repo git principale
GitHub Pages: https://andytrust.github.io/Portfolio-Claude-Code/
Dashboard: Protfolio.html (typo intenzionale)
Struttura file JS โ cosa aggiornare e dove
js/
โโโ data.js โ MARKET_DATA + NEWS_DB + GEOPOLITICAL_RISKS + segnali stock
โโโ intelligence-reports.js โ Array INTELLIGENCE_REPORTS (report giornalieri markdown)
โโโ app.js โ _syncLiveData() โ carica JSON live e aggiorna timestamp
โโโ render-geopolitica.js โ legge GEOPOLITICAL_RISKS da data.js
โโโ render-reports.js โ legge INTELLIGENCE_REPORTS, mostra "Live: YYYY-MM-DD"
โโโ render-intelligence.js โ legge MARKET_DATA + NEWS_DB
โโโ render-money-follow.js โ legge insider_data.json live
data/
โโโ market_data.json โ prezzi live (aggiornato ogni ora VPS, struttura: {indices:[{symbol,name,price,value,change,direction}]})
โโโ insider_data.json โ Form 4 + convergenza (ogni 3gg VPS)
โโโ portfolio_pnl.json โ P&L snapshot (ogni ora VPS, struttura: {positions:{TSLA:{current_price,...}}, summary:{}})
โโโ geopolitical_data.json โ news geo/social (ogni ora VPS, struttura: {items:[...]})
Stock monitorati
6 POSIZIONI REALI:
| Ticker | Azioni | PMC | Costo totale |
|---|
| TSLA | 2.018 az | ~$405 medio | $818.55 (T001+T008) |
| BLK | 0.220 az | $1,137.32 | $250.00 |
| TEM | 3.022 az | $42.36 | $128.00 |
| ACHR | 28.285 az | $5.48 | $155.00 |
| CRSP | 4.018 az | $51.27 | $206.00 |
| CRWV | 1.000 az | $118.48 | $118.50 |
Investito totale: $1,676.05
10 WATCHLIST: NVDA, AVGO, MU, ASML, LLY, NVO, XOM, NEE, DLR, EQIX
PROCEDURA AGGIORNAMENTO COMPLETO (usa questa ogni sessione)
Step 1 โ Leggi i dati live dai JSON VPS
import json
with open('data/market_data.json') as f: mkt = json.load(f)
for idx in mkt['indices']:
print(f"{idx['name']}: {idx['value']} ({idx['change']})")
print("lastUpdated:", mkt['lastUpdated'])
with open('data/portfolio_pnl.json') as f: pnl = json.load(f)
positions = pnl['positions']
PMC = {'TSLA':444.55+374.00, 'BLK':250.00, 'TEM':128.00, 'ACHR':155.00, 'CRSP':206.00, 'CRWV':118.50}
SHARES = {'TSLA':2.018, 'BLK':0.220, 'TEM':3.022, 'ACHR':28.285, 'CRSP':4.018, 'CRWV':1.000}
for t,shares in SHARES.items():
price = positions.get(t, {}).get('current_price', 0)
value = shares * price
pnl_usd = value - PMC[t]
pnl_pct = (pnl_usd/PMC[t])*100
print(f"{t}: ${price:.2f} | P&L: ${pnl_usd:.2f} ({pnl_pct:.1f}%)")
with open('data/insider_data.json') as f: ins = json.load(f)
conv = ins.get('convergence', {})
print("StrongBuy:", conv.get('strongBuy'))
print("StrongSell:", conv.get('strongSell'))
for tx in ins.get('transactions', [])[:10]:
print(f" {tx.get('date')} {tx.get('ticker')} {tx.get('insider_name','?')} {tx.get('transaction_type','?')} qty:{tx.get('qty','?')} @${tx.get('price','?')}")
Step 2 โ Aggiorna i segnali in js/data.js
Per ogni ticker aggiorna:
signal: "ACCUMULO" | "MISTO" | "DISTRIBUZIONE" | "SPECULATIVO"
signalColor: "green" | "yellow" | "red"
lastUpdated: data odierna ("DD/MM/YYYY")
description: aggiorna con news recenti
insider[]: aggiungi transazioni reali verificate
Aggiorna tutti i lastUpdated in bulk:
sed -i 's/lastUpdated: "25\/04\/2026"/lastUpdated: "DD\/MM\/YYYY"/g' js/data.js
Regole segnali basate su insider:
- CEO/CFO compra open market โ ACCUMULO (segnale forte)
- CEO/major shareholder vende open market (non 10b5-1) โ DISTRIBUZIONE o MISTO
- Vendita 10b5-1 pianificata โ non cambia segnale
- Multipli insider vendono simultaneamente โ DISTRIBUZIONE
Step 3 โ Aggiorna MARKET_DATA in js/data.js
const MARKET_DATA = {
indices: [
{name:"S&P 500",value:"$711.69",change:"-0.49%",direction:"down"},
{name:"NASDAQ",value:"$657.55",change:"-1.01%",direction:"down"},
{name:"VIX",value:"$17.90",change:"+0.39%",direction:"up"},
{name:"EUR/USD",value:"$1.171",change:"+0.3%",direction:"up"},
{name:"Oil WTI",value:"$139.60",change:"+3.62%",direction:"up"},
{name:"Gold",value:"$421.91",change:"-0.5%",direction:"down"},
{name:"BTC",value:"$77.034",change:"-1.2%",direction:"down"},
{name:"US 10Y",value:"$86.37",change:"-0.1%",direction:"down"},
{name:"FOMC",value:"HOLD",change:"29 apr โ tassi invariati",direction:"up"},
{name:"Sentiment",value:"RISK-ON",change:"descrizione breve",direction:"up"},
],
sentiment: "RISK-ON BULLISH โ descrizione sentiment del giorno",
lastUpdated: "YYYY-MM-DDTHH:MM:SSZ"
};
NOTA: _syncLiveData() in app.js sostituisce MARKET_DATA.indices con il JSON live.
Il fallback hardcoded in data.js serve solo prima del fetch. Il lastUpdated ISO รจ quello mostrato nel badge.
Step 4 โ Aggiorna GEOPOLITICAL_RISKS in js/data.js
const GEOPOLITICAL_RISKS = [
{
name: "Nome Rischio โ Subtitle",
severity: 9,
probability: 75,
sectors: ["Energia โฒโฒ", "Tech โผ", "Trasporto โผโผ"],
detail: "Descrizione aggiornata con dati di oggi. Citare numeri reali.",
impact: "XOM: +X%. NVDA: -Y%. Impatto specifico per titolo."
},
];
Regola: Aggiorna detail e probability con notizie di oggi. Il renderer mostra esattamente GEOPOLITICAL_RISKS.length + " rischi monitorati".
Step 5 โ Aggiorna NEWS_DB in js/data.js
const NEWS_DB = [
{
id: 30,
date: "29/04/2026",
title: "Titolo notizia",
source: "Bloomberg|Reuters|SEC Form 4|Federal Reserve|...",
category: "macro|geopolitica|insider|sector",
impact: "alto|medio|basso",
tickers: ["TSLA","BLK"],
impactType: "positivo-broad|negativo-insider|positivo-energia|...",
body: "Descrizione della notizia...",
analysis: "Analisi dell'impatto sul portfolio...",
actions: "Azione consigliata..."
},
];
Step 6 โ Aggiorna intelligence-reports.js con report di oggi
import json
with open('reports/intelligence_YYYYMMDD.md') as f:
raw_content = f.read()
with open('js/intelligence-reports.js', 'r') as f:
content = f.read()
new_entry = ',\n ' + json.dumps({"date": "YYYY-MM-DD", "raw": raw_content}, ensure_ascii=False)
new_content = content.replace('\n];', new_entry + '\n];')
with open('js/intelligence-reports.js', 'w') as f:
f.write(new_content)
import re
dates = re.findall(r'"date": "\d{4}-\d{2}-\d{2}"', new_content)
print("Date presenti:", sorted(set(dates)))
Il report markdown DEVE avere questa sezione per i segnali:
## ๐ Riepilogo Segnali
| Ticker | Prezzo | Segnale | Conviction |
|--------|--------|---------|------------|
| TSLA | $376.02 | ๐ก MISTO | โญโญ |
| BLK | $1,049.76 | ๐ก MISTO | โญโญ |
...
NON mettere P&L come prezzo โ il renderer renderReportSignalSummary() mostra cols[1] come prezzo nella card. Usa il prezzo corrente del titolo.
Step 7 โ Syntax check e push
node --check js/data.js && echo "data.js OK"
node --check js/intelligence-reports.js && echo "intelligence-reports.js OK"
Push con gestione VPS auto-commits:
Il VPS fa auto-commit ogni :30 su data/*.json e reports/*.md. Se il push viene rifiutato:
git stash
export GIT_SSH_COMMAND="ssh -i ~/.ssh/id_portfolio -o StrictHostKeyChecking=no"
git fetch origin main
git reset --soft origin/main
git restore --staged data/portfolio_trades.json scripts/crontab_vps.txt scripts/telegram_bot.py 2>/dev/null
git status --short | grep '^[MARD]'
git stash pop
git commit -m "messaggio"
git push origin main
File DA COMMITTARE: js/data.js, js/intelligence-reports.js, reports/intelligence_*.md, data/market_data.json, data/insider_data.json, data/portfolio_pnl.json, data/geopolitical_data.json
File MAI da committare: data/portfolio_trades.json, .env, data/real-trades.json
Aggiornamento segnali stock in data.js โ struttura entry
TICKER: {
price: 376.02,
change: -2.65,
range52w: "$290 โ $490",
pe: 75.4,
fwdPe: 50.0,
evEbitda: 60.0,
marketCap: "$760 Mld",
eps: "$4,99",
dividend: "โ",
beta: 2.30,
sector: "EV / Autonomous / AI",
exchange: "NASDAQ",
currency: "USD",
description: "Aggiornato con news recenti. Citare eventi specifici (earnings, partnership, ecc.)",
signal: "ACCUMULO",
signalColor: "green",
lastUpdated: "29/04/2026",
buyers: [...],
sellers: [...],
insider: [
{
date: "2026-04-22",
name: "David Ricks",
role: "CEO",
action: "ACQUISTO",
shares: 5000,
price: 820.00,
value: "$4,1M",
note: "Acquisto open market. Segnale forte..."
}
],
targets: {low:700, avg:1050, high:1350, analysts:20, consensus:"BUY", consensusScore:85},
technicals: {support:[340,310], resistance:[400,430], sma50:360, sma200:350, rsi:45, macd:"Neutral", volume:"80M", trend:"Laterale"}
}
Come aggiornare Insider Data (OpenInsider + SEC Form 4)
URL OpenInsider per singolo ticker:
http://openinsider.com/search?q=TICKER
Screener globale (730 giorni, tutti i tipi):
http://openinsider.com/screener?s=TICKER&fd=730&xp=1&xs=1&xf=1&xm=1&xx=1&cnt=100
SEC EDGAR Form 4 (ultimi N giorni):
https://efts.sec.gov/LATEST/search-index?q=%22TICKER%22&forms=4&dateRange=custom&startdt=YYYY-MM-DD&enddt=YYYY-MM-DD
Regole dati insider:
- Non inventare mai dati insider. Solo da OpenInsider/SEC verificati.
- OPEN MARKET = segnale forte (discrezionale)
- 10b5-1 = pianificato, meno segnaletico
- CEO/CFO compra = ACCUMULO forte
- CEO/major shareholder vende open market = DISTRIBUZIONE o downgrade
Come leggere P&L reale (portfolio_pnl.json ha struttura dict non list)
import json
with open('data/portfolio_pnl.json') as f: pnl = json.load(f)
positions = pnl['positions']
for ticker, pos in positions.items():
print(f"{ticker}: ${pos.get('current_price', 0)}")
Script VPS โ comandi operativi
cd ~/Portfolio-Claude-Code
source ~/portfolio_venv/bin/activate
python3 scripts/vps_hourly_monitor.py
python3 scripts/vps_social_geo_monitor.py
python3 scripts/fetch_all_daily.py
bash scripts/vps_git_deploy.sh
export GIT_SSH_COMMAND="ssh -i ~/.ssh/id_portfolio -o StrictHostKeyChecking=no"
git add js/data.js js/intelligence-reports.js
git commit -m "messaggio"
git push origin main
Fonti dati primarie
| Fonte | URL | Cosa fornisce |
|---|
| OpenInsider | http://openinsider.com/search?q=TICKER | Form 4 per ticker |
| SEC EDGAR Form 4 | https://efts.sec.gov/LATEST/search-index?q=%22TICKER%22&forms=4 | Filing ufficiali |
| SEC EDGAR RSS | https://data.sec.gov/rss?cik=CIK&count=40 | Feed real-time |
| WhaleWisdom | https://whalewisdom.com | 13F fondi |
| Capitol Trades | https://www.capitoltrades.com/trades | STOCK Act politici |
| YFinance (VPS) | via vps_hourly_monitor.py | Prezzi live ogni ora |
Checklist aggiornamento completo (copia-incolla ogni sessione)
[ ] 1. Leggi market_data.json โ prezzi correnti
[ ] 2. Leggi portfolio_pnl.json โ P&L posizioni
[ ] 3. Leggi insider_data.json โ transazioni recenti + convergenza
[ ] 4. Aggiorna segnali ticker in js/data.js (signal, signalColor, description, insider[])
[ ] 5. Aggiorna lastUpdated di tutti i ticker โ sed bulk
[ ] 6. Aggiorna MARKET_DATA.indices con prezzi di oggi
[ ] 7. Aggiorna GEOPOLITICAL_RISKS con eventi macro recenti
[ ] 8. Aggiungi NEWS_DB entries per oggi (id incrementale, date italiane)
[ ] 9. Genera/aggiorna report markdown in reports/intelligence_YYYYMMDD.md
- Tabella "Riepilogo Segnali" con PREZZI REALI (non P&L!)
- Sezione Portfolio P&L con calcoli corretti
- Alert insider recenti
[ ] 10. Aggiungi report a js/intelligence-reports.js (Python script)
[ ] 11. node --check js/data.js && node --check js/intelligence-reports.js
[ ] 12. git add js/data.js js/intelligence-reports.js reports/intelligence_YYYYMMDD.md
[ ] 13. git commit + push (usa strategia soft-reset se rejected)
[ ] 14. Attendi ~2 min e verifica su GitHub Pages
Errori comuni da evitare
- P&L come prezzo nella tabella Riepilogo Segnali โ mostra "$-8,739" invece di "$1,049.76". Il renderer legge
cols[1] dalla tabella MD.
portfolio_pnl.json positions รจ un dict, non una lista โ for ticker, pos in positions.items()
- Push rejected โ VPS auto-commit ogni :30. Usa
git reset --soft origin/main (non rebase).
- intelligence-reports.js: file enorme โ Non aprire con Read, usa grep/python per modifiche.
- lastUpdated non aggiornati โ usa
sed -i bulk per aggiornare tutte le date in data.js.
- GEOPOLITICAL_RISKS hardcoded โ Il renderer legge l'array JS, non il JSON. Aggiorna data.js.
- NEWS_DB รจ hardcoded โ Stesso: aggiorna in data.js, non nei JSON VPS.