Metadata-Version: 2.4
Name: qcharts
Version: 1.0.0
Summary: The Lightweight Charts Jupyter extension
Project-URL: Homepage, https://github.com/niutool/qcharts
Project-URL: Repository, https://github.com/niutool/qcharts
Author: niutool
License-Expression: MIT
Keywords: charts,jupyter,lightweight-charts,stock,tradingview
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: Jupyter
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial :: Investment
Requires-Python: >=3.12
Requires-Dist: anywidget>=0.11.0
Requires-Dist: jupyterlab>=4.5.7
Requires-Dist: pandas>=3.0.3
Description-Content-Type: text/markdown

# QCharts

A Jupyter stock charting extension built on TradingView [Lightweight Charts](https://github.com/nicehash/lightweight-charts). Create interactive candlestick charts, technical indicators, and volume charts in Jupyter Notebook via a Python API.

[中文文档](#中文文档)

---

## Features

- **6 Chart Types** — Candlestick, Line, Area, Bar, Baseline, Histogram
- **Multi-Pane Support** — Stack multiple panels in a single chart (main chart + volume + MACD + KDJ, etc.)
- **Built-in Technical Indicators** — `add_ma()` Moving Averages, `add_macd()` MACD, `add_kdj()` KDJ
- **Volume** — Auto-colored by up/down, compressed at the bottom of the candlestick pane
- **Trade Markers** — Annotate buy/sell signals on the chart via `set_markers()`
- **Interactive Legend** — Real-time OHLC, price change %, and volume on crosshair hover
- **Responsive Sizing** — Fixed dimensions or auto-fill container

---

## Installation

```bash
pip install qcharts
# or with uv
uv add qcharts
```

**Dependencies:**
- Python >= 3.12
- anywidget >= 0.11.0
- pandas >= 3.0.3
- JupyterLab >= 4.5 (for widget display)

---

## Quick Start

```python
import pandas as pd
from qcharts import Chart

# Load stock data
df = pd.read_csv("stock.csv", parse_dates=["date"])

# Create chart and set data
chart = Chart(height=400)
chart.set_stock_data(df, "603629")
chart  # Display in Jupyter
```

---

## Usage Guide

### 1. Basic Candlestick + Volume

`set_stock_data()` creates candlestick and volume in one step:

```python
chart = Chart(height=400)
chart.set_stock_data(df, "603629")
chart
```

Or build step by step:

```python
chart = Chart(height=400)
chart.add_candles(df)                  # Candlestick
chart.add_volume(df, pane_name="vol")  # Volume (separate pane)
chart
```

**DataFrame requirements:** Must contain `date` (or `time`), `open`, `high`, `low`, `close` columns; volume also requires a `volume` column.

### 2. Moving Averages

`add_ma()` auto-detects columns matching `prefix + number`:

```python
df_ma = df[["date", "close"]].copy()
df_ma["ma5"] = df_ma["close"].rolling(5).mean()
df_ma["ma10"] = df_ma["close"].rolling(10).mean()
df_ma["ma20"] = df_ma["close"].rolling(20).mean()

chart.add_ma(df_ma, prefix="ma")
```

Custom colors:

```python
chart.add_ma(df_ma, prefix="ma", colors=["#2962FF", "#FF6D00", "#7B1FA2"])
```

### 3. MACD Indicator

`add_macd()` creates MACD line, signal line, and histogram (with 4-color auto styling):

```python
ema12 = df["close"].ewm(span=12, adjust=False).mean()
ema26 = df["close"].ewm(span=26, adjust=False).mean()

df_macd = df[["date"]].copy()
df_macd["macd"] = ema12 - ema26
df_macd["signal"] = df_macd["macd"].ewm(span=9, adjust=False).mean()
df_macd["hist"] = df_macd["macd"] - df_macd["signal"]

chart.add_macd(df_macd)
```

**DataFrame requirements:** Must contain `date` (or `time`), `macd`, `signal`, `hist` columns.

### 4. KDJ Indicator

```python
chart.add_kdj(df_kdj)
```

**DataFrame requirements:** Must contain `date` (or `time`), `k`, `d`, `j` columns.

### 5. Trade Signal Markers

```python
markers = [
    {"time": 1704067200, "position": "belowBar", "shape": "arrowUp",
     "color": "#26a69a", "text": "Buy"},
    {"time": 1704153600, "position": "aboveBar", "shape": "arrowDown",
     "color": "#ef5350", "text": "Sell"},
]

# Get candlestick series and set markers
candle = chart.series["default_candlestick"]
candle.set_markers(markers)
```

Supported `position`: `aboveBar`, `belowBar`, `inBar`.
Supported `shape`: `arrowUp`, `arrowDown`, `circle`, `square`, etc.

### 6. Multi-Pane Management

All series go into the main pane by default. Technical indicators (MACD, KDJ) auto-create new panes. You can also manage panes manually:

```python
chart.add_pane("volume", label="Volume", height=20)
chart.add_volume(df, pane_name="volume")

chart.add_pane("rsi", label="RSI", height=15)
chart.add_line("rsi", pane_name="rsi", color="#7B1FA2")
```

`height` is a proportional weight (not pixels), controlling the relative height of each pane.

### 7. Chart Sizing

```python
# Fixed size
chart = Chart(width=800, height=500)

# Auto-fill container
chart = Chart(auto_size=True)

# Resize dynamically
chart.set_size(width=1000, height=600)
```

### 8. Custom Styling

All `add_*` methods accept Lightweight Charts style options. Parameters support both `snake_case` and `camelCase`:

```python
chart.add_line("ma20", color="#FF6D00", line_width=2, line_style=2)
chart.add_candlestick("kline", up_color="#ef5350", down_color="#26a69a",
                       border_visible=True)
```

---

## Data Format

All methods accept either a `pandas.DataFrame` or a pre-formatted `list[dict]`.

### DataFrame Format

| Method | Required Columns |
|--------|-----------------|
| `set_stock_data` / `add_candles` | `date` (or `time`), `open`, `high`, `low`, `close` |
| `add_volume` | `date` (or `time`), `volume`, `close`, `open` |
| `add_ma` | `date` (or `time`), `ma{N}` columns (e.g. `ma5`, `ma10`) |
| `add_macd` | `date` (or `time`), `macd`, `signal`, `hist` |
| `add_kdj` | `date` (or `time`), `k`, `d`, `j` |

`date` / `time` columns support `datetime64[ns]`, `datetime64[us]`, `datetime64[ms]` precision and are auto-converted to Unix timestamps (seconds).

### list[dict] Format

```python
# Candlestick data
[{"time": 1704067200, "open": 10.0, "high": 10.5, "low": 9.8, "close": 10.3}]

# Line/Area data
[{"time": 1704067200, "value": 10.3}]

# Histogram data (per-bar color supported)
[{"time": 1704067200, "value": 12345, "color": "#ef535080"}]
```

---

## API Reference

### `Chart(width=0, height=300, auto_size=False)`

| Method | Description |
|--------|-------------|
| `set_stock_data(df, code)` | One-step candlestick + volume, sets pane label |
| `add_candles(data, pane_name=None)` | Add candlestick series |
| `add_volume(data, pane_name=None)` | Add volume histogram |
| `add_ma(df, pane_name=None, prefix='ma', colors=None)` | Add moving averages |
| `add_macd(data, pane_name='macd')` | Add MACD (line + signal + histogram) |
| `add_kdj(data, pane_name='kdj')` | Add KDJ (K/D/J lines) |
| `add_line(name, pane_name=None, color='#2962FF', **kwargs)` | Add line series |
| `add_area(name, pane_name=None, **kwargs)` | Add area series |
| `add_bar(name, pane_name=None, **kwargs)` | Add bar series |
| `add_baseline(name, pane_name=None, **kwargs)` | Add baseline series |
| `add_histogram(name, pane_name=None, **kwargs)` | Add histogram series |
| `add_candlestick(name, pane_name=None, **kwargs)` | Add candlestick series (custom name) |
| `add_pane(name, label=None, height=30)` | Add a new pane |
| `get_pane(name)` | Get a pane object |
| `set_size(width=0, height=300)` | Resize the chart |

### Series Methods

Each `add_*` method returns a Series object with:

| Method | Description |
|--------|-------------|
| `set_data(data)` | Update series data |
| `set_markers(markers)` | Set trade markers |

---

## Development

```bash
# Python environment
uv sync

# JS build
cd js
pnpm install
pnpm run build        # Build ESM bundle
pnpm run dev          # Watch mode

# Formatting
cd js
pnpm run format       # Prettier formatting
```

After modifying JS code, rebuild with `pnpm run build` and restart the Jupyter kernel to see changes.

## License

MIT
