robertgdev/alphaforge-statistics
Composer 安装命令:
composer require robertgdev/alphaforge-statistics
包简介
Trading strategy performance analytics and statistics engine
README 文档
README
Trading strategy performance analytics and statistics engine — zero-dependency computation library.
Design Philosophy
This package is a pure computation engine. It operates on plain data structures (arrays, DTOs, Ds\Vector) and knows nothing about:
- Laravel / Eloquent / any ORM
- Database schemas or SQL
- Carbon dates or formatting
- CLI/TUI/HTTP presentation layers
- Exchanges, orders, or portfolio management
If you delete the AlphaForge CLI tomorrow, this package remains fully functional as a standalone library usable from any PHP 8.3+ project.
Architecture
┌──────────────────────────┐
│ Your Application │
│ (Laravel, Symfony, CLI, │
│ desktop, Python bridge) │
└──────────┬───────────────┘
│
┌──────────▼───────────────┐
│ Adapter Layer │
│ (DB entities → DTOs) │
└──────────┬───────────────┘
│
┌──────────────────────▼──────────────────────┐
│ Alphaforge Statistics │
│ ┌────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ Math │ │ Statistics│ │ Monte Carlo │ │
│ └────────┘ └──────────┘ └──────────────┘ │
│ ┌────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ Series │ │ Walk- │ │ Sensitivity │ │
│ │ Metrics│ │ Forward │ │ Analysis │ │
│ └────────┘ └──────────┘ └──────────────┘ │
└─────────────────────────────────────────────┘
Dependency direction
Your App ──► Adapter Layer ──► Alphaforge Statistics
│
(no framework, no ORM,
no Carbon, no DB)
The package consumes only its own data types:
| Input type | Example |
|---|---|
TradeInput |
new TradeInput(id: '1', direction: 'long', entryTimestamp: 1704067200, ...) |
array<float> |
[0.02, -0.01, 0.03, ...] |
array<string> |
['50000', '51000', '50500', ...] |
Ds\Vector |
new Vector(['10000', '10500', '11000']) |
Package Contents
src/
├── Math/ Bcmath-precision statistical functions
├── Statistics/ Full backtest performance analysis
├── MonteCarlo/ Bootstrap Monte Carlo simulation
├── Series/ Time-series metrics (descriptive stats)
├── WalkForward/ Walk-forward analysis tools + strategy grading
├── Sensitivity/ Parameter importance and interaction analysis
└── Trade/ Trade input DTO
Dependencies
PHP ^8.3
ext-bcmath *
ext-ds *
No framework dependencies. Installable standalone.
Quick Start
Backtest Statistics
use RobertGDev\AlphaforgeStatistics\Statistics\StatisticsService; use RobertGDev\AlphaforgeStatistics\Trade\TradeInput; use Ds\Vector; $positions = new Vector; $positions->push(new TradeInput( id: '1', direction: 'long', entryPrice: '50000', exitPrice: '55000', entryTimestamp: strtotime('2024-01-01'), exitTimestamp: strtotime('2024-01-15'), realizedPnl: '1000', )); $service = new StatisticsService; $stats = $service->calculate( positions: $positions, initialCapital: '10000', finalCapital: '11000', ); echo $stats['total_return_percent']; // "10.000000" echo $stats['sharpe_ratio']; echo $stats['max_drawdown_percent']; echo $stats['profit_factor']; echo $stats['win_rate'];
Monte Carlo Simulation
use RobertGDev\AlphaforgeStatistics\MonteCarlo\MonteCarloService; $pnlValues = ['100', '-50', '200', '-30', '150', '-20', '80', '-10']; $service = new MonteCarloService($pnlValues, '10000'); $report = $service->analyze(iterations: 2000, seed: 42); foreach ($report->metrics as $metric) { echo "{$metric->label}: median={$metric->median}, " . "p5={$metric->p5}, p95={$metric->p95}\n"; if ($metric->isSignificant()) { echo " → statistically significant\n"; } }
Series Metrics
use RobertGDev\AlphaforgeStatistics\Series\SeriesMetricService; $service = new SeriesMetricService; $metrics = $service->calculate(['50000', '51000', '50500', '51500']); echo $metrics['mean']; // bcmath string echo $metrics['median']; echo $metrics['std_dev']; echo $metrics['skewness']; echo $metrics['kurtosis']; // Float-based helpers: $returns = [0.02, -0.01, 0.03, 0.005, -0.02]; $sharpe = $service->sharpeRatioFromReturns($returns); $sortino = $service->sortinoRatioFromReturns($returns); $maxDD = $service->maxDrawdownFromReturns($returns); $stats = $service->tradeWinLossStats($returns); // ['total_trades' => 5, 'winning_trades' => 3, 'losing_trades' => 2, ...]
Walk-Forward Strategy Grading
use RobertGDev\AlphaforgeStatistics\WalkForward\WalkForwardAnalysis; use RobertGDev\AlphaforgeStatistics\WalkForward\StrategyGrader; $analysis = new WalkForwardAnalysis( results: [], oosIsRatio: 60.0, robustCount: 3, robustRatio: 0.6, beatBuyHoldCount: 2, beatBuyHoldRatio: 0.4, returnGt10Count: 1, returnGt10Ratio: 0.2, sharpeBeatBenchmarkCount: 1, sharpeBeatBenchmarkRatio: 0.2, medianIsScore: 2.0, medianOosScore: 1.5, avgDegradation: 20.0, medianDegradation: 15.0, bestOosRank: 1, stabilityClassification: 'good', rankCorrelation: 0.5, benchmarkReturn: 20.0, benchmarkSharpe: 1.0, benchmarkHasData: true, captureRatio: 15.0, medianOosReturn: 5.0, medianOosSharpe: 0.8, medianOosMaxDd: 15.0, ); $grade = StrategyGrader::grade($analysis); // ['score' => 46.7, 'stars' => '\u2605\u2605\u2605\u2606\u2606', 'label' => '...', ...]
Parameter Sensitivity Analysis
use RobertGDev\AlphaforgeStatistics\Sensitivity\ParameterSensitivityService; $runs = [ ['params' => ['fast' => 5, 'slow' => 20], 'stats' => ['score' => '3.5']], ['params' => ['fast' => 5, 'slow' => 30], 'stats' => ['score' => '3.8']], ['params' => ['fast' => 10, 'slow' => 20], 'stats' => ['score' => '6.2']], ['params' => ['fast' => 10, 'slow' => 30], 'stats' => ['score' => '6.5']], ]; $service = new ParameterSensitivityService($runs); // Which parameter matters most? $importance = $service->importance('score'); // fast \u2192 92.3%, slow \u2192 7.7% // 2D score surface $surface = $service->surface('fast', 'slow', 'score'); // ['rows' => [5,10], 'cols' => [20,30], 'grid' => [[3.5,3.8],[6.2,6.5]]] // Interaction between parameters $interactions = $service->interactions('score'); // [{param_a: 'fast', param_b: 'slow', interaction: 0.0024}]
Walk-Forward Statistical Helpers
use RobertGDev\AlphaforgeStatistics\WalkForward\WalkForwardAnalyzer; // Rank correlation $corr = WalkForwardAnalyzer::spearmanRankCorrelation( [2.0, 1.8, 1.6], [1.5, 1.3, 1.1] ); // Robustness classification $class = WalkForwardAnalyzer::classifyRobustness(65.0, 70.0, 0.7); // "good" // Parameter boundary warnings $warnings = WalkForwardAnalyzer::boundaryWarnings( [['parameters' => ['fast' => 195]], ['parameters' => ['fast' => 50]]], ['fast' => ['min' => 5, 'max' => 200]] ); // Flag suspicious Sharpe $suspicious = WalkForwardAnalyzer::detectSuspiciousSharpe([ 'sharpe_ratio' => '8.5', 'total_return_percent' => '0.3', ]); // true
Math Utilities
use RobertGDev\AlphaforgeStatistics\Math\Math; Math::mean(['10', '20', '30'], 12); // "20.000000000000" Math::standardDeviation(['2', '4', '4', '5'], 6); Math::variance(['2', '4', '4', '5'], 6); Math::covariance(['1', '2', '3'], ['2', '4', '6'], 6); Math::percentage('500', '10000', 4); // "5.0000"
All Math methods use bcmath for precision — no floating-point rounding errors.
API Reference
TradeInput
| Property | Type | Description |
|---|---|---|
id |
string |
Trade identifier |
direction |
string |
'long' or 'short' |
entryPrice |
string |
Entry price (bcmath string) |
exitPrice |
?string |
Exit price (null if open) |
entryTimestamp |
int |
Unix seconds — no Carbon |
exitTimestamp |
?int |
Unix seconds (null if open) |
realizedPnl |
string |
Realized P&L (bcmath string) |
exitTag |
?string |
Optional exit reason tag |
StatisticsService
Implements StatisticsServiceInterface.
calculate( Vector $positions, // Vector<TradeInput> string $initialCapital, string $finalCapital, ?string $riskFreeRate = null, int $tradingDaysPerYear = 252, ?Vector $barEquityCurve = null, // Vector<string> ): array
Returns 40+ fields including:
total_return, total_return_percent, cagr, total_trades, winning_trades,
losing_trades, win_rate, gross_profit, gross_loss, net_profit,
profit_factor, average_win, average_loss, largest_win, largest_loss,
max_drawdown, max_drawdown_percent, avg_drawdown,
max_drawdown_duration, avg_drawdown_duration,
sharpe_ratio, sortino_ratio, active_sharpe_ratio, active_sortino_ratio,
calmar_ratio, volatility, alpha, beta,
time_in_market_percent, idle_capital_percent,
average_trade_duration, median_trade_duration, min_trade_duration,
max_trade_duration, max_consecutive_wins, max_consecutive_losses,
expectancy, long_trades, short_trades, long_win_rate, short_win_rate.
Risk metrics require >=10 data points. Volatility < 0.1% annualized yields zero ratios.
MonteCarloService
__construct(array<int, string> $tradePnlValues, string $initialCapital) analyze(int $iterations = 1000, ?int $seed = null): MonteCarloReport
MonteCarloReport
| Property | Type |
|---|---|
totalTrades |
int |
iterations |
int |
metrics |
array<string, MonteCarloMetric> |
Method: hasTrades(): bool
MonteCarloMetric
| Property | Type | Description |
|---|---|---|
label |
string |
Human-readable name |
p5 |
float |
5th percentile |
p25 |
float |
25th percentile |
median |
float |
Median |
p75 |
float |
75th percentile |
p95 |
float |
95th percentile |
probNegative |
float |
% iterations with negative outcome |
Method: isSignificant(): bool — true when probNegative < 5% AND p5 > 0.
Metrics produced: total_return_pct, win_rate, max_drawdown_pct, profit_factor, avg_trade_pnl, positive_trades.
SeriesMetricService
Implements SeriesMetricServiceInterface.
calculate(array<int, string> $values): array
Returns: count, min, max, mean, median, std_dev, variance,
sum, range, quartiles{q1,q2,q3}, skewness, kurtosis.
Float helpers:
sharpeRatioFromReturns(array<int, float> $returns): float sortinoRatioFromReturns(array<int, float> $returns): float maxDrawdownFromReturns(array<int, float> $returns): float performanceStabilityFromTrades(array<int, array{timestamp:int,pnl:float}> $trades): float tradeWinLossStats(array<int, float> $returns): array
StrategyGrader
static grade(WalkForwardAnalysis $analysis): array
Weights: economic (40%), robustness (30%), risk (20%), optimization (10%). Robustness acts as a score ceiling.
Returns: {score, stars, label, stars_by_category, breakdown}.
WalkForwardAnalysis
Pure DTO — 38 constructor properties. See source for full list.
WalkForwardAnalyzer
Stateless static functions:
| Method | Purpose |
|---|---|
median(array<float>): float |
Compute median |
spearmanRankCorrelation(array, array): ?float |
IS-OOS rank correlation |
rankValues(array<float>): array<float> |
Fractional rank assignment |
pearsonCorrelation(array, array): float |
Pearson r |
classifyRobustness(float, float, ?float): string |
excellent/good/moderate/weak/likely_overfit |
interpretClassification(string): string |
Human-readable classification |
classifyRankStability(?float): string |
stable/moderate/unstable |
boundaryWarnings(array, array): array |
Parameter boundary clustering |
detectInflatedOosIsRatio(float, float, float, ?array): bool |
Inflated OOS/IS flag |
classifyEconomicPerformance(?array, array): string |
strong/moderate/poor vs benchmark |
interpretEconomicPerformance(string, ?array, array): string |
Human-readable interpretation |
detectSuspiciousSharpe(?array): bool |
High Sharpe + tiny return |
hasLowTradeWarning(?array): bool |
< 30 trades in OOS |
ParameterSensitivityService
__construct(list<array{params, stats}> $runs) importance(string $metric = 'optimization_score'): array surface(string $paramA, string $paramB, string $metric = 'optimization_score'): array interactions(string $metric = 'optimization_score'): array
Math
All-static bcmath methods:
| Method | Signature |
|---|---|
mean |
(array<string>, int $scale): string |
variance |
(array<string>, int $scale, bool $sample=true): string |
standardDeviation |
(array<string>, int $scale, bool $sample=true): string |
covariance |
(array<string>, array<string>, int $scale, bool $sample=true): string |
percentage |
(string $value, string $base, int $scale=10): string |
Adapting from AlphaForge
Adapters exist in app/AlphaForge/Backtesting/Adapter/:
TradeInputAdapter::fromPositions(Vector $positions): Vector<TradeInput>— convertsPositionDto+ Carbon toTradeInput+ unix timestampsMonteCarloService::fromBacktestRunId(string $id)— Eloquent -> package delegationParameterSensitivityService::fromOptimizationRunId(string $id)— Eloquent -> package delegation
Testing
cd src
composer install
php vendor/bin/pest
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-25