4 Commits

Author SHA1 Message Date
Alfred
1f9ce289d2 feat: 新增 DecisionSignal 反馈、后验验证与统计 P5 (#1710)
* feat: add decision signal outcomes and feedback

* fix: align outcome filters and retry rotation
2026-06-18 21:23:11 +08:00
mumu
9f4755bda2 Stabilize actionable stock decisions (#1245)
* fix: stabilize actionable decisions
2026-05-10 13:33:48 +08:00
[ZE]
0e47e8a737 fix(backtest): address PR #269 review comments (#277)
* fix(backtest): address PR #269 review comments

- Replace naive substring keyword matching with negation-aware
  _matches_intent that handles phrases like "do not sell" and "不要卖出"
- Default unrecognized/empty advice to cash instead of long to prevent
  contaminating backtest statistics with false long positions
- Separate wait (flat) from bearish (down) direction semantics so "wait"
  advice no longer inflates directional accuracy
- Move StockDaily access (get_start_daily, get_forward_bars) from
  BacktestRepository to StockRepository for proper separation of concerns

* refactor(backtest): simplify keyword matching internals

- Consolidate _NEGATION_EN/_NEGATION_ZH into single _NEGATION_PATTERNS
- Merge duplicate if-branches in infer_position_recommendation
- Simplify _is_negated to single any() expression
- Remove unused timedelta import from stock_repo

* feat(backtest): add eval_window_days and force controls to WebUI

- Add Window (eval_window_days) number input to backtest page
- Add Force toggle button that bypasses min_age_days filter
- Add min_age_days to BacktestRunRequest schema
- Pass eval_window_days filter to results and performance endpoints
  so table and summary always show consistent data for the same window
- Thread eval_window_days through performance API (backend + frontend)

* fix(backtest): show latest performance summary on page refresh

When no eval_window_days filter is specified, return the most recent
summary (by computed_at) instead of defaulting to config value 10.
This ensures the performance panel is populated on fresh page load
regardless of which window was used for the last backtest run.

* fix(backtest): filter results by eval_window_days consistently

On initial load, fetch the latest performance summary and use its
eval_window_days to filter results and pre-populate the Window input.
Also pass window filter through Filter button and pagination so all
views stay consistent.
2026-02-09 19:32:36 +08:00
[ZE]
dbe1cd7cae feat(backtest): add backtest engine with evaluation pipeline and WebUI (#269)
Add a complete backtest/evaluation system that measures the accuracy of
AI-generated stock analysis recommendations against actual market outcomes.

Backend:
- Backtest engine (src/core/backtest_engine.py) with direction inference,
  stop-loss/take-profit simulation, and outcome classification (win/loss/neutral)
- Repository layer (src/repositories/backtest_repo.py) with SQLite persistence
  for backtest_results and backtest_summaries tables
- Service layer (src/services/backtest_service.py) orchestrating evaluation runs
  with configurable window days, neutral band, and min-age filters
- REST API endpoints: POST /run, GET /results, GET /performance, GET /performance/{code}
- Pydantic schemas for request/response validation

Frontend (apps/dsa-web):
- New Backtest page with performance dashboard sidebar showing direction
  accuracy, win rate, simulated returns, SL/TP trigger rates, and W/L/N counts
- Paginated results table with outcome badges, direction indicators, and
  color-coded return percentages
- Stock code filter and one-click "Run Backtest" trigger
- Full TypeScript types and API client matching backend schemas

Direction mapping fix:
- "Wait/observe" (观望) advice now maps to direction_expected="down" instead
  of "flat", correctly reflecting that "wait" means "stay out due to downside
  risk" rather than predicting a flat market

Tests:
- 21 unit tests covering engine logic, service orchestration, and summary
  aggregation (all passing)

Docs:
- Updated README, full-guide, and translations with backtest feature docs
2026-02-08 14:49:50 +08:00