app/options.py and app/providers/cboe.py build full option chains — delta, gamma, theta, vega, rho, implied volatility and open interest — plus an unusual-activity ranking that finds contracts trading above their entire open interest. It works. tests/test_options.py covers it with 34 passing assertions.
It is just not reachable. The view was taken back out of the terminal as too much at the time, and never went back in. grep -c "api/options" app/server.py returns 0.
So this is a route and a view, not a rewrite.
What it needs
- A route in
app/server.py — follow _market_news or the new _livetv as the shape. Both cache their payload with strip_cache/store_strip because the upstream is slow relative to how often the UI asks.
- A view in
app/web/index.html — a tab, a view-options div, a loader, and a draw function. view-earnings is the closest existing model: a table of rows grouped by a key.
- Register the key in the
keys map near the bottom of index.html and add the tab to the rail. ui_smoke.js asserts the tab count, so update that number in the same PR.
The functions you are wiring
options.chain(symbol, expiry=None, strikes=16) # one expiry, strikes around spot
options.stats(contracts, expiry=None) # put/call ratio, IV summary
options.unusual(symbol, min_volume=...) # volume above open interest
Rules that bite here
- Cboe data is delayed and the panel must say so. House rule 1: never claim live over stale. The existing panels render
DELAYED and mean it.
- A greek that cannot be computed stays
null. Do not default a missing IV to zero — see house rule 2 in CONTRIBUTING.md.
- Run
node tests/ui_smoke.js — it is the only thing that catches a runtime throw at page load.
Good first issue because the hard half — the maths, the provider, the tests — is already done and reviewed.
app/options.pyandapp/providers/cboe.pybuild full option chains — delta, gamma, theta, vega, rho, implied volatility and open interest — plus an unusual-activity ranking that finds contracts trading above their entire open interest. It works.tests/test_options.pycovers it with 34 passing assertions.It is just not reachable. The view was taken back out of the terminal as too much at the time, and never went back in.
grep -c "api/options" app/server.pyreturns 0.So this is a route and a view, not a rewrite.
What it needs
app/server.py— follow_market_newsor the new_livetvas the shape. Both cache their payload withstrip_cache/store_stripbecause the upstream is slow relative to how often the UI asks.app/web/index.html— a tab, aview-optionsdiv, a loader, and a draw function.view-earningsis the closest existing model: a table of rows grouped by a key.keysmap near the bottom ofindex.htmland add the tab to the rail.ui_smoke.jsasserts the tab count, so update that number in the same PR.The functions you are wiring
Rules that bite here
DELAYEDand mean it.null. Do not default a missing IV to zero — see house rule 2 in CONTRIBUTING.md.node tests/ui_smoke.js— it is the only thing that catches a runtime throw at page load.Good first issue because the hard half — the maths, the provider, the tests — is already done and reviewed.