154 Commits

Author SHA1 Message Date
머니페니
98a161574e security: migrate JWT from localStorage to httpOnly cookie
Eliminates XSS token theft by storing JWT in httpOnly Secure cookie
instead of localStorage. Backend sets cookie on login and clears on
logout. Token extraction uses cookie-first with Authorization header
fallback for backward compatibility with existing tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 22:30:47 +09:00
머니페니
60d2221edc feat: add manual transaction entry UI with modal dialog
Add "거래 추가" button to the transactions tab with a modal dialog for
manually entering buy/sell transactions (ticker, type, quantity, price, memo).
Refreshes portfolio and transaction list after successful submission.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 22:22:56 +09:00
머니페니
4ea744ce62 feat: replace simulated sine wave chart with real snapshot data
Portfolio value chart now uses actual snapshot API data instead of
generated simulation. Shows empty state message when no snapshots exist.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 22:22:44 +09:00
머니페니
ee0de0504c feat: add portfolio edit/delete UI with confirmation dialogs
Add hover-visible edit (rename) and delete buttons to portfolio cards
on the list page, with modal dialogs for name editing and delete
confirmation. Uses existing PUT/DELETE API endpoints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 22:22:37 +09:00
머니페니
815f255ff5 feat: add React ErrorBoundary with retry and reload UI
Add class-based ErrorBoundary component that catches rendering errors
and shows a user-friendly fallback with retry/reload buttons. Wrap in
root layout to protect against full-page crashes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 22:22:29 +09:00
머니페니
f12709ea79 fix: add toast error feedback for API failures in signals and data explorer pages
Replace silent console.error-only handling with user-visible toast notifications
using sonner, while keeping console.error for debugging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 22:22:22 +09:00
머니페니
b80feb7176 perf: add DB performance indexes and fix N+1 query in backtest listing
Add 10 indexes across prices, etf_prices, financials, valuations,
holdings, transactions, signals, portfolio_snapshots, and etfs tables.
Fix N+1 query in list_backtests by eager-loading backtest results
with joinedload.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 22:20:29 +09:00
머니페니
4483f6e4ba feat: add DC pension ETF-only filter to strategy API
Add dc_only parameter to all strategy endpoints. When true, filters
results to include only tickers present in the ETF table, supporting
DC pension investment constraints where only ETFs are allowed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 20:57:47 +09:00
머니페니
62ac92eaaf feat: add minimum trade amount filter to rebalancing calculation
Add min_trade_amount parameter (default 10,000 KRW) to rebalance/calculate
endpoint. Trades below this threshold are converted to hold actions to avoid
inefficient micro-trades during rebalancing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 20:57:43 +09:00
머니페니
01f86298c4 feat: add strategy comparison UI for side-by-side multi-strategy analysis
Add a compare page at /strategy/compare that runs MultiFactor, Quality,
and ValueMomentum strategies simultaneously and displays results side-by-side
with common ticker highlighting and factor score comparison table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 20:57:38 +09:00
머니페니
9249821a25 feat: add realized/unrealized PnL tracking and position sizing guide
- Add realized_pnl column to transactions table with alembic migration
- Calculate realized PnL on sell transactions: (sell_price - avg_price) * quantity
- Show total realized/unrealized PnL in portfolio detail summary cards
- Show per-transaction realized PnL in transaction history table
- Add position sizing API endpoint (GET /portfolios/{id}/position-size)
- Show position sizing guide in signal execution modal for buy signals
- 8 new E2E tests, all 88 tests passing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 19:04:36 +09:00
머니페니
65618cd957 feat: add signal execution cancel with transaction rollback and holding restore 2026-03-18 18:56:29 +09:00
머니페니
213f03a8e5 fix: replace deprecated datetime.utcnow() and SQLAlchemy Query.get() 2026-03-18 18:53:29 +09:00
eb06dfc48b feat: implement scenario gap analysis - core loop completion
All checks were successful
Deploy to Production / deploy (push) Successful in 1m32s
Phase 1 (Critical):
- Add bulk rebalance apply API + UI with confirmation modal
- Add strategy results to portfolio targets flow (shared component)

Phase 2 (Important):
- Show current holdings in signal execute modal with auto-fill
- Add DC pension risk asset ratio warning (70% limit)
- Add KOSPI benchmark comparison to portfolio returns
- Track signal execution details (price, quantity, timestamp)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 18:18:15 +09:00
ea93e09059 chore: add .worktrees/ to .gitignore 2026-02-19 16:51:15 +09:00
c97bb8595e docs: add scenario gap analysis results and implementation plan
Expert team identified 12 gaps across 6 scenarios. Prioritized into
3 phases: Critical (rebalance apply, strategy-to-portfolio link),
Important (signal holdings, DC limits, benchmark, signal PnL),
and Nice-to-have (comparison UI, walk-forward, undo).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 16:44:40 +09:00
7cff4003d7 docs: add scenario-based gap analysis design for DC pension management
Define 6 core usage scenarios and expert team composition for
evaluating feature completeness of the quant portfolio management system.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 16:40:35 +09:00
a7366d053e feat: add manual signal execution to portfolio
Allow users to execute active KJB signals by selecting a portfolio,
entering quantity and price, then creating the corresponding transaction
and updating holdings. Signal status changes to 'executed' after completion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 16:10:48 +09:00
e6160fffc6 fix: add KJB strategy to frontend strategy list and backtest form
All checks were successful
Deploy to Production / deploy (push) Successful in 1m37s
- Add KJB card to strategy page with Zap icon
- Create /strategy/kjb detail page with ranking table and rules reference
- Add KJB option to backtest strategy dropdown
- Add KJB-specific params UI (max positions, cash reserve, stop-loss, targets)
- Hide rebalance period selector when KJB is selected (uses daily simulation)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:53:01 +09:00
7150227c88 feat: implement KJB (Kim Jong-bong) short-term trading strategy
All checks were successful
Deploy to Production / deploy (push) Successful in 1m44s
Full system: signal generator, daily backtest engine, trading portfolio,
signal API, scheduler job, and frontend dashboard.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:25:06 +09:00
f51f3cc4bf docs: add KJB strategy design doc, implementation plan, and quant notes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:25:00 +09:00
2d1983efff feat: add KJB signal dashboard frontend page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:19:54 +09:00
5268d1fa60 test: add E2E tests for KJB strategy, backtest, and signal endpoints
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:18:02 +09:00
3c969fc53c feat: wire KJB into backtest worker, add Signal API, add scheduler job
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:16:13 +09:00
8d1a2f7937 feat: add DailyBacktestEngine for KJB signal-based backtesting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:14:15 +09:00
65bc4cb623 feat: add KJBStrategy ranking class and API endpoint
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:12:18 +09:00
932b46c5fe feat: add KJBSignalGenerator for daily buy/sell signal detection
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:10:53 +09:00
0aac70886f feat: add TradingPortfolio for signal-based position management
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:08:36 +09:00
01d6b007f6 feat: add Signal Pydantic schemas
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:06:03 +09:00
a64636f6ff feat: add Signal model for KJB trading signals
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:05:17 +09:00
a33457ee6c feat: add pre-backtest data validation to detect missing price data
All checks were successful
Deploy to Production / deploy (push) Successful in 1m13s
Validates trading day count, benchmark coverage, per-date ticker
density, and date gaps before running simulation. Logs warnings for
holdings with missing prices during execution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 22:55:50 +09:00
5422383fd8 feat: add FinancialCollector for FnGuide financial statement scraping
All checks were successful
Deploy to Production / deploy (push) Successful in 1m8s
Port make-quant-py's FnGuide scraping logic into galaxy-po's
BaseCollector pattern. Collects annual and quarterly financial
statements (revenue, net income, total assets, etc.) and maps
Korean account names to English keys for FactorCalculator.
Scheduled weekly on Monday 19:00 KST since data updates quarterly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 22:38:05 +09:00
653fa08fa4 fix: use actual invested amounts for avg_price in seed data
All checks were successful
Deploy to Production / deploy (push) Successful in 1m48s
The seed script was incorrectly using the latest snapshot's market price
as avg_price, resulting in inflated average costs. Now computes avg_price
from actual total invested amounts per ticker.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 22:01:01 +09:00
238c4d1caf feat: accept valuation amount instead of price for rebalancing input
For holdings with quantity > 0, the input now accepts the total
valuation amount and derives the current price by dividing by quantity.
Holdings with quantity 0 (target-only) still accept price directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 21:51:05 +09:00
fe48e20642 fix: set scheduler timezone to KST for correct job execution times
CronTrigger had no explicit timezone, defaulting to system timezone
(UTC in Docker containers), causing jobs to run at KST 03:00/03:30
instead of the intended 18:00/18:30.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 21:45:08 +09:00
d12bf7b54f chore: old plan 2026-02-18 21:44:45 +09:00
a899c17a65 feat: generate transaction records from snapshot diffs in seed script
All checks were successful
Deploy to Production / deploy (push) Successful in 1m27s
Derive buy/sell transactions by comparing consecutive snapshots and
replace existing portfolio on re-run instead of skipping.
2026-02-16 20:56:12 +09:00
48417a03f5 feat: show stock names as primary display in history, strategy, and backtest pages
All checks were successful
Deploy to Production / deploy (push) Successful in 1m32s
2026-02-16 12:52:56 +09:00
87dff8bfa7 feat: show stock names as primary display in portfolio card, detail, and rebalance pages 2026-02-16 12:51:56 +09:00
628b431171 feat: include stock names in snapshot, transaction, and backtest transaction API responses 2026-02-16 12:50:21 +09:00
b6c22f70ae feat: add name field to SnapshotHoldingResponse, TransactionResponse, and backtest TransactionItem schemas 2026-02-16 12:49:18 +09:00
b92f8f298b docs: add stock name display implementation plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 12:47:13 +09:00
c836c133dd docs: add stock name display design
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 12:44:54 +09:00
98d8c1115e feat: add backfill API endpoint for historical data collection
All checks were successful
Deploy to Production / deploy (push) Successful in 1m12s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:35:31 +09:00
9b4d678995 feat: register daily collection job at 18:00 in scheduler
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:33:25 +09:00
f13be37470 feat: add backfill job for historical price data
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:31:59 +09:00
20240fdb4d feat: add backfill job for historical price data
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:29:36 +09:00
cc7ab311ed feat: add daily collection job orchestration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 00:27:06 +09:00
c8bb675ba4 feat: add data explorer to sidebar navigation and fix gitignore
All checks were successful
Deploy to Production / deploy (push) Successful in 1m30s
- Add "데이터 탐색" menu item to sidebar with Search icon
- Add "수집 데이터 조회" link button on data management page
- Fix sidebar active state to correctly distinguish /admin/data
  from /admin/data/explorer
- Add page title mapping for data explorer in header
- Fix .gitignore: add negation for frontend/src/app/admin/data/
  so admin data pages are tracked without needing git add -f
- Fix dashboard loading state (return null → skeleton with layout)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 23:54:09 +09:00
2858c87b1b fix: use named volume for production PostgreSQL to prevent data loss
Two issues caused DB reset on every deploy:

1. docker-compose.prod.yml used bind mount (./data/postgres) with
   PostgreSQL 18's incompatible /var/lib/postgresql/data path.

2. The Gitea CI runner shares Docker socket with the host, but
   ./data/postgres resolves to a temp path inside the runner container.
   Each deploy creates a fresh workspace, so the bind mount always
   points to an empty directory on the host.

Fix: Use a named Docker volume (same as docker-compose.yml dev config).
Named volumes are managed by Docker daemon directly, survive container
recreation, and don't depend on working directory resolution.

Also fix deploy.yml: remove unnecessary mkdir for data dirs, write
backup to /tmp instead of relative path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 23:47:46 +09:00