Chart visualization toolkit for quantitative trading analysis
Project description
ChartPipe
A professional chart visualization toolkit for quantitative trading analysis. Seamlessly integrates with seamflux CLI and quantpipe via Unix pipes.
Pipeline contract (CLI flags, JSON envelope, exit codes, runs/<runId>/ layout) is defined in the repo root rule.md. ChartPipe uses schemaVersion: 1 on stdout when --json is set.
Features overview
| Area | What ChartPipe does |
|---|---|
| OHLCV | Candlestick charts with optional moving averages and volume (mplfinance) |
| Indicators | RSI, MACD, Bollinger Bands (single or --indicator all) |
| Backtest | Equity curve, drawdown, trade markers from JSON or runs/<id>/ CSVs |
| Stats | Returns distribution, price distribution, monthly returns heatmap |
| Volatility | Historical vol, rolling vol, volatility cone |
| Compare | Multi-asset price overlay, correlation matrix, relative strength vs benchmark |
| Volume | VWAP with bands, volume profile, on-balance volume (OBV) |
| Drawdown | Underwater curve, recovery-time distribution, top-N drawdowns on price |
| Calendar | Returns by weekday, month, or intraday hour |
| Regime | Trend (ADX), volatility regime, MA-cross bull/bear |
| Themes | Dark and light |
| Pipelines | --json single-line envelope; optional --dry-run; global or per-command -o / --json / --dry-run |
| Input | Auto-detects Binance-style klines, wrapped JSON (data, result, ohlcv, candles), Polymarket-style price history, generic OHLCV |
Installation
From source (development)
cd chartpipe
pip install -e .
Using requirements.txt
pip install -r requirements.txt
Quick start
Integration with seamflux
# OHLCV candlestick
seamflux invoke binance fetchOhlcv --pipe -p symbol=BTC/USDT -p interval=1h -p limit=200 | chartpipe ohlcv --stdin
# RSI
seamflux invoke binance fetchOhlcv --pipe -p symbol=BTC/USDT -p interval=1h -p limit=200 | chartpipe indicators --indicator rsi --stdin
# Returns distribution
seamflux invoke binance fetchOhlcv --pipe -p symbol=BTC/USDT -p interval=1h -p limit=500 | chartpipe stats --type returns --stdin
# JSON output (one line on stdout; parse with jq)
seamflux invoke binance fetchOhlcv --pipe -p symbol=BTC/USDT -p interval=1h -p limit=200 | chartpipe ohlcv --stdin --json
Integration with quantpipe
# Recommended (rule.md): quantpipe writes equity.csv / trades.csv under runs/<id>/
quantpipe backtest --data btc_history.json --strategy ma_cross --run-dir runs/my-run --json
chartpipe backtest --run-dir runs/my-run --json
# Stdin: quantpipe JSON line that includes artifacts.equity (paths from --run-dir/--run-id)
quantpipe backtest --data btc_history.json --strategy ma_cross --run-dir runs/my-run --json | chartpipe backtest --stdin --json
Note: quantpipe --json without --run-dir / --run-id does not emit equity.csv; chartpipe backtest --stdin then fails with a clear error—use --run-dir on quantpipe or chartpipe backtest --run-dir.
Global CLI
Options (group level)
| Option | Description |
|---|---|
--version |
Show version and exit |
--json |
Machine-readable JSON envelope on stdout (single line); debug on stderr |
-o, --output-dir PATH |
Directory for charts (default: ./charts). Works as chartpipe -o DIR <cmd> or chartpipe <cmd> -o DIR. |
-v, --verbose |
Debug logs on stderr |
--dry-run |
Validate input only; do not write chart files |
Most subcommands also accept their own --json, --dry-run, and -o. --json and --dry-run are enabled if either the global or the subcommand flag is set (logical OR). -o on the subcommand wins when provided; otherwise the global --output-dir applies.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General failure (I/O, plot error, bad args) |
| 2 | Input / schema mismatch |
| 3 | Missing optional dependency (e.g. mplfinance for OHLCV) |
Run chartpipe --help for the full epilog.
Headless rendering
charts.py sets matplotlib to the Agg backend by default so charts run without a display. You may set MPLBACKEND=Agg in the environment if needed.
Commands (complete reference)
Common input pattern for OHLCV-based commands:
--data PATH/-dor--input(alias): JSON file--stdin: read JSON from stdin- If neither file nor
--stdinis given, stdin is still read when used in a pipe (same as--stdinbehavior in implementations that treat “no path” as stdin)
chartpipe ohlcv — candlestick charts
Professional OHLCV charts with optional moving averages and volume.
| Option | Description |
|---|---|
--data PATH, -d |
OHLCV JSON file |
--input PATH |
Alias for --data |
--stdin |
Read from stdin |
--title, -t |
Title (default: Price Chart) |
--volume / --no-volume |
Volume subplot (default: on) |
--ma INT |
Moving average period (repeatable; default periods: 20, 50) |
--theme |
dark or light |
-o, --output-dir |
Output directory (overrides global) |
--json |
JSON line on stdout |
--dry-run |
Validate only |
chartpipe ohlcv --data ohlcv.json --title "BTC/USDT" --ma 20 --ma 50 --volume
seamflux invoke binance fetchOhlcv --pipe ... | chartpipe ohlcv --stdin --theme dark
chartpipe indicators — RSI, MACD, Bollinger Bands
| Option | Description |
|---|---|
--indicator, -i |
rsi, macd, bb, or all |
--period, -p |
RSI period (default: 14) |
--data, --input, --stdin |
Same as ohlcv |
--title, -t |
Title |
--theme |
dark / light |
-o, --output-dir, --json, --dry-run |
As above |
--indicator all produces three charts; JSON artifacts uses keys rsi, macd, bb.
chartpipe backtest — equity, drawdown, trades
Sources:
--run-dir:equity.csv, optionaltrades.csv, optionalsummary.json(quantpipe layout)--data/--stdin: JSON envelope or legacy backtest JSON (parsed bybacktest_input.py)
| Option | Description |
|---|---|
--run-dir PATH |
Load CSVs from a run directory |
--data, --input, --stdin |
JSON file or stdin |
--title, -t |
Override title (else from summary.json or default) |
--theme |
dark / light |
-o, --output-dir, --json, --dry-run |
As above |
Requires a valid equity series (equity column after load).
chartpipe stats — statistical charts
| Option | Description |
|---|---|
--type |
returns, distribution, monthly, or all |
--data, --input, --stdin |
OHLCV JSON |
--title, -t, --theme, -o, --json, --dry-run |
As above |
--type all → artifact keys returns, distribution, monthly.
chartpipe volatility — volatility analysis
| Option | Description |
|---|---|
--type |
history, rolling, cone, or all |
--window, -w |
Rolling window (default: 20) |
--annualize, -a |
Annualization factor (default: 252, daily) |
--data, --input, --stdin |
OHLCV JSON (needs close) |
--title, -t, --theme, -o, --json, --dry-run |
As above |
--type all → artifact keys history, rolling, cone.
chartpipe compare — multi-asset comparison
Input formats:
- Object whose values are OHLCV lists:
{"BTCUSDT": [...], "ETHUSDT": [...]} - Or
{"data": { "SYM": [...], ... } } - Single-asset list or dict is treated as one series (symbol
unknownorsymbolfield if present)
| Option | Description |
|---|---|
--type |
price, correlation, rs, or all |
--benchmark, -b |
Benchmark symbol for relative strength (for rs, defaults to first asset if omitted) |
--normalize, -n |
Normalize series to start at 100 (price charts) |
--data, --input, --stdin |
Multi-asset or single-asset JSON |
--title, -t, --theme, -o, --json, --dry-run |
As above |
Rules: correlation and all require at least two assets. For --type all, correlation is included only if ≥2 assets; rs only if --benchmark is in the asset set (or defaulted and present).
chartpipe volume — VWAP, profile, OBV
| Option | Description |
|---|---|
--type |
vwap, profile, obv, or all |
--bands, -b |
VWAP standard-deviation bands count (default: 3) |
--session, -s |
daily, weekly, or none — session reset for VWAP |
--data, --input, --stdin |
OHLCV JSON |
--title, -t, --theme, -o, --json, --dry-run |
As above |
Columns: close and volume always; high and low also required for vwap and profile.
chartpipe drawdown — drawdown analytics
| Option | Description |
|---|---|
--type |
underwater, recovery, top, or all |
--top, -t |
Number of top drawdowns for top type (default: 5) |
--from-equity |
Input is already an equity curve (use equity or close column) |
--data, --input, --stdin |
OHLCV (default) or equity series with --from-equity |
--title, --theme, -o, --json, --dry-run |
As above |
Without --from-equity, equity is synthesized from close returns (cumulative, starting at 100).
chartpipe calendar — calendar effects
| Option | Description |
|---|---|
--type |
weekday, month, intraday, or all |
--agg |
mean, sum, or median — aggregation for returns |
--data, --input, --stdin |
OHLCV with parseable datetime index |
--title, -t, --theme, -o, --json, --dry-run |
As above |
Note: Data must normalize to a datetime index after timestamp parsing. For --type all, intraday is included only if the index has hour components and there are more than 24 rows.
chartpipe regime — market regime
| Option | Description |
|---|---|
--type |
trend, volatility, ma-cross, or all |
--period, -p |
Period for ADX / related (default: 14) |
--fast / --slow |
Fast/slow MA for ma-cross (default: 20 / 50) |
--data, --input, --stdin |
OHLCV JSON |
--title, -t, --theme, -o, --json, --dry-run |
As above |
Columns: close always; high and low required for trend and ma-cross.
Semantics: trend — ADX-style trend strength; volatility — high/low vol classification; ma-cross — bull/bear from MA crossovers.
Data formats
ChartPipe accepts JSON parsed from a string, file, or stdin. parse_input_text loads JSON; nested shapes are unwrapped by json_payload_to_dataframe.
Wrapper objects (single series)
If the root is a dict, the table rows may come from:
| Key | Use |
|---|---|
data |
pd.DataFrame(data["data"]) |
result |
Recurse into result (also used by unwrap_upstream_json in pipeline code) |
ohlcv |
pd.DataFrame(data["ohlcv"]) |
candles |
Binance-style array rows (first six columns → timestamp, open, high, low, close, volume) |
history |
Polymarket-style list of points (e.g. {t, p}) → DataFrame |
Standard OHLCV list
[
{"timestamp": "2024-01-01", "open": 42000, "high": 43000, "low": 41000, "close": 42500, "volume": 1000}
]
Binance-style objects
[
{"t": 1704067200000, "o": "42000.00", "h": "43000.00", "l": "41000.00", "c": "42500.00", "v": "1000.00"}
]
Epoch milliseconds in t / T are detected and converted appropriately for plotting.
Polymarket-style price history
Rows with p / P (price) and no full OHLCV: ChartPipe synthesizes open/high/low/close from price and sets volume to 0 if missing.
Multi-asset JSON (compare)
{
"BTCUSDT": [{"timestamp": "...", "close": 42000, "open": 41900, "high": 42100, "low": 41800, "volume": 100}],
"ETHUSDT": [{"timestamp": "...", "close": 2800, "open": 2790, "high": 2810, "low": 2780, "volume": 200}]
}
Backtest JSON (file/stdin)
Legacy or quantpipe-style payloads with equity curve and optional trades—see backtest_input.py. Run directory layout is preferred for quantpipe (equity.csv, trades.csv, summary.json).
Column name mapping (excerpt)
| Canonical | Aliases |
|---|---|
timestamp |
t, T, time, Time |
open |
o, O, Open |
high |
h, H, High |
low |
l, L, Low |
close |
c, C, Close |
volume |
v, V, vol, Volume |
price (Polymarket) |
p, P → synthesized OHLCV |
Output
Human-readable
Chart saved: /path/to/charts/ohlcv_20260317_130405.png
JSON (--json)
- One JSON object per invocation on stdout (single line by default).
- Success:
schemaVersion,tool,command,ok: true, optionalartifacts,meta(startedAt,finishedAt;dryRun: truewhen applicable), optionaldata(dry-run diagnostics). - Chart paths in
artifactsare relative to cwd unless absolute. - Single-chart commands use
artifacts.chartunless noted above (indicators all,stats all, etc. use multiple keys). - Failure:
ok: false,error: { "code", "message" }(e.g.INVALID_INPUT,MISSING_FILE,MISSING_DEPENDENCY,PLOT_ERROR).
Migration: older releases used {"img": "..."}; prefer artifacts.chart or the multi-key maps for all modes.
Upstream JSON unwrap
If stdin/file is a seamflux-style {"result": { ... }}, inner result may be unwrapped for pipeline compatibility (unwrap_upstream_json).
Package layout
chartpipe/
├── src/chartpipe/
│ ├── cli.py
│ ├── cli_exit.py
│ ├── core/
│ │ ├── backtest_input.py
│ │ ├── charts.py
│ │ ├── input_data.py
│ │ ├── pipeline_json.py
│ │ └── styles.py
│ └── commands/
│ ├── ohlcv.py
│ ├── indicators.py
│ ├── backtest.py
│ ├── stats.py
│ ├── volatility.py
│ ├── compare.py
│ ├── volume.py
│ ├── drawdown.py
│ ├── calendar.py
│ └── regime.py
├── tests/
├── requirements.txt
├── requirements-dev.txt
├── pytest.ini
├── setup.py
└── README.md
Tests
pip install -r requirements-dev.txt
pytest
Requirements
- Python >= 3.10
- pandas >= 2.0.0
- numpy >= 1.24.0
- matplotlib >= 3.7.0
- mplfinance >= 0.12.10b0
- seaborn >= 0.12.0
- click >= 8.0.0
License
MIT License
Contributing
Contributions are welcome. Please open a Pull Request.
Changelog
Current (0.1.0+)
- Subcommands:
ohlcv,indicators,backtest,stats,volatility,compare,volume,drawdown,calendar,regime - Pipeline JSON, exit codes, dry-run, global/per-command output and JSON flags
- Input normalization: Binance klines, wrappers, Polymarket price history, multi-asset compare
v0.1.0
- Initial release: OHLCV, indicators, backtest, stats, themes, JSON output
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chartpipe-0.1.2.tar.gz.
File metadata
- Download URL: chartpipe-0.1.2.tar.gz
- Upload date:
- Size: 66.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46fd7a392faf0ccf28208fe6eee8e354147ec4d8f416c3ae20abd6b6143035ad
|
|
| MD5 |
74acb44b12b1e484af13a57d6c4511a8
|
|
| BLAKE2b-256 |
2b8d8e8920cfb51a02216a7132a0e3862e57dc31d7f9e2c4af3310bb53255aa9
|
File details
Details for the file chartpipe-0.1.2-py3-none-any.whl.
File metadata
- Download URL: chartpipe-0.1.2-py3-none-any.whl
- Upload date:
- Size: 78.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b513507748a224b18fd8c7ec7938281a4bbef03a245e264e0c80da0512470d2
|
|
| MD5 |
5077cd683dfe35120f92b09f2906a45c
|
|
| BLAKE2b-256 |
bb9885661c9910eeea082b01decf605bd3ca4411a98e97e5ca7f1038c3614db9
|