mirror of https://github.com/ghostfolio/ghostfolio
2 changed files with 137 additions and 1 deletions
@ -0,0 +1,135 @@ |
|||
# Charts Module |
|||
|
|||
This module covers the chart subsystem: selectable time range (zoom/pan), the value/invested-capital/cash toggle, total-return vs. price-return comparison, the contribution/waterfall chart, benchmark comparison, and the drawdown chart. Full design docs for each live in `/docs/design/`, this README is the quick-reference API contract. |
|||
|
|||
## Shared range contract |
|||
|
|||
Every endpoint below accepts the same range params, so client code only needs to implement range handling once. |
|||
|
|||
``` |
|||
?range=1d|wtd|mtd|ytd|1y|5y|max |
|||
``` |
|||
|
|||
or |
|||
|
|||
``` |
|||
?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD |
|||
``` |
|||
|
|||
Rules: |
|||
|
|||
- `range` and `startDate`/`endDate` are mutually exclusive, sending both returns 400. |
|||
- `startDate`/`endDate` must both be present if either is, returns 400 otherwise. |
|||
- `endDate` before `startDate` returns 400. |
|||
- `endDate` beyond today is clamped to today. |
|||
- `startDate` before the account's earliest activity is clamped to that date. |
|||
- Granularity is resolved server-side from range width (daily up to 2 years, weekly beyond) and returned in the response, not requested by the client. |
|||
|
|||
## Endpoints |
|||
|
|||
### `GET /api/v1/portfolio/performance` |
|||
|
|||
Portfolio value, invested capital, or cash as a time series. |
|||
|
|||
Extra param: `kind` = `portfolioValue` (default) | `investedCapital` | `cash` |
|||
|
|||
```ts |
|||
interface ChartSeriesResponse { |
|||
kind: 'portfolioValue' | 'investedCapital' | 'cash'; |
|||
granularity: 'daily' | 'weekly'; |
|||
startDate: string; |
|||
endDate: string; |
|||
points: Array<{ date: string; value: number }>; |
|||
} |
|||
``` |
|||
|
|||
### `GET /api/v1/portfolio/return-comparison` |
|||
|
|||
Total return vs. price return, indexed to base 100 at `startDate`. |
|||
|
|||
Extra param: `symbol` (optional, omit for whole-portfolio scope) |
|||
|
|||
```ts |
|||
interface ReturnComparisonResponse { |
|||
granularity: 'daily' | 'weekly'; |
|||
startDate: string; |
|||
endDate: string; |
|||
points: Array<{ date: string; priceReturn: number; totalReturn: number }>; |
|||
} |
|||
``` |
|||
|
|||
### `GET /api/v1/portfolio/benchmark-comparison` |
|||
|
|||
Portfolio total return vs. a benchmark symbol, both indexed to base 100. |
|||
|
|||
Required param: `benchmark` (a market-data symbol, same lookup as adding a holding) |
|||
|
|||
```ts |
|||
interface BenchmarkComparisonResponse { |
|||
granularity: 'daily' | 'weekly'; |
|||
startDate: string; |
|||
endDate: string; |
|||
benchmarkSymbol: string; |
|||
benchmarkAvailableFrom: string; |
|||
points: Array<{ |
|||
date: string; |
|||
portfolioReturn: number; |
|||
benchmarkReturn: number; |
|||
}>; |
|||
} |
|||
``` |
|||
|
|||
### `GET /api/v1/portfolio/drawdown` |
|||
|
|||
Percentage decline from the portfolio's running all-time peak. Peak tracking always uses full account history, even when the requested range starts later. |
|||
|
|||
```ts |
|||
interface DrawdownResponse { |
|||
granularity: 'daily' | 'weekly'; |
|||
startDate: string; |
|||
endDate: string; |
|||
maxDrawdown: number; |
|||
maxDrawdownDate: string; |
|||
points: Array<{ date: string; drawdown: number; isNewPeak: boolean }>; |
|||
} |
|||
``` |
|||
|
|||
### `GET /api/v1/portfolio/waterfall` |
|||
|
|||
Discrete start/contribution/end segments explaining a period's value change. |
|||
|
|||
Extra param: `breakdown` = `portfolio` (default) | `holding` |
|||
|
|||
```ts |
|||
type WaterfallSegment = |
|||
| { kind: 'start'; label: string; value: number } |
|||
| { |
|||
kind: 'contribution'; |
|||
label: string; |
|||
value: number; |
|||
category: 'netCashFlow' | 'marketGainLoss' | 'dividends'; |
|||
holdingSymbol?: string; |
|||
} |
|||
| { kind: 'end'; label: string; value: number }; |
|||
|
|||
interface WaterfallResponse { |
|||
startDate: string; |
|||
endDate: string; |
|||
currency: string; |
|||
segments: WaterfallSegment[]; |
|||
} |
|||
``` |
|||
|
|||
## Design docs |
|||
|
|||
| Area | Doc | |
|||
| -------------------------------------- | ------------------------------------------------------------------ | |
|||
| Zoom / pan / selectable time range | `docs/design/zoom-pan-time-range-data-spec.md` | |
|||
| Value / invested capital / cash toggle | `docs/design/portfolio-value-invested-capital-cash-toggle-spec.md` | |
|||
| Total return vs. price return | `docs/design/total-return-vs-price-return-comparison-spec.md` | |
|||
| Contribution / waterfall | `docs/design/contribution-waterfall-chart-data-structure.md` | |
|||
| Benchmark comparison | `docs/design/benchmark-comparison-data-model.md` | |
|||
| Drawdown | `docs/design/drawdown-chart-calculation-spec.md` | |
|||
| Overall architecture | `docs/design/design-architecture-charts.md` | |
|||
|
|||
Adjust the paths above to wherever the docs actually land in the repo before merging. |
|||
Loading…
Reference in new issue