221 lines
10 KiB
Markdown
221 lines
10 KiB
Markdown
# Web PRD (Source of Truth)
|
|
|
|
## 1. Scope
|
|
This document defines the product behavior for the Streamlit web app in `web/src/`.
|
|
|
|
This PRD is intentionally web-only:
|
|
- Data fetch and analysis logic
|
|
- Classification/trend rules
|
|
- Filters, chart behavior, exports, and persisted settings
|
|
|
|
Out of scope:
|
|
- macOS shell/wrapper architecture and packaging
|
|
|
|
## 2. Product Goal
|
|
Provide an analysis-only charting tool that classifies OHLC bars as real/fake, tracks trend state using only real bars, and exposes clear visual, training-oriented guidance, and exportable outputs.
|
|
|
|
## 3. Inputs and Data Pipeline
|
|
1. User configures:
|
|
- `symbol`
|
|
- optional `watchlist` (per-profile)
|
|
- `interval`
|
|
- `period`
|
|
- `max_bars`
|
|
- optional `market_preset`
|
|
- filter/toggle settings
|
|
- optional advanced controls (alerts, replay, compare symbols, backtest controls, regime filter)
|
|
2. App fetches OHLCV via Yahoo Finance (`yfinance`).
|
|
- For day-based periods (for example `1d`, `5d`), fetch widens calendar lookback as needed, then trims to the latest N trading days that actually contain bars.
|
|
3. Optional last-bar drop (live-bar guard) for intraday intervals.
|
|
4. Bars are classified (`real_bull`, `real_bear`, `fake`, `unclassified` for first bar).
|
|
5. Trend state is derived from classification sequence.
|
|
6. UI renders metrics, chart, events, and export artifacts.
|
|
|
|
## 4. Settings Contract
|
|
Persisted settings path:
|
|
- Primary: `~/.web_local_shell/settings.json`
|
|
- Legacy fallback read: `~/.manesh_trader/settings.json`
|
|
|
|
Storage format:
|
|
- Current format stores per-profile settings:
|
|
- `last_profile`: most recently used profile id
|
|
- `profiles`: object map of `profile_id -> profile record`
|
|
- profile record fields:
|
|
- `settings`: normalized settings payload
|
|
- `pin_hash`: optional SHA-256 hash for 4-6 digit PIN
|
|
- `audit`: metadata (`created_at`, `updated_at`, `last_login_at`, `last_symbol`)
|
|
- Legacy single-profile payloads are read as profile `default` and migrated to current format on next save.
|
|
|
|
Profile behavior:
|
|
- App enforces a profile login gate before data/settings UI is shown.
|
|
- Login requires typing an existing profile name.
|
|
- Login checks PIN when profile has one configured.
|
|
- Login includes `Remember me on this browser`.
|
|
- Create Profile requires typing a new profile name.
|
|
- Create Profile accepts optional 4-6 digit PIN.
|
|
- Profile-name uniqueness is case-insensitive (for example `Matt` and `matt` are treated as duplicates).
|
|
- Sidebar shows active profile with a `Switch profile` control.
|
|
- Sidebar shows profile audit stamps (created/updated/last login/last symbol).
|
|
- Query param `profile` selects active profile.
|
|
- Save/load are scoped to active profile to avoid cross-user overwrites.
|
|
- If profile has no saved settings, defaults are used.
|
|
- Session activity is tracked in-memory; after 30 minutes of inactivity the app clears active profile and returns to login screen.
|
|
- If `remember=1` is present with a known non-PIN profile, app auto-restores that profile without showing login.
|
|
- PIN-protected profiles always require PIN entry after session timeout/reopen.
|
|
|
|
Watchlist and preset behavior:
|
|
- `watchlist` is saved per profile and supports comma/newline input.
|
|
- Watchlist supports one-click symbol quick-select buttons.
|
|
- `market_preset` applies tuned defaults for common workflows (`Custom`, `Stocks Swing`, `Crypto Intraday`, `Crypto Swing`).
|
|
- Preset application affects defaults for timeframe/period/max bars and related monitoring/gap options.
|
|
|
|
Advanced feature behavior:
|
|
- Multi-timeframe confirmation (`1h`, `4h`, `1d`) can show consensus trend and agreement percent.
|
|
- Alert rules can trigger on bullish/bearish trend events and optionally POST JSON payloads to a webhook URL.
|
|
- Session stats track since-login wins/losses, average move after signal, and fake-bar rate for visible data.
|
|
- Backtest controls include slippage/fees (bps), optional stop-loss/take-profit %, and min/max hold bars.
|
|
- Signal quality score combines trend state, volume-filter usage, and recent fake-bar density.
|
|
- Replay mode limits visible bars to first N rows to simulate no-hindsight review.
|
|
- Compare symbols panel can summarize trend/regime/fake-ratio for a small basket.
|
|
- Regime filter flags choppy periods and can suppress directional bias.
|
|
|
|
Normalization constraints:
|
|
- `symbol`: uppercase, non-empty fallback `AAPL`
|
|
- `interval`: must be one of `INTERVAL_OPTIONS`, fallback `1d`
|
|
- `period`: must be one of `PERIOD_OPTIONS`, fallback `6mo`
|
|
- `max_bars`: `[20, 5000]`, fallback `500`
|
|
- `volume_sma_window`: `[2, 100]`, fallback `20`
|
|
- `volume_multiplier`: `[0.1, 3.0]`, rounded to 0.1, fallback `1.0`
|
|
- `refresh_sec`: `[10, 600]`, fallback `60`
|
|
- `show_live_guide`: boolean, fallback `false`
|
|
- `show_past_behavior`: boolean, fallback `false`
|
|
- `show_trade_markers`: boolean, fallback `false`
|
|
- `focus_chart_on_selected_example`: boolean, fallback `false`
|
|
- `max_training_examples`: `[5, 100]`, fallback `20`
|
|
- `watchlist`: uppercase de-duplicated symbol list, max 40 items
|
|
- `market_preset`: one of `Custom`, `Stocks Swing`, `Crypto Intraday`, `Crypto Swing`, fallback `Custom`
|
|
- `compare_symbols`: uppercase de-duplicated symbol list, max 12 items
|
|
- `alert_webhook_url`: optional string
|
|
- `backtest_slippage_bps`: `[0.0, 100.0]`, fallback `0.0`
|
|
- `backtest_fee_bps`: `[0.0, 100.0]`, fallback `0.0`
|
|
- `backtest_stop_loss_pct`: `[0.0, 25.0]`, fallback `0.0` (0 disables)
|
|
- `backtest_take_profit_pct`: `[0.0, 25.0]`, fallback `0.0` (0 disables)
|
|
- `backtest_min_hold_bars`: `[1, 20]`, fallback `1`
|
|
- `backtest_max_hold_bars`: `[1, 40]`, fallback `1` and clamped to `>= min_hold`
|
|
- `display_timezone`: one of `America/New_York`, `America/Chicago`, `America/Denver`, `America/Los_Angeles`, `America/Phoenix`, `America/Anchorage`, `Pacific/Honolulu`; fallback `America/Chicago`
|
|
- `use_24h_time`: boolean, fallback `false` (`false` => `1:00 PM`, `true` => `13:00`)
|
|
- booleans normalized from common truthy/falsy strings and numbers
|
|
|
|
## 5. Classification Rules
|
|
For each bar `i` (starting at index 1):
|
|
- Reference prior bar `i-1`.
|
|
- If `use_body_range = false`:
|
|
- `prev_high = prev.High`
|
|
- `prev_low = prev.Low`
|
|
- If `use_body_range = true`:
|
|
- `prev_high = max(prev.Open, prev.Close)`
|
|
- `prev_low = min(prev.Open, prev.Close)`
|
|
|
|
Volume filter:
|
|
- If enabled, `volume_ok = Volume >= SMA(Volume, volume_sma_window) * volume_multiplier`
|
|
- If `volume_ok` is false, classification is `fake` regardless of price break.
|
|
|
|
Price logic (when volume is OK):
|
|
- `Close > prev_high` -> `real_bull`
|
|
- `Close < prev_low` -> `real_bear`
|
|
- otherwise -> `fake`
|
|
|
|
First bar is always `unclassified`.
|
|
|
|
## 6. Trend-State Rules
|
|
Trend states:
|
|
- `No Active Trend`
|
|
- `Bullish Trend Active`
|
|
- `Bearish Trend Active`
|
|
|
|
State machine:
|
|
- From neutral:
|
|
- 2 consecutive `real_bull` -> bullish trend started
|
|
- 2 consecutive `real_bear` -> bearish trend started
|
|
- From bullish:
|
|
- 2 consecutive `real_bear` -> bearish reversal confirmed
|
|
- From bearish:
|
|
- 2 consecutive `real_bull` -> bullish reversal confirmed
|
|
|
|
Important:
|
|
- `fake` bars do not increment opposite-run counters enough to reverse trend.
|
|
|
|
## 7. Chart and Visualization Behavior
|
|
- Main candlestick chart with bullish/bearish markers:
|
|
- `real_bull`: green triangle-up
|
|
- `real_bear`: red triangle-down
|
|
- Optional fake-bar de-emphasis via gray candle layer (`gray_fake`).
|
|
- Optional example-trade overlay markers (`show_trade_markers`):
|
|
- long entry marker
|
|
- short entry marker
|
|
- winning exit marker
|
|
- loss/flat exit marker
|
|
- If a past-behavior row is selected, chart highlights that trade window and path.
|
|
- Optional focused zoom around selected trade (`focus_chart_on_selected_example`).
|
|
- Volume subplot colored by trend state.
|
|
|
|
Gap handling (`hide_market_closed_gaps`):
|
|
- Always removes weekend gaps (`sat` -> `mon`).
|
|
- Removes full missing calendar days between first/last bar (for example market holidays with no bars).
|
|
- For intraday intervals, uses contiguous bar-order x-axis (no closed-session spacing) and day-level tick labels.
|
|
- For daily interval, weekend break removal is applied.
|
|
|
|
## 8. Help and Onboarding Behavior
|
|
- Web-only help entry exists in sidebar:
|
|
- `Help / Quick Start`
|
|
- Help appears in a dialog with multiple navigable screens (screen picker + previous/next).
|
|
- Help copy is intentionally beginner-friendly and explains each major sidebar control group, including detailed backtest controls and why each setting matters.
|
|
- Main page includes a beginner training block:
|
|
- `What This Tool Means (Beginner Training)`
|
|
- Plain-English definitions for top metrics (`Current Trend`, real/fake bars, `Signal Quality`, `Regime`, `Recent Fake Ratio`).
|
|
- Historical learning table with trailing windows (`1M`, `3M`, `6M`, `1Y`) computed from loaded data.
|
|
- Per-window interpretation text that summarizes whether behavior was trend-dominant, bearish-dominant, or choppy/noisy.
|
|
- The onboarding markdown remains project documentation; in-app help content is rendered from `web/src/web_core/ui/help_content.py`.
|
|
|
|
## 9. Outputs
|
|
- Metrics:
|
|
- current trend
|
|
- real bullish count
|
|
- real bearish count
|
|
- fake count
|
|
- beginner training guide (plain-English metric glossary)
|
|
- historical learning snapshots (`1M`, `3M`, `6M`, `1Y`) including price change, bar-type counts, trend flips, and interpretation
|
|
- Live decision guide (optional):
|
|
- bias (long/short/neutral)
|
|
- signal confirmation status
|
|
- latest bar interpretation
|
|
- action + invalidation guidance
|
|
- Trend events table (latest events), rendered in selected US display timezone and 12h/24h format
|
|
- Backtest snapshot:
|
|
- signal at trend-change rows to active bull/bear states
|
|
- advanced mode supports configurable costs/holds/stop/target
|
|
- Past behavior examples (optional training panel):
|
|
- historical examples using trend-confirmation entries and opposite-confirmation exits
|
|
- per-example direction, entry/exit timestamps (rendered in selected US display timezone and 12h/24h format), bars held, P/L%, and outcome
|
|
- aggregate example metrics (count, win/loss, win rate, average P/L)
|
|
- selectable table rows that drive chart highlight of chosen example
|
|
- plain-language explanation for selected example
|
|
- Exports:
|
|
- CSV always available
|
|
- PDF via Plotly image export (requires Kaleido runtime)
|
|
- Additional optional panels:
|
|
- multi-timeframe confirmation
|
|
- compare symbols snapshot
|
|
- session stats
|
|
|
|
## 10. Validation Expectations
|
|
Code-level checks:
|
|
- `python -m py_compile web/src/app.py`
|
|
- `PYTHONPATH=web/src pytest -q web/src/tests`
|
|
|
|
Behavior checks:
|
|
- No crash on missing/invalid persisted settings
|
|
- Symbol/interval/period invalid combinations show actionable data error
|
|
- Trend logic matches two-consecutive-real-bars contract
|
|
- Exports include normalized timestamp column
|