Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
{
"enabledPlugins": {
"frontend-design@claude-plugins-official": true,
"context7@claude-plugins-official": true,
"playwright@claude-plugins-official": true
"independent-reviewer@ed-tools": true
}
}
3 changes: 2 additions & 1 deletion .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ jobs:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
prompt: '/code-review:code-review --comment ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
claude_args: '--allowedTools "mcp__github_inline_comment__create_inline_comment"'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options

2 changes: 1 addition & 1 deletion .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,5 @@ jobs:
# Optional: Add claude_args to customize behavior and configuration
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
# claude_args: '--allowed-tools Bash(gh pr:*)'
# claude_args: '--allowed-tools Bash(gh pr *)'

82 changes: 40 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,61 +1,59 @@
# FinAlly — AI Trading Workstation

A visually stunning AI-powered trading workstation that streams live market data, simulates portfolio trading, and integrates an LLM chat assistant that can analyze positions and execute trades via natural language.
A trading terminal that streams live market data, simulates portfolio trading, and puts
an LLM assistant beside your positions — one that can analyze holdings and execute trades
from natural language.

Built entirely by coding agents as a capstone project for an agentic AI coding course.
Built entirely by coding agents as the capstone for an agentic AI coding course. Agents
coordinate through shared docs in [`planning/`](planning/).

## Features
## Status

- **Live price streaming** via SSE with green/red flash animations
- **Simulated portfolio** — $10k virtual cash, market orders, instant fills
- **Portfolio visualizations** — heatmap (treemap), P&L chart, positions table
- **AI chat assistant** — analyzes holdings, suggests and auto-executes trades
- **Watchlist management** — track tickers manually or via AI
- **Dark terminal aesthetic** — Bloomberg-inspired, data-dense layout
**Early — market data is the only component built.** There's no frontend and no Dockerfile
yet, so the app doesn't run end to end.

## Architecture

Single Docker container serving everything on port 8000:
| Component | Status |
|---|---|
| Market data — simulator, Massive client, price cache, SSE | ✅ 73 tests, 84% coverage |
| Portfolio, trades, watchlist, chat API | ⬜ |
| Database, frontend, Docker, E2E tests | ⬜ |

- **Frontend**: Next.js (static export) with TypeScript and Tailwind CSS
- **Backend**: FastAPI (Python/uv) with SSE streaming
- **Database**: SQLite with lazy initialization
- **AI**: LiteLLM → OpenRouter (Cerebras inference) with structured outputs
- **Market data**: Built-in GBM simulator (default) or Massive API (optional)
## Try It

## Quick Start
Requires [uv](https://docs.astral.sh/uv/) and Python 3.12+. No API key needed.

```bash
# Clone and configure
cp .env.example .env
# Add your OPENROUTER_API_KEY to .env
cd backend
uv sync --dev
uv run market_data_demo.py # live terminal dashboard, 10 tickers, ~60s
uv run pytest # test suite
```

# Run with Docker
docker build -t finally .
docker run -v finally-data:/app/db -p 8000:8000 --env-file .env finally
## Architecture

# Open http://localhost:8000
```
Target design is one Docker container on port 8000: a **Next.js** static export served by
**FastAPI**, backed by **SQLite**, with **LiteLLM → OpenRouter** (Cerebras) for chat and
Server-Sent Events for price streaming. Single origin, so no CORS.

## Environment Variables
Market data has two interchangeable sources behind one interface — a GBM simulator
(default) and a Massive/Polygon.io poller (when `MASSIVE_API_KEY` is set) — both writing
to a thread-safe `PriceCache` that SSE, portfolio valuation, and trade pricing read from.
See [`planning/MARKET_DATA_SUMMARY.md`](planning/MARKET_DATA_SUMMARY.md).

| Variable | Required | Description |
|---|---|---|
| `OPENROUTER_API_KEY` | Yes | OpenRouter API key for AI chat |
| `MASSIVE_API_KEY` | No | Massive (Polygon.io) key for real market data; omit to use simulator |
| `LLM_MOCK` | No | Set `true` for deterministic mock LLM responses (testing) |
## Configuration

## Project Structure
Read from a gitignored `.env` in the project root.

```
finally/
├── frontend/ # Next.js static export
├── backend/ # FastAPI uv project
├── planning/ # Project documentation and agent contracts
├── test/ # Playwright E2E tests
├── db/ # SQLite volume mount (runtime)
└── scripts/ # Start/stop helpers
```
| Variable | Description |
|---|---|
| `OPENROUTER_API_KEY` | LLM assistant. Everything except chat works without it. |
| `MASSIVE_API_KEY` | Optional — real market data. Omit to use the simulator. |
| `LLM_MOCK` | Optional — `true` for deterministic mock responses in tests. |

## Docs

- [`planning/PLAN.md`](planning/PLAN.md) — full spec, and the contract between agents
- [`backend/README.md`](backend/README.md) — backend development and testing

## License

Expand Down
Loading