docs: migrate roadmap to structured yaml tasks
This commit is contained in:
619
docs/ROADMAP.md
619
docs/ROADMAP.md
@@ -1,619 +0,0 @@
|
|||||||
# Vault Dashboard Roadmap
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
A prioritized roadmap for the Vault Dashboard Lombard loan hedging platform.
|
|
||||||
|
|
||||||
## Legend
|
|
||||||
- **Priority**: P0 (Critical), P1 (High), P2 (Medium), P3 (Low)
|
|
||||||
- **Dependencies**: Features tagged with `[depends: ID]` require the named feature to be completed first
|
|
||||||
- **Effort**: S (Small), M (Medium), L (Large)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Phase 1: Data Foundation (Foundation Layer)
|
|
||||||
|
|
||||||
### DATA-001: Live Price Feed Integration [P0, M] **[foundation]**
|
|
||||||
**As a** portfolio manager, **I want** real-time gold price updates **so that** my LTV calculations reflect current market conditions.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Integrate yfinance/live data for GLD spot price
|
|
||||||
- Update prices every 30 seconds via WebSocket
|
|
||||||
- Display last update timestamp
|
|
||||||
- Fallback to cached data if feed fails
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Create `app/services/price_feed.py` with async price fetching
|
|
||||||
- Extend existing WebSocket manager in `app/services/websocket.py`
|
|
||||||
- Store prices in Redis with 60s TTL
|
|
||||||
|
|
||||||
**Dependencies:** None
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### DATA-002: Options Chain Data [P0, L] **[depends: DATA-001]**
|
|
||||||
**As a** trader, **I want** live options chain data for GLD **so that** I can evaluate protective put strikes and premiums.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Fetch options chains from yfinance or IBKR API
|
|
||||||
- Display strikes, expiration dates, bid/ask, implied volatility
|
|
||||||
- Cache chain data for 5 minutes
|
|
||||||
- Support filtering by expiration (30/60/90 days)
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Create `app/services/options_chain.py`
|
|
||||||
- Add `/api/options/chain` endpoint
|
|
||||||
- Update Options Chain page (`app/pages/options.py`)
|
|
||||||
|
|
||||||
**Dependencies:** DATA-001
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### DATA-003: Greeks Calculation [P1, M] **[depends: DATA-002]**
|
|
||||||
**As a** risk manager, **I want** real-time Greeks calculations **so that** I understand my hedge sensitivity.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Calculate Delta, Gamma, Theta, Vega for selected options
|
|
||||||
- Display Greeks in options chain view
|
|
||||||
- Show portfolio-level Greeks if positions held
|
|
||||||
- Use Black-Scholes model with live IV
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Create `app/services/pricing.py` with B-S model
|
|
||||||
- Add QuantLib integration (optional dependency)
|
|
||||||
- Cache calculations for performance
|
|
||||||
|
|
||||||
**Dependencies:** DATA-002
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Phase 2: Portfolio & Risk (Core Features)
|
|
||||||
|
|
||||||
### PORT-001: Portfolio State Management [P0, M] **[depends: DATA-001]**
|
|
||||||
**As a** user, **I want** to configure my actual portfolio (gold value, loan amount) **so that** LTV calculations match my real position.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Settings page with editable portfolio parameters
|
|
||||||
- Store config in Redis/database
|
|
||||||
- Validate LTV < 100%
|
|
||||||
- Show current vs recommended collateral
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Extend `app/pages/settings.py`
|
|
||||||
- Create `app/models/portfolio.py` with Pydantic models
|
|
||||||
- Add persistence layer (Redis JSON or SQLite)
|
|
||||||
|
|
||||||
**Dependencies:** DATA-001
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### PORT-002: Alert Notifications [P1, M] **[depends: PORT-001]**
|
|
||||||
**As a** risk manager, **I want** alerts when LTV approaches margin call thresholds **so that** I can take action before liquidation.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Configurable alert thresholds (default: 70%, 75%)
|
|
||||||
- Browser push notifications
|
|
||||||
- Email notifications (optional)
|
|
||||||
- Alert history log
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Create `app/services/alerts.py`
|
|
||||||
- Integrate browser notifications API
|
|
||||||
- Add `/api/alerts/configure` endpoint
|
|
||||||
- Background task to check thresholds
|
|
||||||
|
|
||||||
**Dependencies:** PORT-001
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### PORT-003: Historical LTV Chart [P2, M] **[depends: PORT-001]**
|
|
||||||
**As a** user, **I want** to see my LTV history over time **so that** I can identify trends and stress periods.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Store LTV snapshots every hour
|
|
||||||
- Display 7/30/90 day charts
|
|
||||||
- Show margin call threshold line
|
|
||||||
- Export data as CSV
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Create `app/services/history.py`
|
|
||||||
- Use TimescaleDB or Redis TimeSeries (optional)
|
|
||||||
- Integrate with existing chart components
|
|
||||||
|
|
||||||
**Dependencies:** PORT-001
|
|
||||||
|
|
||||||
### PORT-004: Hashed Workspace Persistence [P0, L] **[depends: PORT-001]**
|
|
||||||
**As a** user, **I want** my dashboard settings and scenarios to live inside a shareable hashed workspace URL **so that** I can return on a new device or share the exact workspace with someone else.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- First visit with no known workspace shows a welcome/bootstrap page at `/`
|
|
||||||
- Welcome page contains a short description and a clear call to action such as `Get started`
|
|
||||||
- Clicking `Get started` creates a new workspace id (UUID/hash-like token), stores it in a browser cookie, and redirects to `/{workspace_id}`
|
|
||||||
- Returning visitors with a valid workspace cookie who visit `/` are redirected to their existing workspace
|
|
||||||
- Visiting an existing `/{workspace_id}` loads that workspace without requiring the cookie
|
|
||||||
- Workspace URL is copyable/shareable and restores the same settings on another device/browser
|
|
||||||
- Settings persistence is scoped by workspace id rather than one global local file
|
|
||||||
- Existing pages (`/{workspace_id}`, `/{workspace_id}/settings`, `/{workspace_id}/overview`, `/{workspace_id}/hedge`, `/{workspace_id}/backtests`, `/{workspace_id}/event-comparison`) read/write the active workspace state
|
|
||||||
- Invalid or unknown workspace ids show a clear recovery path instead of a server error
|
|
||||||
- Browser test verifies:
|
|
||||||
- first visit shows the welcome page
|
|
||||||
- clicking `Get started` creates/redirects to a workspace route
|
|
||||||
- cookie-backed revisit to `/` returns to the same workspace
|
|
||||||
- visiting the same workspace URL in a fresh context restores the same settings
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Introduce a workspace model/repository keyed by generated id
|
|
||||||
- Prefer server-side persistence keyed by workspace id; cookie stores only the id, not the full state
|
|
||||||
- Keep workspace ids opaque and non-sequential
|
|
||||||
- Treat `/` as a dedicated bootstrap/welcome route rather than making every page handle bootstrap behavior
|
|
||||||
- Workspace pages can remain focused on workspace-aware rendering only; bootstrap logic stays isolated at `/`
|
|
||||||
- Ensure routing design stays compatible with existing NiceGUI pages before implementation
|
|
||||||
|
|
||||||
**Dependencies:** PORT-001
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Phase 3: Strategy Execution (Advanced Features)
|
|
||||||
|
|
||||||
### EXEC-001: Strategy Builder [P1, L] **[depends: DATA-003]**
|
|
||||||
**As a** trader, **I want** to build and compare hedging strategies **so that** I can choose optimal protection.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Select strategy type (protective put, collar, laddered)
|
|
||||||
- Choose strikes and expirations
|
|
||||||
- See P&L payoff diagrams
|
|
||||||
- Compare cost vs protection level
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Extend `app/pages/hedge.py`
|
|
||||||
- Create `app/services/strategy_builder.py`
|
|
||||||
- Add payoff chart visualization
|
|
||||||
- Store strategy templates
|
|
||||||
|
|
||||||
**Dependencies:** DATA-003
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### EXEC-002: IBKR Order Integration [P2, L] **[depends: EXEC-001]**
|
|
||||||
**As a** authorized user, **I want** to execute hedge trades directly from the dashboard **so that** I can act quickly on recommendations.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- IBKR API connection (paper trading first)
|
|
||||||
- Preview order with estimated fill
|
|
||||||
- One-click execution
|
|
||||||
- Order tracking and status updates
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Create `app/services/broker.py` with IBKR API
|
|
||||||
- Add paper/live mode toggle
|
|
||||||
- Store credentials securely
|
|
||||||
- Order audit log
|
|
||||||
|
|
||||||
**Dependencies:** EXEC-001
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### EXEC-003: Position Monitoring [P2, M] **[depends: EXEC-002]**
|
|
||||||
**As a** portfolio manager, **I want** to see my open hedge positions **so that** I know my current protection status.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Display open options positions
|
|
||||||
- Show expiration countdown
|
|
||||||
- Calculate net Greeks exposure
|
|
||||||
- Alert on approaching expiration
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Create positions table/view
|
|
||||||
- Sync with IBKR positions
|
|
||||||
- Update portfolio Greeks calculation
|
|
||||||
|
|
||||||
**Dependencies:** EXEC-002
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Phase 4: Reporting & Analytics (Polish)
|
|
||||||
|
|
||||||
### RPT-001: Strategy Report Generation [P3, M] **[depends: EXEC-001]**
|
|
||||||
**As a** compliance officer, **I want** PDF reports of hedging decisions **so that** I can document risk management.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Generate PDF with strategy rationale
|
|
||||||
- Include P&L scenarios
|
|
||||||
- Date range selection
|
|
||||||
- Export to email/share
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Use reportlab or weasyprint
|
|
||||||
- Create `app/services/reporting.py`
|
|
||||||
- Add download endpoint
|
|
||||||
|
|
||||||
**Dependencies:** EXEC-001
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### RPT-002: What-If Analysis [P3, L] **[depends: DATA-003]**
|
|
||||||
**As a** risk manager, **I want** to simulate gold price drops **so that** I can stress test my protection.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Slider to adjust gold price scenarios (-10%, -20%, etc.)
|
|
||||||
- Show portfolio P&L impact
|
|
||||||
- Display hedge payoff under scenarios
|
|
||||||
- Compare protected vs unprotected
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Extend strategy builder with scenario mode
|
|
||||||
- Add sensitivity analysis
|
|
||||||
- Interactive chart updates
|
|
||||||
|
|
||||||
**Dependencies:** DATA-003
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Dependency Graph
|
|
||||||
|
|
||||||
```
|
|
||||||
DATA-001 (Price Feed)
|
|
||||||
├── DATA-002 (Options Chain)
|
|
||||||
│ ├── DATA-003 (Greeks)
|
|
||||||
│ │ ├── EXEC-001 (Strategy Builder)
|
|
||||||
│ │ │ ├── EXEC-002 (IBKR Orders)
|
|
||||||
│ │ │ │ └── EXEC-003 (Position Monitoring)
|
|
||||||
│ │ │ └── RPT-001 (Reports)
|
|
||||||
│ │ └── RPT-002 (What-If)
|
|
||||||
│ └── PORT-001 (Portfolio Config)
|
|
||||||
│ ├── PORT-002 (Alerts)
|
|
||||||
│ └── PORT-003 (History)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Fast Follow-up Backlog
|
|
||||||
|
|
||||||
### DATA-002A: Lazy Options Loading [P0, S] **[depends: DATA-002]**
|
|
||||||
**As a** trader, **I want** the options page to render immediately **so that** it feels responsive and usable.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Initial page load fetches only expirations plus one default expiry chain
|
|
||||||
- Changing expiry fetches that expiry on demand
|
|
||||||
- Browser test verifies `/options` becomes visible quickly
|
|
||||||
- No visible 500/runtime error during page load
|
|
||||||
|
|
||||||
**Dependencies:** DATA-002
|
|
||||||
|
|
||||||
### DATA-001A: Live Overview Price Wiring [P0, S] **[depends: DATA-001, PORT-001]**
|
|
||||||
**As a** portfolio manager, **I want** the overview cards to use live quote data **so that** the displayed spot/LTV values are trustworthy.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Overview page uses live quote from service instead of hardcoded `215.0`
|
|
||||||
- Display source and last updated timestamp
|
|
||||||
- Margin call / LTV calculations use configured portfolio values
|
|
||||||
- Browser test verifies overview renders with live data metadata
|
|
||||||
|
|
||||||
**Dependencies:** DATA-001, PORT-001
|
|
||||||
|
|
||||||
### OPS-001: Caddy Route for Production Dashboard [P1, S] **[depends: deploy-stable]**
|
|
||||||
**As a** user, **I want** to reach the deployed dashboard at `lombard.uncloud.tech` **so that** I can access it directly over HTTPS.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Caddy route proxies `lombard.uncloud.tech` to the deployment container
|
|
||||||
- HTTPS works with a valid certificate
|
|
||||||
- Health check succeeds through Caddy
|
|
||||||
- Deployment docs include the route and note that `vd1.uncloud.vpn` was retired
|
|
||||||
|
|
||||||
**Dependencies:** stable deployed app on VPS
|
|
||||||
|
|
||||||
### PORT-001A: Collateral Entry Basis in Settings [P1, M] **[depends: PORT-001]**
|
|
||||||
**As a** portfolio manager, **I want** to store my collateral entry basis **so that** the dashboard can derive position size consistently from either cost basis or weight.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Settings supports entering either:
|
|
||||||
- total collateral start value **and** entry price, or
|
|
||||||
- gold weight directly
|
|
||||||
- Updating one mode calculates the other representation automatically
|
|
||||||
- Persist both the chosen input mode and the derived values needed by the app
|
|
||||||
- Validation prevents impossible or contradictory values (zero/negative price, value, or weight)
|
|
||||||
- UI makes the relationship explicit: `weight = start_value / entry_price`
|
|
||||||
- Browser-visible test covers switching modes and saving derived values
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Extend `PortfolioConfig` / settings persistence with entry-basis fields
|
|
||||||
- Keep overview and other consumers compatible with existing portfolio settings
|
|
||||||
- Prefer a single canonical stored representation plus derived display fields to avoid drift
|
|
||||||
|
|
||||||
**Dependencies:** PORT-001
|
|
||||||
|
|
||||||
### EXEC-001A: Named Strategy Templates [P1, M] **[depends: DATA-003]**
|
|
||||||
**As a** risk manager, **I want** protection strategies to be first-class named templates **so that** I can compare, reuse, and later edit hedge definitions.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Persist strategy templates with a stable id and display name
|
|
||||||
- Support at least initial system-defined templates (future user-editable names)
|
|
||||||
- Store template parameters separately from backtest scenarios
|
|
||||||
- Strategy templates are reusable by both live recommendation flows and backtests
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Add strategy template model/repository
|
|
||||||
- Separate template definition from strategy execution state
|
|
||||||
- Keep room for future user-editable naming and rule parameters
|
|
||||||
|
|
||||||
**Dependencies:** DATA-003
|
|
||||||
|
|
||||||
### BT-001: Synthetic Historical Backtesting [P1, L] **[depends: EXEC-001A, PORT-001]**
|
|
||||||
**As a** portfolio manager, **I want** to backtest hedge strategies against historical selloffs **so that** I can see which approach would have survived without a margin call.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Define a backtest scenario with start date, end date, collateral basis, and initial LTV
|
|
||||||
- Simulate at least one named hedge strategy over historical GLD prices
|
|
||||||
- Report max LTV, final equity, hedge cost, and whether a margin call would have occurred
|
|
||||||
- Compare protected vs unprotected outcomes for the same scenario
|
|
||||||
- Support known event replay such as the 2026 gold selloff window
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Start with synthetic/model-priced historical options rather than requiring point-in-time full historical chains
|
|
||||||
- Use historical underlying prices plus Black-Scholes/volatility assumptions
|
|
||||||
- Output both time series and summary metrics
|
|
||||||
|
|
||||||
**Dependencies:** EXEC-001A, PORT-001
|
|
||||||
|
|
||||||
### BT-002: Historical Daily Options Snapshot Provider [P2, L] **[depends: BT-001]**
|
|
||||||
**As a** quant user, **I want** real historical daily options snapshots **so that** backtests use observed premiums instead of only modeled prices.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Historical data provider abstraction supports point-in-time daily option chain snapshots
|
|
||||||
- Backtest engine can swap synthetic pricing for provider-backed historical daily premiums
|
|
||||||
- Contract selection avoids lookahead bias
|
|
||||||
- Provider choice and data quality limits are documented clearly
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Add provider interface for underlying history and option snapshot history
|
|
||||||
- Prefer daily snapshots first; intraday/tick fidelity is a later upgrade
|
|
||||||
- Candidate providers: Databento, Massive/Polygon, ThetaData, EODHD
|
|
||||||
|
|
||||||
**Dependencies:** BT-001
|
|
||||||
|
|
||||||
### BT-003: Selloff Event Comparison Report [P2, M] **[depends: BT-001]**
|
|
||||||
**As a** portfolio manager, **I want** event-based backtest reports **so that** I can answer questions like “which strategy got me through the Jan 2026 selloff?”
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Event presets can define named historical windows
|
|
||||||
- Report ranks strategies by survival, max LTV, cost, and final equity
|
|
||||||
- Report highlights breach date if a strategy fails
|
|
||||||
- UI can show the unhedged path beside hedged paths
|
|
||||||
|
|
||||||
**Dependencies:** BT-001
|
|
||||||
|
|
||||||
### BT-001A: Backtest Scenario Runner UI [P1, M] **[depends: BT-001, EXEC-001A, PORT-001]**
|
|
||||||
**As a** portfolio manager, **I want** a thin backtest page where I can run a synthetic scenario and inspect the result **so that** the BT-001 engine is available through the product UI instead of only tests/services.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Add a backtest page with a simple scenario form for:
|
|
||||||
- symbol
|
|
||||||
- start date
|
|
||||||
- end date
|
|
||||||
- template selection
|
|
||||||
- underlying units
|
|
||||||
- entry spot
|
|
||||||
- loan amount
|
|
||||||
- margin call LTV
|
|
||||||
- Running the form executes the existing BT-001 synthetic backtest service
|
|
||||||
- Results show at least:
|
|
||||||
- start value
|
|
||||||
- end unhedged value
|
|
||||||
- end hedged net value
|
|
||||||
- total hedge cost
|
|
||||||
- max LTV unhedged / hedged
|
|
||||||
- margin-call outcome
|
|
||||||
- Results include a visible daily path chart/table comparing unhedged vs hedged values
|
|
||||||
- Invalid scenarios surface user-visible validation errors instead of server errors
|
|
||||||
- Browser test verifies the page can run one deterministic scenario end-to-end
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Keep this slice read-only and in-process; no run persistence required yet
|
|
||||||
- Reuse existing BT-001 models/services rather than adding a second execution path
|
|
||||||
- Prefer a single page that renders metrics first and a compact path visualization second
|
|
||||||
- Do not block on historical option snapshot providers; synthetic pricing is sufficient for the first UI slice
|
|
||||||
|
|
||||||
**Dependencies:** BT-001, EXEC-001A, PORT-001
|
|
||||||
|
|
||||||
### BT-003A: Event Comparison UI Read Path [P1, M] **[depends: BT-003, BT-001A]**
|
|
||||||
**As a** portfolio manager, **I want** to select a named selloff event and compare template outcomes in the UI **so that** event-comparison results are visible without invoking services manually.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Add an event comparison page or section that lets the user select:
|
|
||||||
- event preset
|
|
||||||
- one or more strategy templates
|
|
||||||
- initial portfolio inputs
|
|
||||||
- Running the comparison executes the existing BT-003 comparison service
|
|
||||||
- UI displays ranked strategy results with at least:
|
|
||||||
- rank
|
|
||||||
- template name
|
|
||||||
- survived margin call
|
|
||||||
- max hedged LTV
|
|
||||||
- hedge cost
|
|
||||||
- final equity
|
|
||||||
- UI shows the selected event window metadata and the scenario dates actually used
|
|
||||||
- UI shows at least one simple visual comparison of hedged vs unhedged path behavior
|
|
||||||
- Empty template selection and invalid inputs surface user-visible validation states
|
|
||||||
- Browser test verifies one seeded event preset comparison renders ranked results
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Start with existing seeded event presets from `config/event_presets.json`
|
|
||||||
- Keep this slice read-only; no saved reports/downloads required yet
|
|
||||||
- Reuse `EventComparisonService` and avoid duplicating ranking logic in the UI layer
|
|
||||||
- Keep the output intentionally thin: ranked table first, deeper charts/details later
|
|
||||||
|
|
||||||
**Dependencies:** BT-003, BT-001A
|
|
||||||
|
|
||||||
### BT-001B: Backtest Defaults from Saved Portfolio [P1, S] **[depends: BT-001A, PORT-001A]**
|
|
||||||
**As a** portfolio manager, **I want** the backtest forms to prefill from my saved portfolio settings **so that** I do not have to re-enter start value, start price, weight, and loan inputs across pages.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- `/backtests` defaults derive from the canonical saved portfolio/settings state
|
|
||||||
- `/event-comparison` defaults derive from the same canonical saved portfolio/settings state
|
|
||||||
- UI makes the implied starting position explicit (start value, start price, weight)
|
|
||||||
- Changes in settings are reflected in both backtest pages on reload
|
|
||||||
- Browser test verifies saved settings influence backtest defaults
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Reuse the existing portfolio/settings persistence path
|
|
||||||
- Avoid duplicating position-derivation logic between settings and backtest pages
|
|
||||||
- Keep BT-001A/BT-003A read-only with respect to persistence; settings remains the source of truth
|
|
||||||
|
|
||||||
**Dependencies:** BT-001A, PORT-001A
|
|
||||||
|
|
||||||
### BT-003B: Event Comparison Drilldown [P1, M] **[depends: BT-003A]**
|
|
||||||
**As a** portfolio manager, **I want** to inspect why one ranked strategy beat another **so that** the comparison page explains survival, cost, and path behavior instead of only showing a summary table.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Selecting a ranked strategy shows its daily path details
|
|
||||||
- UI exposes at least:
|
|
||||||
- margin call days hedged/unhedged
|
|
||||||
- total option payoff realized
|
|
||||||
- total hedge cost
|
|
||||||
- final equity
|
|
||||||
- UI highlights the worst LTV point and any breach dates
|
|
||||||
- User can compare the selected strategy path against the unhedged baseline and one other ranked strategy
|
|
||||||
- Browser test verifies drilldown content updates when selecting a ranked result
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Reuse existing `daily_path` and summary metrics from BT-001/BT-003 results
|
|
||||||
- Keep this slice read-only; no saved reports required yet
|
|
||||||
- Prefer progressive disclosure below the ranked table rather than a separate workflow
|
|
||||||
|
|
||||||
**Dependencies:** BT-003A
|
|
||||||
|
|
||||||
### BT-001C: Shared Historical Fixture/Test Provider Cleanup [P2, S] **[depends: BT-001A, BT-003A]**
|
|
||||||
**As a** developer, **I want** one shared deterministic historical fixture provider for backtest UI paths **so that** seeded browser tests and demo scenarios stay consistent and do not duplicate historical-window logic.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Deterministic historical fixture/provider logic is centralized instead of duplicated across page-specific services
|
|
||||||
- Supported seeded windows are explicit and fail closed outside allowed ranges
|
|
||||||
- Both `/backtests` and `/event-comparison` use the shared deterministic provider in browser-tested demo paths
|
|
||||||
- Tests cover the supported-window contract and failure mode
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Prefer a small shared test/demo provider abstraction over page-local fixture classes
|
|
||||||
- Keep live providers separate from deterministic seeded UI/demo behavior
|
|
||||||
|
|
||||||
**Dependencies:** BT-001A, BT-003A
|
|
||||||
|
|
||||||
### CORE-001: Explicit Unit/Value Classes for Domain Quantities [P1, L] **[foundation]**
|
|
||||||
**As a** developer, **I want** money, weight, spot-price, and quantity values to use explicit unit-aware value classes **so that** incompatible units cannot be mixed silently in calculations.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Introduce explicit domain value types for at least:
|
|
||||||
- currency amount
|
|
||||||
- currency per weight
|
|
||||||
- gold/underlying quantity
|
|
||||||
- weight unit
|
|
||||||
- base currency
|
|
||||||
- All unit-bearing numeric values use decimal-based representation suitable for bookkeeping/accounting accuracy rather than binary floating point
|
|
||||||
- Each value object carries both numeric value and declared unit/currency metadata
|
|
||||||
- Implicit arithmetic between incompatible types is rejected by default
|
|
||||||
- Only explicit conversions and explicitly defined operators are allowed
|
|
||||||
- Conversions between supported weight units are implemented and tested
|
|
||||||
- Domain operations express intent clearly, e.g. multiplying `Gold` by `CurrencyPerWeight` yields `Currency`
|
|
||||||
- Existing high-risk calculation paths (overview, hedge, backtests, event comparison) are migrated away from raw `float` mixing for unit-bearing values
|
|
||||||
- Tests cover both valid conversions/operations and invalid combinations that must fail loudly
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Prefer small immutable value objects / dataclasses over loose primitives
|
|
||||||
- Use Python `Decimal` (or an equivalent decimal fixed-precision type) as the canonical numeric representation for money, quantities, and conversion-bearing domain values
|
|
||||||
- Add enums or equivalent typed constants for currency (`USD`, `EUR`, `CHF`, ...) and weight (`grams`, `kilograms`, `oz`)
|
|
||||||
- Make conversion APIs explicit, e.g. `to_weight(...)`, `to_currency(...)`, or named constructors
|
|
||||||
- Default operators should be conservative: fail closed unless a unit-safe operation is explicitly defined
|
|
||||||
- Start with gold/collateral and spot-price paths first, then extend to options/backtesting quantities where needed
|
|
||||||
- Define clear boundaries for interoperability with existing float-heavy libraries/services so conversion into/out of `Decimal` happens intentionally at the edges
|
|
||||||
- Use this story to remove the class of bugs caused by mixing physical-gold ounces, ETF-like units, USD notionals, and USD-per-weight spot quotes
|
|
||||||
|
|
||||||
**Dependencies:** None
|
|
||||||
|
|
||||||
### CORE-001A: Decimal Unit Value Object Foundation [P1, M] **[depends: CORE-001]**
|
|
||||||
**As a** developer, **I want** a small core set of immutable Decimal-based value objects and enums **so that** unit-aware domain modeling exists before we migrate calculation paths.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Introduce foundational domain types for at least:
|
|
||||||
- `BaseCurrency`
|
|
||||||
- `WeightUnit`
|
|
||||||
- `Money`
|
|
||||||
- `PricePerWeight`
|
|
||||||
- `GoldQuantity` / equivalent weight-bearing quantity type
|
|
||||||
- Core numeric fields use `Decimal` as the canonical representation
|
|
||||||
- Constructors/validators reject invalid or missing unit metadata
|
|
||||||
- Weight conversion methods are explicit and tested
|
|
||||||
- Unsupported arithmetic fails closed unless an operator is deliberately defined
|
|
||||||
- Tests cover constructors, conversions, equality/normalization expectations, and invalid operations
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Prefer a dedicated domain module such as `app/domain/units.py` or similar
|
|
||||||
- Keep the first slice focused on primitives and unit algebra, not page migration yet
|
|
||||||
- Add string/serialization helpers carefully so persistence remains deterministic
|
|
||||||
- See `docs/CORE-001A_DECIMAL_UNITS_ARCHITECTURE.md` for the implementation-ready design
|
|
||||||
|
|
||||||
**Dependencies:** CORE-001
|
|
||||||
|
|
||||||
### CORE-001B: Overview and Hedge Migration to Unit-Safe Types [P1, M] **[depends: CORE-001A, PORT-001A]**
|
|
||||||
**As a** developer, **I want** overview and hedge calculations to use the new unit-safe Decimal value objects **so that** the most user-visible collateral math stops depending on raw float conventions.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Overview calculations use unit-safe types for collateral quantity, spot price, notional values, and margin-call math
|
|
||||||
- Hedge scenario calculations use unit-safe types for starting position, option contribution framing, and equity outputs where applicable
|
|
||||||
- The incompatible live-quote fallback path remains correct under the new model
|
|
||||||
- Existing visible outputs remain browser-verified on `/overview` and `/hedge`
|
|
||||||
- Regression tests cover previously discovered unit-confusion bugs
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Start with calculation helpers and view-model boundaries before touching every page widget
|
|
||||||
- Convert to/from legacy float-heavy libraries only at the edges, with explicit naming
|
|
||||||
- Preserve current Lombard/domain compatibility while migrating internals
|
|
||||||
|
|
||||||
**Dependencies:** CORE-001A, PORT-001A
|
|
||||||
|
|
||||||
### CORE-001C: Backtests and Event Comparison Migration to Unit-Safe Types [P1, M] **[depends: CORE-001A, BT-001, BT-003A]**
|
|
||||||
**As a** developer, **I want** historical scenario inputs and outputs to use the new unit-safe Decimal value objects **so that** backtests stop mixing live portfolio units, historical units, and notional values implicitly.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Backtest scenario portfolio inputs are expressed via unit-safe Decimal types at the domain boundary
|
|
||||||
- Event-comparison scenario materialization uses explicit conversions from workspace value basis to historical units
|
|
||||||
- Historical entry spot, underlying units, and resulting notionals are no longer mixed as raw floats in core scenario setup paths
|
|
||||||
- Deterministic test/demo paths still work and remain browser-tested
|
|
||||||
- Tests cover both correct conversions and fail-closed invalid unit combinations
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Focus first on scenario/materialization boundaries and summary calculations rather than every chart payload
|
|
||||||
- Preserve deterministic fixture behavior while tightening the domain model
|
|
||||||
- This slice should make the current `gold_value -> historical underlying_units` conversion explicit in the type system
|
|
||||||
|
|
||||||
**Dependencies:** CORE-001A, BT-001, BT-003A
|
|
||||||
|
|
||||||
### CORE-001D: External Boundary and Persistence Cleanup for Decimal Unit Types [P2, M] **[depends: CORE-001B, CORE-001C]**
|
|
||||||
**As a** developer, **I want** persistence and service boundaries to handle Decimal unit-safe types explicitly **so that** the new model remains reliable across JSON, APIs, caches, and third-party integrations.
|
|
||||||
|
|
||||||
**Acceptance Criteria:**
|
|
||||||
- Persistence format for unit-safe values is explicit and stable
|
|
||||||
- JSON/API serialization for Decimal-bearing unit objects is documented and tested
|
|
||||||
- Float-heavy provider integrations have named conversion boundaries
|
|
||||||
- Remaining raw-float domain hotspots are identified or removed
|
|
||||||
- Developer docs note when to use unit-safe value objects vs primitive edge values
|
|
||||||
|
|
||||||
**Technical Notes:**
|
|
||||||
- Keep transport/persistence schemas boring and explicit; avoid magic implicit coercion
|
|
||||||
- Consider typed DTOs at the edges if needed to keep core domain objects strict
|
|
||||||
- This is the cleanup slice that reduces backsliding after the initial migrations
|
|
||||||
|
|
||||||
**Dependencies:** CORE-001B, CORE-001C
|
|
||||||
|
|
||||||
## Implementation Priority Queue
|
|
||||||
|
|
||||||
1. **CORE-001A** - Introduce Decimal-based unit/value object foundations before more calculation drift accumulates
|
|
||||||
2. **CORE-001B** - Migrate overview and hedge to unit-safe types on the most user-visible paths
|
|
||||||
3. **PORT-004** - Continue hashed workspace persistence as the new state foundation
|
|
||||||
4. **BT-001B** - Prefill backtest UIs from canonical saved portfolio settings
|
|
||||||
5. **CORE-001C** - Migrate backtests and event comparison to unit-safe scenario/value handling
|
|
||||||
6. **BT-003B** - Add event-comparison drilldown and explanation of ranking outcomes
|
|
||||||
7. **PORT-003** - Historical LTV visibility and export groundwork
|
|
||||||
8. **BT-002** - Upgrade backtests to real daily options snapshots
|
|
||||||
9. **BT-001C** - Consolidate deterministic historical fixture/demo provider logic
|
|
||||||
10. **CORE-001D** - Clean up persistence and external boundaries for Decimal unit-safe types
|
|
||||||
11. **EXEC-001** - Core user workflow
|
|
||||||
12. **EXEC-002** - Execution capability
|
|
||||||
13. Remaining features
|
|
||||||
62
docs/roadmap/ROADMAP.yaml
Normal file
62
docs/roadmap/ROADMAP.yaml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
version: 1
|
||||||
|
updated_at: 2026-03-24
|
||||||
|
structure:
|
||||||
|
backlog_dir: docs/roadmap/backlog
|
||||||
|
in_progress_dir: docs/roadmap/in-progress
|
||||||
|
done_dir: docs/roadmap/done
|
||||||
|
blocked_dir: docs/roadmap/blocked
|
||||||
|
cancelled_dir: docs/roadmap/cancelled
|
||||||
|
notes:
|
||||||
|
- ROADMAP.md is now a human-readable compatibility index.
|
||||||
|
- One task lives in one YAML file and changes state by moving between status folders.
|
||||||
|
- Priority ordering is maintained here so agents can parse one short file first.
|
||||||
|
priority_queue:
|
||||||
|
- SEC-001
|
||||||
|
- SEC-001A
|
||||||
|
- CORE-001D
|
||||||
|
- BT-003B
|
||||||
|
- PORT-003
|
||||||
|
- BT-002
|
||||||
|
- BT-001C
|
||||||
|
- EXEC-001
|
||||||
|
- EXEC-002
|
||||||
|
recently_completed:
|
||||||
|
- CORE-001A
|
||||||
|
- CORE-001B
|
||||||
|
- CORE-001C
|
||||||
|
- PORT-004
|
||||||
|
- BT-001A
|
||||||
|
- BT-003A
|
||||||
|
states:
|
||||||
|
backlog:
|
||||||
|
- SEC-001
|
||||||
|
- SEC-001A
|
||||||
|
- DATA-002A
|
||||||
|
- DATA-001A
|
||||||
|
- OPS-001
|
||||||
|
- PORT-003
|
||||||
|
- EXEC-001
|
||||||
|
- EXEC-002
|
||||||
|
- BT-002
|
||||||
|
- BT-003
|
||||||
|
- BT-003B
|
||||||
|
- BT-001C
|
||||||
|
- CORE-001D
|
||||||
|
in_progress: []
|
||||||
|
done:
|
||||||
|
- DATA-001
|
||||||
|
- DATA-002
|
||||||
|
- DATA-003
|
||||||
|
- PORT-001
|
||||||
|
- PORT-001A
|
||||||
|
- PORT-002
|
||||||
|
- PORT-004
|
||||||
|
- EXEC-001A
|
||||||
|
- BT-001
|
||||||
|
- BT-001A
|
||||||
|
- BT-003A
|
||||||
|
- CORE-001A
|
||||||
|
- CORE-001B
|
||||||
|
- CORE-001C
|
||||||
|
blocked: []
|
||||||
|
cancelled: []
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
id: BT-001C
|
||||||
|
title: Shared Historical Fixture/Test Provider Cleanup
|
||||||
|
status: backlog
|
||||||
|
priority: P2
|
||||||
|
effort: S
|
||||||
|
depends_on:
|
||||||
|
- BT-001A
|
||||||
|
- BT-003A
|
||||||
|
tags: [backtesting, test-infra]
|
||||||
|
summary: Centralize deterministic historical fixture logic used by browser-tested backtest UIs.
|
||||||
|
acceptance_criteria:
|
||||||
|
- Deterministic historical fixture/provider logic is centralized.
|
||||||
|
- Supported seeded windows are explicit and fail closed outside allowed ranges.
|
||||||
|
- Both /backtests and /event-comparison use the shared deterministic provider.
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
id: BT-002
|
||||||
|
title: Historical Daily Options Snapshot Provider
|
||||||
|
status: backlog
|
||||||
|
priority: P2
|
||||||
|
effort: L
|
||||||
|
depends_on:
|
||||||
|
- BT-001
|
||||||
|
tags: [backtesting, data]
|
||||||
|
summary: Support real daily historical options premiums in backtests.
|
||||||
|
acceptance_criteria:
|
||||||
|
- Historical provider abstraction supports point-in-time daily option snapshots.
|
||||||
|
- Backtests can swap synthetic pricing for observed historical premiums.
|
||||||
|
- Contract selection avoids lookahead bias.
|
||||||
|
- Provider/data-quality tradeoffs are documented.
|
||||||
13
docs/roadmap/backlog/BT-003-selloff-event-report.yaml
Normal file
13
docs/roadmap/backlog/BT-003-selloff-event-report.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
id: BT-003
|
||||||
|
title: Selloff Event Comparison Report
|
||||||
|
status: backlog
|
||||||
|
priority: P2
|
||||||
|
effort: M
|
||||||
|
depends_on:
|
||||||
|
- BT-001
|
||||||
|
tags: [backtesting, events]
|
||||||
|
summary: Rank named strategies across historical selloff events.
|
||||||
|
acceptance_criteria:
|
||||||
|
- Event presets define named windows.
|
||||||
|
- Reports rank strategies by survival, max LTV, cost, and final equity.
|
||||||
|
- UI can show unhedged vs hedged path comparisons.
|
||||||
14
docs/roadmap/backlog/BT-003B-event-comparison-drilldown.yaml
Normal file
14
docs/roadmap/backlog/BT-003B-event-comparison-drilldown.yaml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
id: BT-003B
|
||||||
|
title: Event Comparison Drilldown
|
||||||
|
status: backlog
|
||||||
|
priority: P1
|
||||||
|
effort: M
|
||||||
|
depends_on:
|
||||||
|
- BT-003A
|
||||||
|
tags: [backtesting, ui]
|
||||||
|
summary: Explain why one ranked strategy beat another on the event comparison page.
|
||||||
|
acceptance_criteria:
|
||||||
|
- Selecting a ranked strategy shows daily path details.
|
||||||
|
- UI exposes margin-call days, payoff realized, hedge cost, and final equity.
|
||||||
|
- Worst LTV point and breach dates are highlighted.
|
||||||
|
- Browser test verifies drilldown content updates when selecting a ranked result.
|
||||||
15
docs/roadmap/backlog/CORE-001D-decimal-boundary-cleanup.yaml
Normal file
15
docs/roadmap/backlog/CORE-001D-decimal-boundary-cleanup.yaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
id: CORE-001D
|
||||||
|
title: External Boundary and Persistence Cleanup for Decimal Unit Types
|
||||||
|
status: backlog
|
||||||
|
priority: P2
|
||||||
|
effort: M
|
||||||
|
depends_on:
|
||||||
|
- CORE-001B
|
||||||
|
- CORE-001C
|
||||||
|
tags: [core, decimal, persistence]
|
||||||
|
summary: Make Decimal/unit-safe values reliable across persistence, APIs, and provider boundaries.
|
||||||
|
acceptance_criteria:
|
||||||
|
- Persistence format for unit-safe values is explicit and stable.
|
||||||
|
- Decimal-bearing JSON/API serialization is documented and tested.
|
||||||
|
- Float-heavy integrations have named conversion boundaries.
|
||||||
|
- Remaining raw-float domain hotspots are identified or removed.
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
id: DATA-001A
|
||||||
|
title: Live Overview Price Wiring
|
||||||
|
status: backlog
|
||||||
|
priority: P0
|
||||||
|
effort: S
|
||||||
|
depends_on:
|
||||||
|
- DATA-001
|
||||||
|
- PORT-001
|
||||||
|
tags: [overview, pricing]
|
||||||
|
summary: Use the live price service directly on the overview page.
|
||||||
|
acceptance_criteria:
|
||||||
|
- Overview uses live quote data instead of a hardcoded spot.
|
||||||
|
- Source and last-updated metadata are displayed.
|
||||||
|
- Margin-call and LTV values use configured portfolio inputs.
|
||||||
|
- Browser test verifies visible live data metadata.
|
||||||
15
docs/roadmap/backlog/DATA-002A-lazy-options-loading.yaml
Normal file
15
docs/roadmap/backlog/DATA-002A-lazy-options-loading.yaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
id: DATA-002A
|
||||||
|
title: Lazy Options Loading
|
||||||
|
status: backlog
|
||||||
|
priority: P0
|
||||||
|
effort: S
|
||||||
|
depends_on:
|
||||||
|
- DATA-002
|
||||||
|
tags: [options, performance]
|
||||||
|
summary: Render the options page fast by loading only the minimum data initially.
|
||||||
|
acceptance_criteria:
|
||||||
|
- Initial page load fetches expirations plus one default expiry chain.
|
||||||
|
- Changing expiry fetches only that expiry on demand.
|
||||||
|
- Browser test verifies /options becomes visible quickly with no visible runtime error.
|
||||||
|
technical_notes:
|
||||||
|
- Keep initial render fast and move additional data loading behind user selection.
|
||||||
13
docs/roadmap/backlog/EXEC-001-strategy-builder.yaml
Normal file
13
docs/roadmap/backlog/EXEC-001-strategy-builder.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
id: EXEC-001
|
||||||
|
title: Strategy Builder
|
||||||
|
status: backlog
|
||||||
|
priority: P1
|
||||||
|
effort: L
|
||||||
|
depends_on:
|
||||||
|
- DATA-003
|
||||||
|
tags: [strategies, hedge]
|
||||||
|
summary: Build and compare hedge strategies from the product UI.
|
||||||
|
acceptance_criteria:
|
||||||
|
- Select strategy type, strikes, and expirations.
|
||||||
|
- Show payoff diagrams and compare cost vs protection.
|
||||||
|
- Store strategy templates for reuse.
|
||||||
13
docs/roadmap/backlog/EXEC-002-ibkr-order-integration.yaml
Normal file
13
docs/roadmap/backlog/EXEC-002-ibkr-order-integration.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
id: EXEC-002
|
||||||
|
title: IBKR Order Integration
|
||||||
|
status: backlog
|
||||||
|
priority: P2
|
||||||
|
effort: L
|
||||||
|
depends_on:
|
||||||
|
- EXEC-001
|
||||||
|
tags: [broker, execution]
|
||||||
|
summary: Execute hedge trades directly from the dashboard.
|
||||||
|
acceptance_criteria:
|
||||||
|
- Support IBKR paper trading first.
|
||||||
|
- Preview order, execute, and track status.
|
||||||
|
- Securely store credentials and maintain audit history.
|
||||||
15
docs/roadmap/backlog/OPS-001-public-caddy-route.yaml
Normal file
15
docs/roadmap/backlog/OPS-001-public-caddy-route.yaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
id: OPS-001
|
||||||
|
title: Public Caddy Route for Lombard Dashboard
|
||||||
|
status: backlog
|
||||||
|
priority: P1
|
||||||
|
effort: S
|
||||||
|
depends_on: []
|
||||||
|
tags: [ops, deploy, routing]
|
||||||
|
summary: Move the production route to public HTTPS at lombard.uncloud.tech.
|
||||||
|
acceptance_criteria:
|
||||||
|
- Caddy proxies lombard.uncloud.tech to the deployment container.
|
||||||
|
- HTTPS works with a valid certificate.
|
||||||
|
- Health check succeeds through Caddy.
|
||||||
|
- Deployment docs note that vd1.uncloud.vpn was retired in favor of the public route.
|
||||||
|
technical_notes:
|
||||||
|
- Keep public-exposure controls aligned with SEC-001 Turnstile bootstrap protection.
|
||||||
13
docs/roadmap/backlog/PORT-003-historical-ltv-chart.yaml
Normal file
13
docs/roadmap/backlog/PORT-003-historical-ltv-chart.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
id: PORT-003
|
||||||
|
title: Historical LTV Chart
|
||||||
|
status: backlog
|
||||||
|
priority: P2
|
||||||
|
effort: M
|
||||||
|
depends_on:
|
||||||
|
- PORT-001
|
||||||
|
tags: [portfolio, history, charts]
|
||||||
|
summary: Record and display historical LTV snapshots.
|
||||||
|
acceptance_criteria:
|
||||||
|
- Store LTV snapshots over time.
|
||||||
|
- Display 7/30/90 day charts with the margin threshold line.
|
||||||
|
- Allow export as CSV.
|
||||||
26
docs/roadmap/backlog/SEC-001-turnstile-captcha.yaml
Normal file
26
docs/roadmap/backlog/SEC-001-turnstile-captcha.yaml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
id: SEC-001
|
||||||
|
title: Turnstile CAPTCHA for Public Workspace Bootstrap
|
||||||
|
status: backlog
|
||||||
|
priority: P0
|
||||||
|
effort: M
|
||||||
|
depends_on:
|
||||||
|
- PORT-004
|
||||||
|
tags:
|
||||||
|
- security
|
||||||
|
- public-exposure
|
||||||
|
- workspace
|
||||||
|
summary: >
|
||||||
|
Require Cloudflare Turnstile verification before creating a workspace from the
|
||||||
|
public welcome page on lombard.uncloud.tech.
|
||||||
|
acceptance_criteria:
|
||||||
|
- Welcome/bootstrap flow at / and /workspaces/bootstrap requires valid Turnstile verification before creating a workspace.
|
||||||
|
- Workspace creation fails closed when the Turnstile token is missing, invalid, expired, or verification cannot be completed.
|
||||||
|
- Existing users with a valid workspace cookie visiting / are redirected to their workspace without solving CAPTCHA again.
|
||||||
|
- UI shows a clear user-facing retry path when CAPTCHA verification fails.
|
||||||
|
- Server-side verification uses TURNSTILE_SECRET_KEY and does not trust client-side success alone.
|
||||||
|
- Browser test covers protected bootstrap flow using Cloudflare Turnstile test keys in local/dev mode.
|
||||||
|
technical_notes:
|
||||||
|
- Use Cloudflare Turnstile only on the welcome/bootstrap flow, not on normal workspace navigation.
|
||||||
|
- Keep verification in a focused server-side seam such as app/services/turnstile.py.
|
||||||
|
- Use Cloudflare's published Turnstile test keys for deterministic local/browser coverage.
|
||||||
|
- This story exists because the app is now publicly reachable at https://lombard.uncloud.tech.
|
||||||
23
docs/roadmap/backlog/SEC-001A-turnstile-config.yaml
Normal file
23
docs/roadmap/backlog/SEC-001A-turnstile-config.yaml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
id: SEC-001A
|
||||||
|
title: Turnstile Config, Test Keys, and Deployment Wiring
|
||||||
|
status: backlog
|
||||||
|
priority: P0
|
||||||
|
effort: S
|
||||||
|
depends_on:
|
||||||
|
- SEC-001
|
||||||
|
tags:
|
||||||
|
- security
|
||||||
|
- config
|
||||||
|
- deploy
|
||||||
|
summary: >
|
||||||
|
Wire Cloudflare Turnstile configuration cleanly across local dev, tests, CI,
|
||||||
|
and production deployment.
|
||||||
|
acceptance_criteria:
|
||||||
|
- App config supports environment-driven TURNSTILE_SITE_KEY and TURNSTILE_SECRET_KEY.
|
||||||
|
- Local/dev defaults can use Cloudflare's documented Turnstile test keys.
|
||||||
|
- Forgejo deploy/runtime path passes vars.TURNSTILE_SITE_KEY and secrets.TURNSTILE_SECRET_KEY into the app environment.
|
||||||
|
- Missing production keys fail loudly in public/prod mode rather than silently disabling CAPTCHA.
|
||||||
|
- Docs explain local vs production key usage and browser-test setup.
|
||||||
|
technical_notes:
|
||||||
|
- Secret key must remain server-side only.
|
||||||
|
- Prefer explicit settings validation over silent fallback in production.
|
||||||
9
docs/roadmap/done/BT-001-synthetic-backtesting.yaml
Normal file
9
docs/roadmap/done/BT-001-synthetic-backtesting.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
id: BT-001
|
||||||
|
title: Synthetic Historical Backtesting
|
||||||
|
status: done
|
||||||
|
priority: P1
|
||||||
|
effort: L
|
||||||
|
depends_on:
|
||||||
|
- EXEC-001A
|
||||||
|
- PORT-001
|
||||||
|
summary: Synthetic historical backtesting engine ships with deterministic and optional provider-backed paths.
|
||||||
10
docs/roadmap/done/BT-001A-backtest-ui.yaml
Normal file
10
docs/roadmap/done/BT-001A-backtest-ui.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
id: BT-001A
|
||||||
|
title: Backtest Scenario Runner UI
|
||||||
|
status: done
|
||||||
|
priority: P1
|
||||||
|
effort: M
|
||||||
|
depends_on:
|
||||||
|
- BT-001
|
||||||
|
- EXEC-001A
|
||||||
|
- PORT-001
|
||||||
|
summary: Thin read-only /backtests UI over the synthetic backtest engine.
|
||||||
9
docs/roadmap/done/BT-003A-event-comparison-ui.yaml
Normal file
9
docs/roadmap/done/BT-003A-event-comparison-ui.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
id: BT-003A
|
||||||
|
title: Event Comparison UI Read Path
|
||||||
|
status: done
|
||||||
|
priority: P1
|
||||||
|
effort: M
|
||||||
|
depends_on:
|
||||||
|
- BT-003
|
||||||
|
- BT-001A
|
||||||
|
summary: Thin read-only /event-comparison UI over EventComparisonService.
|
||||||
12
docs/roadmap/done/CORE-001A-decimal-unit-foundation.yaml
Normal file
12
docs/roadmap/done/CORE-001A-decimal-unit-foundation.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
id: CORE-001A
|
||||||
|
title: Decimal Unit Value Object Foundation
|
||||||
|
status: done
|
||||||
|
priority: P1
|
||||||
|
effort: M
|
||||||
|
depends_on:
|
||||||
|
- CORE-001
|
||||||
|
summary: Introduced Decimal-backed unit-aware domain primitives.
|
||||||
|
references:
|
||||||
|
- docs/CORE-001A_DECIMAL_UNITS_ARCHITECTURE.md
|
||||||
|
completed_notes:
|
||||||
|
- Added Money, Weight, PricePerWeight, BaseCurrency, and WeightUnit.
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
id: CORE-001B
|
||||||
|
title: Overview and Hedge Migration to Unit-Safe Types
|
||||||
|
status: done
|
||||||
|
priority: P1
|
||||||
|
effort: M
|
||||||
|
depends_on:
|
||||||
|
- CORE-001A
|
||||||
|
- PORT-001A
|
||||||
|
summary: Overview and hedge calculations now route through shared Decimal/unit-backed math.
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
id: CORE-001C
|
||||||
|
title: Backtests and Event Comparison Migration to Unit-Safe Types
|
||||||
|
status: done
|
||||||
|
priority: P1
|
||||||
|
effort: M
|
||||||
|
depends_on:
|
||||||
|
- CORE-001A
|
||||||
|
- BT-001
|
||||||
|
- BT-003A
|
||||||
|
summary: Historical-unit materialization now uses explicit typed asset quantity and price seams.
|
||||||
10
docs/roadmap/done/DATA-001-live-price-feed.yaml
Normal file
10
docs/roadmap/done/DATA-001-live-price-feed.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
id: DATA-001
|
||||||
|
title: Live Price Feed Integration
|
||||||
|
status: done
|
||||||
|
priority: P0
|
||||||
|
effort: M
|
||||||
|
depends_on: []
|
||||||
|
summary: Live quote service integrated with visible metadata and cache behavior.
|
||||||
|
completed_notes:
|
||||||
|
- Added app/services/price_feed.py.
|
||||||
|
- Overview and dependent pages can consume live quote metadata.
|
||||||
10
docs/roadmap/done/DATA-002-options-chain.yaml
Normal file
10
docs/roadmap/done/DATA-002-options-chain.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
id: DATA-002
|
||||||
|
title: Options Chain Data
|
||||||
|
status: done
|
||||||
|
priority: P0
|
||||||
|
effort: L
|
||||||
|
depends_on:
|
||||||
|
- DATA-001
|
||||||
|
summary: Live options chain data integrated with caching and page wiring.
|
||||||
|
completed_notes:
|
||||||
|
- Options page uses live chain data and runtime service registry.
|
||||||
10
docs/roadmap/done/DATA-003-greeks-calculation.yaml
Normal file
10
docs/roadmap/done/DATA-003-greeks-calculation.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
id: DATA-003
|
||||||
|
title: Greeks Calculation
|
||||||
|
status: done
|
||||||
|
priority: P1
|
||||||
|
effort: M
|
||||||
|
depends_on:
|
||||||
|
- DATA-002
|
||||||
|
summary: Real option Greeks are calculated and displayed.
|
||||||
|
completed_notes:
|
||||||
|
- Added live Greeks calculation and Vega display.
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
id: EXEC-001A
|
||||||
|
title: Named Strategy Templates
|
||||||
|
status: done
|
||||||
|
priority: P1
|
||||||
|
effort: M
|
||||||
|
depends_on:
|
||||||
|
- DATA-003
|
||||||
|
summary: Named reusable strategy templates are available to live and backtest flows.
|
||||||
10
docs/roadmap/done/PORT-001-portfolio-state.yaml
Normal file
10
docs/roadmap/done/PORT-001-portfolio-state.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
id: PORT-001
|
||||||
|
title: Portfolio State Management
|
||||||
|
status: done
|
||||||
|
priority: P0
|
||||||
|
effort: M
|
||||||
|
depends_on:
|
||||||
|
- DATA-001
|
||||||
|
summary: Configurable persisted portfolio state with validation.
|
||||||
|
completed_notes:
|
||||||
|
- Added PortfolioConfig and file-backed persistence.
|
||||||
10
docs/roadmap/done/PORT-001A-collateral-entry-basis.yaml
Normal file
10
docs/roadmap/done/PORT-001A-collateral-entry-basis.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
id: PORT-001A
|
||||||
|
title: Collateral Entry Basis in Settings
|
||||||
|
status: done
|
||||||
|
priority: P1
|
||||||
|
effort: M
|
||||||
|
depends_on:
|
||||||
|
- PORT-001
|
||||||
|
summary: Settings support canonical weight/value entry basis handling.
|
||||||
|
completed_notes:
|
||||||
|
- Entry price, weight, and value basis now normalize consistently.
|
||||||
8
docs/roadmap/done/PORT-002-alert-notifications.yaml
Normal file
8
docs/roadmap/done/PORT-002-alert-notifications.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
id: PORT-002
|
||||||
|
title: Alert Notifications
|
||||||
|
status: done
|
||||||
|
priority: P1
|
||||||
|
effort: M
|
||||||
|
depends_on:
|
||||||
|
- PORT-001
|
||||||
|
summary: Alert status and history are persisted and visible in product UI.
|
||||||
12
docs/roadmap/done/PORT-004-workspace-persistence.yaml
Normal file
12
docs/roadmap/done/PORT-004-workspace-persistence.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
id: PORT-004
|
||||||
|
title: Hashed Workspace Persistence
|
||||||
|
status: done
|
||||||
|
priority: P0
|
||||||
|
effort: L
|
||||||
|
depends_on:
|
||||||
|
- PORT-001
|
||||||
|
summary: Workspace-scoped URLs and server-side persistence now drive the product state model.
|
||||||
|
completed_notes:
|
||||||
|
- / is a welcome/bootstrap page.
|
||||||
|
- Workspace routes exist for overview, settings, hedge, backtests, and event comparison.
|
||||||
|
- Cookie stores only workspace_id.
|
||||||
Reference in New Issue
Block a user