// Variation 1: Classic Bloomberg Terminal
// Orange-on-black, 4-panel grid, tab bar, function-key legend
(() => {
const { useState, useMemo, useEffect, useRef } = React;
const { BlinkDot, Bar, fmt, useNow, clockStr, dateStr } = window;
const D = window.TAM_DATA;
// ═══ THEME ═══
const theme = {
bg: '#0a0a0a',
panel: '#0f0f0f',
panelAlt: '#141410',
border: '#2a2a1a',
text: '#e8c468',
textDim: '#8a7a3e',
textMute: '#5a4e28',
accent: '#ff9933',
accentBright: '#ffb84d',
green: '#6ee26e',
red: '#ff5c5c',
blue: '#6aaaff',
cyan: '#5ce6e6',
magenta: '#e66ae6',
headerBg: '#ff9933',
headerText: '#000',
};
// ═══ COINGECKO LIVE PRICES ═══
function useCoinGecko() {
const [live, setLive] = useState(null);
const [lastUpdate, setLastUpdate] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
const ids = D.positions.map(p => p.coingeckoId).join(',');
const url = `https://api.coingecko.com/api/v3/simple/price?ids=${ids}&vs_currencies=usd&include_24hr_change=true`;
const fetchPrices = () => {
fetch(url)
.then(r => {
if (!r.ok) throw new Error(`HTTP ${r.status}`);
return r.json();
})
.then(data => { setLive(data); setLastUpdate(new Date()); setError(null); })
.catch(e => { setError(e.message); });
};
fetchPrices();
const id = setInterval(fetchPrices, 60_000);
return () => clearInterval(id);
}, []);
const getPrice = (pos) => {
if (!live || !live[pos.coingeckoId]) return { price: pos.price, change24h: pos.change24h };
return {
price: live[pos.coingeckoId].usd,
change24h: live[pos.coingeckoId].usd_24h_change,
};
};
return { live, lastUpdate, error, getPrice };
}
// ═══ HEADER ═══
function Header({ tab, setTab, tabs }) {
const now = useNow();
return (
◆ TAM · TRADING AGENT MAREK
{tabs.map((t, i) => (
))}
CRYPTO 24/7
{clockStr(now)} UTC
{dateStr(now)}
);
}
// ═══ FOOTER / STATUS BAR ═══
function StatusBar({ coinError, lastUpdate }) {
return (
ALPACA PAPER
COINGECKO
{coinError
? {coinError.slice(0, 20)}
: lastUpdate
? {clockStr(lastUpdate)}
: CONNECTING
}
GITHUB PUSHED
ALLOW_LIVE=FALSE
OPUS 4.7
UPTIME 14D 12H
);
}
// ═══ PANEL WRAPPER ═══
function Panel({ title, children, actions, style, flex = 1 }) {
return (
);
}
// ═══ METRIC DISPLAY ═══
function Metric({ label, value, sub, subColor, color, big, size }) {
return (
{label}
{value}
{sub &&
{sub}
}
);
}
// ═══ LIGHTWEIGHT CHARTS — equity curve ═══
function ChartBig() {
const containerRef = useRef(null);
const chartRef = useRef(null);
useEffect(() => {
const el = containerRef.current;
if (!el || !window.LightweightCharts) return;
if (chartRef.current) { chartRef.current.remove(); chartRef.current = null; }
const chart = window.LightweightCharts.createChart(el, {
width: el.clientWidth,
height: el.clientHeight || 180,
layout: {
background: { type: 'solid', color: 'transparent' },
textColor: theme.textDim,
fontFamily: '"JetBrains Mono", ui-monospace, monospace',
fontSize: 10,
},
grid: {
vertLines: { color: theme.border, style: 1 },
horzLines: { color: theme.border, style: 1 },
},
crosshair: {
mode: 1,
vertLine: { color: theme.accent, labelBackgroundColor: theme.accent },
horzLine: { color: theme.accent, labelBackgroundColor: theme.accent },
},
rightPriceScale: { borderColor: theme.border },
timeScale: { borderColor: theme.border, timeVisible: true },
handleScroll: true,
handleScale: true,
});
chartRef.current = chart;
// BTC benchmark (dim)
const btcSeries = chart.addAreaSeries({
lineColor: theme.textDim,
lineWidth: 1,
topColor: 'rgba(90,78,40,0.08)',
bottomColor: 'rgba(90,78,40,0)',
priceLineVisible: false,
lastValueVisible: false,
});
btcSeries.setData(D.equityCurve.map(d => ({ time: d.date, value: d.spy })));
// Portfolio (amber)
const portSeries = chart.addAreaSeries({
lineColor: theme.accent,
lineWidth: 2,
topColor: 'rgba(255,153,51,0.18)',
bottomColor: 'rgba(255,153,51,0)',
priceLineVisible: false,
lastValueVisible: true,
});
portSeries.setData(D.equityCurve.map(d => ({ time: d.date, value: d.portfolio })));
chart.timeScale().fitContent();
const ro = new ResizeObserver(() => {
if (el && chartRef.current) {
chartRef.current.applyOptions({ width: el.clientWidth, height: el.clientHeight || 180 });
}
});
ro.observe(el);
return () => {
ro.disconnect();
if (chartRef.current) { chartRef.current.remove(); chartRef.current = null; }
};
}, []);
return ;
}
// ═══ POSITIONS TABLE — crypto with live CoinGecko prices ═══
function PositionsTable({ getPrice }) {
function fmtQty(ticker, qty) {
if (ticker === 'BTC') return qty.toFixed(4);
if (['ETH', 'SOL'].includes(ticker)) return qty.toFixed(2);
return qty.toLocaleString('en-US');
}
function fmtPx(ticker, price) {
if (['DOGE'].includes(ticker)) return '$' + price.toFixed(4);
if (price >= 1000) return '$' + price.toLocaleString('en-US', { maximumFractionDigits: 0 });
return '$' + price.toFixed(2);
}
const rows = D.positions.map(p => {
const { price, change24h } = getPrice ? getPrice(p) : { price: p.price, change24h: p.change24h };
const mkt = p.qty * price;
const cost = p.qty * p.avgCost;
const upl = mkt - cost;
const uplPct = upl / cost;
return { ...p, livePrice: price, change24h, mkt, cost, upl, uplPct };
});
return (
| SYM |
QTY |
LAST |
24h% |
MKT VAL |
U P/L % |
{rows.map(r => (
| {r.ticker} |
{fmtQty(r.ticker, r.qty)} |
{fmtPx(r.ticker, r.livePrice)} |
= 0 ? theme.green : theme.red }}>
{(r.change24h >= 0 ? '+' : '') + r.change24h.toFixed(2) + '%'}
|
{fmt.compact(r.mkt)} |
= 0 ? theme.green : theme.red, fontWeight: 700 }}>{fmt.pct(r.uplPct)} |
))}
);
}
// ═══ ROUTINES LIST ═══
function RoutinesList({ onRun }) {
return (
{D.routines.map(r => (
{r.cron}
NEXT · {r.nextRun}
))}
);
}
// ═══ ACTIVITY FEED ═══
function ActivityFeed() {
const [items, setItems] = useState(D.activity);
useEffect(() => {
const id = setInterval(() => {
setItems(prev => {
const base = [...D.activity];
const t = `15:3${Math.floor(Math.random() * 5)}:${String(Math.floor(Math.random() * 60)).padStart(2, '0')}`;
const pool = [
{ level: 'think', msg: 'Evaluating BTC on-chain NUPL — still in "belief" zone' },
{ level: 'info', msg: 'Querying CoinGecko: 24h volume for SOL/LINK' },
{ level: 'ok', msg: 'Memory sync complete: positions.md updated' },
{ level: 'info', msg: 'Reading memory/learnings.md (AVAX unlock trap, line 8)' },
{ level: 'think', msg: 'ETH staking yield +0.2% this week — thesis strengthening' },
];
const next = pool[Math.floor(Math.random() * pool.length)];
return [...base.slice(-9), { t, routine: 'scan', ...next }];
});
}, 3800);
return () => clearInterval(id);
}, []);
const levelColor = { info: theme.textDim, ok: theme.green, think: theme.cyan, act: theme.accent, warn: theme.red };
return (
{items.slice(-10).map((it, i) => (
{it.t}
{it.level}
{it.msg}
))}
);
}
// ═══ TAB: DASHBOARD ═══
function DashboardTab({ onRun }) {
const { getPrice, lastUpdate, error } = useCoinGecko();
const rm = D.riskMetrics;
const dayPnl = 428.44;
const dayPnlPct = 0.0042;
return (
{/* Portfolio vs BTC */}
60 DAYS · USD}>
{/* Top metrics row */}
= 0 ? theme.green : theme.red} big />
D.btcBenchmarkReturn ? theme.green : theme.red} color={D.portfolioReturn > D.btcBenchmarkReturn ? theme.green : theme.red} />
{/* Risk metrics row */}
1 ? 'GOOD' : rm.sharpe > 0.5 ? 'OK' : 'WEAK'}
subColor={rm.sharpe > 1 ? theme.green : rm.sharpe > 0.5 ? theme.accent : theme.red}
color={rm.sharpe > 1 ? theme.green : rm.sharpe > 0.5 ? theme.accent : theme.red}
size={17}
/>
{/* Chart */}
▬▬ TAM PORTFOLIO
▬▬ BTC BENCHMARK
{error && ⚠ CoinGecko: {error}}
{/* Positions */}
{lastUpdate ? `LIVE · ${clockStr(lastUpdate)}` : D.positions.length + ' HOLDINGS'}
}>
{/* Routines */}
5 ACTIVE · 24/7}>
{/* Activity feed */}
SCAN RUNNING>}>
);
}
// ═══ TAB: ROUTINES ═══
function RoutinesTab() {
const [sel, setSel] = useState('scan');
const r = D.routines.find(x => x.id === sel);
return (
{D.routines.map(r => (
))}
{r.status === 'running' && } {r.status}
}
style={{ maxHeight: 220 }}>
);
}
function AgentTranscript() {
const [visible, setVisible] = useState(0);
useEffect(() => {
setVisible(0);
const id = setInterval(() => setVisible(v => v < D.agentThoughts.length ? v + 1 : v), 900);
return () => clearInterval(id);
}, []);
return (
{D.agentThoughts.slice(0, visible).map((m, i) => {
const tag = { system: 'SYS', agent: 'TAM', tool: 'TOOL' }[m.role];
const color = { system: theme.textDim, agent: theme.accent, tool: theme.cyan }[m.role];
return (
{tag}
{m.content}
);
})}
{visible < D.agentThoughts.length && (
TAM
▎thinking…
)}
);
}
// ═══ TAB: MEMORY FILES ═══
function MemoryTab() {
const [sel, setSel] = useState('CLAUDE.md');
return (
/memory}>
{D.memoryFiles.map(f => (
))}
READ-ONLY · AGENT WRITES}>
{D.fileContents[sel] || '(no preview available)'}
);
}
// ═══ TAB: TRADES ═══
function TradesTab() {
const [sel, setSel] = useState(0);
const t = D.tradeLog[sel];
function fmtTradeQty(ticker, qty) {
if (qty === '—') return '—';
if (ticker === 'BTC') return qty.toFixed ? qty.toFixed(4) : qty;
if (['ETH', 'SOL'].includes(ticker)) return qty.toFixed ? qty.toFixed(2) : qty;
return typeof qty === 'number' ? qty.toLocaleString('en-US') : qty;
}
return (
{D.tradeLog.length} TRADES · 30D}>
| DATE |
TIME |
SIDE |
SYM |
QTY |
PRICE |
{D.tradeLog.map((t, i) => (
setSel(i)} style={{
borderTop: `1px solid ${theme.border}`,
background: sel === i ? theme.panelAlt : 'transparent',
cursor: 'pointer',
}}>
| {t.date} |
{t.time} |
{t.action} |
{t.ticker} |
{fmtTradeQty(t.ticker, t.qty)} |
${typeof t.price === 'number' ? (t.price >= 100 ? t.price.toLocaleString('en-US', { maximumFractionDigits: 2 }) : t.price.toFixed(4)) : t.price} |
))}
AGENT REASONING
{t.reason}
SOURCE: routines/{t.action === 'ADJUST' ? 'scan' : t.time < '12:00' ? 'morning-brief' : 'risk-review'}.md
COMMIT: pushed to trading-routine/main
);
}
// ═══ TAB: GUARDRAILS ═══
function GuardrailsTab() {
const [g, setG] = useState(D.guardrails);
const update = (k, v) => setG(prev => ({ ...prev, [k]: v }));
const Row = ({ k, label, help, min = 0, max = 100, step = 0.5, unit = '%' }) => (
);
return (
ALPACA_ALLOW_LIVE
Permanently false. Real-money trading disabled at env level. Cannot be overridden by agent.
FALSE — LOCKED
{`# guardrails.md (auto-compiled)
# AGENT MUST OBEY.
max_position_pct = ${g.maxPositionPct}
daily_loss_cap_pct = ${g.dailyLossCapPct}
max_new_per_week = ${g.maxNewPerWeek}
initial_stop_pct = ${g.initialStopPct}
tighten_at_gain_pct = ${g.tightenAtGainPct}
tight_stop_pct = ${g.tightStopPct}
min_confidence_pct = ${g.minConfidencePct}
allow_live = false # PERMANENT
paper_mode = true
# No leverage. Ever.
# No margin.
# Stops are NON-NEGOTIABLE.
# DOGE/meme: max 5% combined.
# Anything < $500M market cap: SKIP.`}
);
}
// ═══ TAB: RESEARCH ═══
function ResearchTab() {
return (
{[
{ q: 'Bitcoin on-chain holder behavior May 2026', when: '15:32:29', sources: 3, status: 'done' },
{ q: 'ETH Dencun fee burn weekly update', when: '08:00:12', sources: 4, status: 'done' },
{ q: 'Chainlink CCIP mainnet usage statistics', when: '08:15:07', sources: 3, status: 'done' },
{ q: 'Solana DEX volume vs Ethereum DEX April 2026', when: '12:00:31', sources: 5, status: 'done' },
{ q: 'Dogecoin X payments integration rumor factcheck', when: '12:04:22', sources: 2, status: 'done' },
].map((r, i) => (
{r.when}
▸ CoinGecko / Glassnode
{r.q}
{r.sources} SOURCES
● {r.status.toUpperCase()}
))}
);
}
// ═══ RUN MODAL ═══
function RunModal({ id, onClose }) {
const r = D.routines.find(x => x.id === id);
const [step, setStep] = useState(0);
const lines = [
'$ claude code --routine ' + id + ' --remote',
'cloning trading-routine@main ...',
'spawning opus-4.7 agent ...',
'reading memory/CLAUDE.md, memory/strategy.md, memory/guardrails.md',
'reading memory/positions.md (6 crypto positions)',
'GET alpaca paper /v2/account → equity $102,750',
'GET alpaca paper /v2/positions → 6',
'GET coingecko /simple/price?ids=bitcoin,ethereum,solana,chainlink,dogecoin,litecoin',
'analyzing stop levels vs current prices ...',
'BTC +17.0% unrealized → tighten stop 7% → 5%',
'git commit -m "' + id + ' ' + new Date().toISOString().slice(0, 10) + '"',
'DONE. tokens used: ' + r.tokensAvg.toLocaleString(),
];
useEffect(() => {
if (step < lines.length) {
const t = setTimeout(() => setStep(s => s + 1), 350 + Math.random() * 400);
return () => clearTimeout(t);
}
}, [step]);
return (
▸ RUN NOW · {r.name.toUpperCase()}
{lines.slice(0, step).map((l, i) => (
{l}
))}
{step < lines.length &&
▎_
}
);
}
// ═══ APP ROOT ═══
function TAM_V1() {
const [tab, setTab] = useState('dashboard');
const [runModal, setRunModal] = useState(null);
const { error: coinError, lastUpdate } = useCoinGecko();
const tabs = [
{ id: 'dashboard', label: 'Dashboard' },
{ id: 'routines', label: 'Routines' },
{ id: 'trades', label: 'Trades' },
{ id: 'memory', label: 'Memory' },
{ id: 'research', label: 'Research' },
{ id: 'guardrails',label: 'Guardrails' },
];
return (
{tab === 'dashboard' && setRunModal(id)} />}
{tab === 'routines' && }
{tab === 'trades' && }
{tab === 'memory' && }
{tab === 'research' && }
{tab === 'guardrails' && }
{runModal &&
setRunModal(null)} />}
);
}
window.TAM_V1 = TAM_V1;
})();