Today's change measured against the chart's last close
Browse files- static/index.html +11 -3
static/index.html
CHANGED
|
@@ -393,8 +393,17 @@ function showPerf() {
|
|
| 393 |
if (perf.dates.length < 6) note = `The fund started on ${perf.start || "its first trade"} — the chart fills in day by day. ` + note;
|
| 394 |
setText($("live-note"), note);
|
| 395 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 396 |
async function loadPerformance() {
|
| 397 |
-
try { perf = await get("/api/performance"); syncLive(); showPerf(); }
|
| 398 |
catch (e) { setText($("live-note"), "Performance unavailable right now: " + e.message); }
|
| 399 |
}
|
| 400 |
async function loadPortfolio() {
|
|
@@ -403,8 +412,7 @@ async function loadPortfolio() {
|
|
| 403 |
if (perf) { syncLive(); showPerf(); }
|
| 404 |
setText($("mode"), p.paper ? "Paper trading" : "LIVE trading");
|
| 405 |
setText($("k-eq"), usd(p.equity));
|
| 406 |
-
|
| 407 |
-
signCls($("k-today"), p.today_pct);
|
| 408 |
const tb = $("holdings").querySelector("tbody"); tb.textContent = "";
|
| 409 |
if (!p.positions.length) { const tr = tb.insertRow(); const td = tr.insertCell(); td.colSpan = 6; td.className = "empty"; td.textContent = "No positions yet — the first rebalance buys the top 3."; }
|
| 410 |
for (const r of p.positions) {
|
|
|
|
| 393 |
if (perf.dates.length < 6) note = `The fund started on ${perf.start || "its first trade"} — the chart fills in day by day. ` + note;
|
| 394 |
setText($("live-note"), note);
|
| 395 |
}
|
| 396 |
+
function showToday() { // against the last close on the chart: Alpaca's own last_equity can lag a day on paper
|
| 397 |
+
if (!port) return;
|
| 398 |
+
let ch = port.today_change, pc = port.today_pct;
|
| 399 |
+
if (perf && perf.src && perf.src[perf.src.length - 1] === "live" && perf.value.length > 1) {
|
| 400 |
+
const prev = perf.value[perf.value.length - 2]; ch = port.equity - (perf.flows_today || 0) - prev; pc = ch / prev;
|
| 401 |
+
}
|
| 402 |
+
setText($("k-today"), pc == null ? "" : `today ${pct(pc, 2)} (${ch >= 0 ? "+" : "−"}${usd(Math.abs(ch))})`);
|
| 403 |
+
signCls($("k-today"), pc);
|
| 404 |
+
}
|
| 405 |
async function loadPerformance() {
|
| 406 |
+
try { perf = await get("/api/performance"); syncLive(); showPerf(); showToday(); }
|
| 407 |
catch (e) { setText($("live-note"), "Performance unavailable right now: " + e.message); }
|
| 408 |
}
|
| 409 |
async function loadPortfolio() {
|
|
|
|
| 412 |
if (perf) { syncLive(); showPerf(); }
|
| 413 |
setText($("mode"), p.paper ? "Paper trading" : "LIVE trading");
|
| 414 |
setText($("k-eq"), usd(p.equity));
|
| 415 |
+
showToday();
|
|
|
|
| 416 |
const tb = $("holdings").querySelector("tbody"); tb.textContent = "";
|
| 417 |
if (!p.positions.length) { const tr = tb.insertRow(); const td = tr.insertCell(); td.colSpan = 6; td.className = "empty"; td.textContent = "No positions yet — the first rebalance buys the top 3."; }
|
| 418 |
for (const r of p.positions) {
|