Candle annotator
Find a file
2026-02-12 14:05:01 +01:00
openspec chore: mark all 59 tasks as completed in OpenSpec 2026-02-12 11:20:46 +01:00
src feat: add color support for line annotations 2026-02-12 14:04:51 +01:00
.eslintrc.json feat: initialize Next.js project with database schema 2026-02-12 10:23:02 +01:00
.gitignore feat: initialize Next.js project with database schema 2026-02-12 10:23:02 +01:00
CLAUDE.md starting planning 2026-02-12 09:42:55 +01:00
components.json feat: initialize Next.js project with database schema 2026-02-12 10:23:02 +01:00
DEPLOYMENT.md feat: complete candle annotator implementation 2026-02-12 11:20:29 +01:00
drizzle.config.ts feat: initialize Next.js project with database schema 2026-02-12 10:23:02 +01:00
EURUSD.csv fix: resolve chart visibility issues after CSV upload 2026-02-12 11:50:48 +01:00
EURUSD.csv~ fix: resolve chart visibility issues after CSV upload 2026-02-12 11:50:48 +01:00
EURUSD_1000.csv fix: resolve chart visibility issues after CSV upload 2026-02-12 11:50:48 +01:00
LINE_DRAWING_IMPROVEMENTS.md docs: mark Phase 1 as complete in implementation plan 2026-02-12 14:05:01 +01:00
next-env.d.ts fix: resolve chart visibility issues after CSV upload 2026-02-12 11:50:48 +01:00
next.config.js feat: initialize Next.js project with database schema 2026-02-12 10:23:02 +01:00
package-lock.json fix: resolve chart visibility issues after CSV upload 2026-02-12 11:50:48 +01:00
package.json fix: resolve chart visibility issues after CSV upload 2026-02-12 11:50:48 +01:00
PLAN.md starting planning 2026-02-12 09:42:55 +01:00
postcss.config.js feat: initialize Next.js project with database schema 2026-02-12 10:23:02 +01:00
README.md feat: complete candle annotator implementation 2026-02-12 11:20:29 +01:00
tailwind.config.ts feat: initialize Next.js project with database schema 2026-02-12 10:23:02 +01:00
tsconfig.json feat: complete candle annotator implementation 2026-02-12 11:20:29 +01:00

Candle Annotator

A web-based tool for manually annotating candlestick charts with pattern labels and trend lines. Built for creating labeled training data for machine learning models in trading analysis.

Overview

Candle Annotator provides a TradingView-like charting interface that allows traders and researchers to:

  • Upload historical OHLC (Open, High, Low, Close) candle data from CSV files
  • Visualize candlestick charts with interactive zoom and pan
  • Mark breakout patterns (Break Up, Break Down) directly on candles
  • Draw custom trend lines with two-click interaction
  • Delete annotations with a dedicated tool
  • Export all annotations as CSV for ML training pipelines

Features

Data Management

  • CSV Upload: Import OHLC data with support for both Unix timestamps and date strings
  • SQLite Storage: All candle data and annotations stored locally in SQLite database
  • Data Persistence: Annotations and candles persist between sessions

Chart Visualization

  • Interactive Candlestick Chart: Powered by lightweight-charts library
  • Dark Theme: Eye-friendly slate color scheme
  • Zoom & Pan: Mouse wheel zoom and drag-to-pan functionality
  • Crosshair: Precise price and time tracking

Annotation Tools

  • Break Up Markers: Green arrow markers below candles indicating upward breakouts
  • Break Down Markers: Red arrow markers above candles indicating downward breakouts
  • Trend Lines: Two-click line drawing with real-time preview
  • Delete Tool: Remove any annotation (markers or lines) by clicking on them
  • Tool Toggle: Click tool button again to deactivate

Export

  • CSV Export: Download all annotations with timestamp, label type, and price data
  • ML-Ready Format: Structured data suitable for training ML models

Tech Stack

  • Frontend: Next.js 16 (App Router), React 19, TypeScript
  • Styling: Tailwind CSS 3, shadcn/ui components
  • Charting: lightweight-charts 4.x (TradingView)
  • Icons: lucide-react
  • Backend: Next.js API Routes
  • Database: SQLite with better-sqlite3
  • ORM: Drizzle ORM
  • CSV Parsing: papaparse

Getting Started

Prerequisites

  • Node.js 18.x or higher
  • npm 9.x or higher
  • Build tools for native modules (see DEPLOYMENT.md)

Installation

  1. Clone the repository:

    git clone <repository-url>
    cd candle_annotator
    
  2. Install dependencies:

    npm install
    
  3. Start the development server:

    npm run dev
    
  4. Open http://localhost:3000 in your browser

Usage

  1. Upload Data: Click "Choose CSV File" and select a CSV with columns: time,open,high,low,close
  2. View Chart: The candlestick chart renders automatically after upload
  3. Add Annotations:
    • Click "Label: Break Up" or "Label: Break Down" then click on a candle
    • Click "Draw Line" then click two points to draw a trend line
    • Press Escape to cancel line drawing
  4. Delete Annotations: Click "Delete" tool, then click on markers or lines to remove them
  5. Export: Click "Export CSV" to download all annotations

CSV File Format

Input Format

Your CSV file should have these columns:

time,open,high,low,close
1700000000,1.0500,1.0520,1.0490,1.0510
1700000060,1.0510,1.0530,1.0505,1.0525

Time column accepts:

  • Unix timestamps (seconds): 1700000000
  • Date strings: 2024-01-15, 2024-01-15 10:30:00

Export Format

The exported CSV includes:

timestamp,label_type,price
1700000000,break_up,1.0510
1700000120,break_down,1.0505
1700000000,line,1.0500
  • timestamp: Unix timestamp of the annotation
  • label_type: break_up, break_down, or line
  • price: Close price for markers, start price for lines

Database Schema

Candles Table

{
  id: integer (PK, auto-increment),
  time: integer (Unix timestamp, unique),
  open: real,
  high: real,
  low: real,
  close: real
}

Annotations Table

{
  id: integer (PK, auto-increment),
  timestamp: integer (Unix timestamp),
  label_type: text ('break_up' | 'break_down' | 'line'),
  geometry: text (JSON string for line coordinates, null for markers),
  created_at: integer (Unix timestamp)
}

API Endpoints

POST /api/upload

Upload CSV file and store candle data

Request: multipart/form-data with file field
Response: { success: true, count: number } or { error: string }

GET /api/candles

Retrieve all candle records

Response: Array of candle objects ordered by time

GET /api/annotations

Retrieve all annotations

Response: Array of annotation objects with parsed geometry

POST /api/annotations

Create a new annotation

Request: { timestamp: number, label_type: string, geometry?: object }
Response: Created annotation object with ID

DELETE /api/annotations/[id]

Delete an annotation by ID

Response: { success: true } or { error: string }

GET /api/export

Export annotations as downloadable CSV

Response: CSV file download with Content-Disposition header

Architecture

Component Structure

  • page.tsx: Main page composition, manages active tool state
  • Toolbox.tsx: Sidebar with tool buttons and export functionality
  • FileUpload.tsx: CSV upload component with status messages
  • CandleChart.tsx: Core chart wrapper with lightweight-charts integration
    • Initializes chart with dark theme
    • Handles marker annotations (Break Up/Down)
    • Manages click events for annotation creation
    • Exposes refreshData() method for parent updates
  • SvgOverlay.tsx: Transparent SVG layer for line drawing
    • Coordinate transformation between data and pixels
    • Two-click line drawing with preview
    • Line hit detection for deletion

Data Flow

  1. User uploads CSV → POST /api/upload → SQLite storage
  2. Chart mounts → GET /api/candles + GET /api/annotations → Render
  3. User clicks with active tool → POST /api/annotations → Refresh chart
  4. User deletes → DELETE /api/annotations/[id] → Refresh chart
  5. User exports → GET /api/export → CSV download

Development

Project Structure

candle_annotator/
├── src/
│   ├── app/
│   │   ├── api/              # API route handlers
│   │   │   ├── upload/
│   │   │   ├── candles/
│   │   │   ├── annotations/
│   │   │   └── export/
│   │   ├── globals.css       # Tailwind styles
│   │   ├── layout.tsx        # Root layout with dark theme
│   │   └── page.tsx          # Main page
│   ├── components/
│   │   ├── ui/               # shadcn/ui components
│   │   ├── CandleChart.tsx
│   │   ├── SvgOverlay.tsx
│   │   ├── Toolbox.tsx
│   │   └── FileUpload.tsx
│   └── lib/
│       ├── db/
│       │   ├── index.ts      # Drizzle client
│       │   ├── schema.ts     # Table definitions
│       │   └── migrate.ts    # Migration runner
│       └── utils.ts          # Utility functions
├── data/                     # SQLite database directory
├── drizzle/                  # Migration files
├── DEPLOYMENT.md             # Deployment instructions
└── README.md                 # This file

Key Technical Decisions

  1. lightweight-charts v4: Stable API with good candlestick and marker support
  2. SQLite with better-sqlite3: Synchronous access, perfect for single-user local apps
  3. SVG Overlay for Lines: Maintains separate rendering layer from chart, easier coordinate management
  4. Drizzle ORM: Type-safe queries with minimal overhead
  5. Next.js App Router: Server-side API routes co-located with frontend code

Known Limitations

  • Single User: No authentication or concurrent access support
  • No Undo: Can only delete annotations, not undo placement
  • Memory: Large CSV files (100k+ rows) may cause slow uploads
  • Line Snapping: Lines don't snap to candles, free-form placement only

Troubleshooting

See DEPLOYMENT.md for detailed troubleshooting steps.

Common issues:

  • better-sqlite3 binding errors: Run npm rebuild better-sqlite3
  • Port 3000 in use: Use PORT=3001 npm run dev
  • Database corruption: Delete data/candles.db and restart

License

ISC

Contributing

This is a focused tool for a specific use case. For questions or issues, please open a GitHub issue.