Open source
Trading Analytics for Laravel
composer require roundly-consulting/trading-analytics-for-laravelOverview
A calculation library that turns a stream of trades into a complete performance report: realized and unrealized P&L, cumulative returns, win rates, streaks, profit factor, expectancy, maximum drawdown and the Sharpe and Sortino ratios — globally and per trading pair, base currency and quote currency, split into buys and sells. Every figure is computed with bcmath and returned as a string-backed value object, so totals never drift. It stores nothing and ships no migrations: feed it trades, database rows or an ordered query through the TradingAnalytics facade and read the results, or return them straight from a controller as JSON. One pass, no per-trade history — memory stays flat however long the history is. MIT-licensed and dependency-light: ext-bcmath, Laravel and two Roundly foundation packages.
What you get
The full metric matrix
Realized and unrealized P&L, cumulative returns, win rate, streaks, profit factor, expectancy, max drawdown, Sharpe and Sortino — 17 results.
Per pair and per currency
Every metric globally and per trading pair, base currency and quote currency — split into total, buys and sells.
bcmath precision
All arithmetic runs in bcmath and every figure is a string-backed value object — no floating-point drift in your totals.
One pass, flat memory
Pass trades, rows or an ordered query — queries stream in pages and the engine keeps no per-trade history, so memory stays flat.
Only the metrics you need
only() and except() with automatic dependencies, and metrics() to discover every calculator the engine runs.
API-ready output
The engine and every result are Arrayable, Jsonable and JsonSerializable — return them straight from a controller.
Facade, DI & extension
One TradingAnalytics facade or an injectable manager, plus hooks, custom calculators and your own Analytics subclass via using().
Documentation
Installation
Install via Composer — no migrations, views or commands to set up — and optionally publish the config file.
Configuration
The two config keys — default bcmath scale and win-rate period — their env variables, and how a single run overrides them.
The TradingAnalytics facade
The whole API on one facade — build or run the engine for trades, rows or a query, map rows lazily, list calculators and swap in your engine.
Without the facade
Inject TradingAnalyticsManager for the same API without static calls, or run the Analytics engine class directly.
Building trades
Build Trade value objects from named scalars, array rows or NumericValueAsString fields — open or closed, validated on construction.
Loading trade history
Pass a query builder, Eloquent builder or relation straight to the facade — streamed in pages by close time, one page in memory at a time.
Trade order
Drawdown, streaks and the running cumulative return follow close-time order — out-of-order trades throw rather than skew the figures.
Per-trade P&L and ROI
Read a single trade’s pair, status, gross and net P&L and ROI, or serialize it to an array that carries both figures.
Running the engine
Run the engine through the TradingAnalytics facade — set precision and win-rate period, pick metrics, and calculate in one pass.
Choosing metrics
Run only the calculators you need with only() and except(), discover them with metrics(), and know which dependencies are pulled in.
Reading results
Every result accessor, and how breakdowns work — global, per pair, per base and quote currency, split into total, buy and sell.
Precision
Which figures follow the run’s scale and which have a fixed one — bcmath truncates, and ratios divide at full precision first.
Profit & loss
Realized and unrealized P&L, gross and net of commissions, with profit and loss splits and the profit factor per pair and currency.
Cumulative returns
Compounded returns in percent, gross and net of commissions, with a geometric per-trade average and running highs and lows.
Win rate & streaks
Winning trades and win ratios, the longest winning and losing streaks, and win rate bucketed by day, week or month.
Expectancy, drawdown & risk ratios
Expectancy, risk-reward ratio, maximum drawdown and the Sharpe and Sortino ratios — all computed from closed trades in bcmath.
Volume, value, commissions & timing
Traded size and notional value, commission totals, how often trades are opened and how long positions stay open.
JSON & API responses
Return the engine or any single result straight from a controller — every object is Arrayable, Jsonable and JsonSerializable.
Working with NumericValueAsString
The bcmath value object behind every figure — creation, arithmetic and mutability, rounding, comparisons and display formatting.
Direction & Period enums
The buy/sell Direction and daily/weekly/monthly Period enums, their domain methods and the shared select and validation helpers.
Extending the engine
Per-trade and after-trades hooks, custom calculators via AnalyticsInterface, Analytics subclasses via using() and the BcMath helpers.
Exceptions
Every package exception extends TradingAnalyticsException — invalid trades, unordered sources, scales and numbers, unknown calculators or engines.
Testing
Unit-test your reports with hand-built trades — no database, no fakes — and assert exact string figures.
Requirements
PHP 8.4+ with the bcmath extension and Laravel 12 or 13 — no database tables, migrations or queues.
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.