NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

Open source

Trading Analytics for Laravel

Install
composer require roundly-consulting/trading-analytics-for-laravel
Requires: PHP ^8.4 · Laravel ^12.0|^13.0

Overview

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 crypto

By 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.