What to build
renderExpiryTable in src/js/06-render-table.js currently reads raw trades[] and recomputes APR inline. The APR formula is already computed by compute() on every enriched row as r.annual. This creates two copies of the formula that can silently diverge.
The fix: pipe enriched allRows from compute() through rStats into renderExpiryTable, so it filters from the already-enriched rows and reads r.annual directly.
Three concrete changes:
src/js/08-render.js: pass c.allRows to rStats
src/js/06-render-table.js — rStats signature updated to accept allRows and forward it to renderExpiryTable(allRows)
renderExpiryTable(allRows): filters enriched rows for open options expiring within 7 days (keeping its own sFilter asset check), uses r.annual instead of the inline formula, uses the existing _liveDte(r.expiry) helper instead of recalculating days manually
- Remove the dead
else renderExpiryTable() fallback in fetchExpiryPrices — render is always defined in the built app; this branch never executes
Acceptance criteria
Blocked by
None — can start immediately.
What to build
renderExpiryTableinsrc/js/06-render-table.jscurrently reads rawtrades[]and recomputes APR inline. The APR formula is already computed bycompute()on every enriched row asr.annual. This creates two copies of the formula that can silently diverge.The fix: pipe enriched
allRowsfromcompute()throughrStatsintorenderExpiryTable, so it filters from the already-enriched rows and readsr.annualdirectly.Three concrete changes:
src/js/08-render.js: passc.allRowstorStatssrc/js/06-render-table.js—rStatssignature updated to acceptallRowsand forward it torenderExpiryTable(allRows)renderExpiryTable(allRows): filters enriched rows for open options expiring within 7 days (keeping its ownsFilterasset check), usesr.annualinstead of the inline formula, uses the existing_liveDte(r.expiry)helper instead of recalculating days manuallyelse renderExpiryTable()fallback infetchExpiryPrices—renderis always defined in the built app; this branch never executesAcceptance criteria
renderExpiryTableno longer contains an inline APR formularenderExpiryTableno longer readstrades[]directlyelse renderExpiryTable()branch infetchExpiryPricesis removedsFilter) still applies correctly in the Expiring This Week sectionpython3 build.py --checkpassesnpm testpassesBlocked by
None — can start immediately.