Skip to content

DDD Analytics: ROI, Sharpe Ratio, Max Drawdown calculation. Event-driven, TypeScript.

License

Notifications You must be signed in to change notification settings

KeepALifeUS/ddd-analytics-domain

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Analytics Domain

CI License: MIT

Analytics Bounded Context for analyzing trading metrics and strategy performance

Overview

The Analytics Domain implements complex business logic for:

  • Financial metrics calculation (ROI, Sharpe Ratio, Max Drawdown)
  • Performance analysis of trading strategies
  • Risk management and alerts
  • Historical analysis and trends
  • Strategy comparison and benchmarking

Architecture (DDD)

analytics/
├── domain/
│   ├── aggregates/          # Aggregate roots
│   │   └── metrics.aggregate.ts
│   ├── value-objects/       # Immutable value objects
│   │   ├── metric-id.value-object.ts
│   │   ├── time-range.value-object.ts
│   │   ├── profit-loss.value-object.ts
│   │   ├── roi.value-object.ts
│   │   ├── sharpe-ratio.value-object.ts
│   │   └── max-drawdown.value-object.ts
│   ├── events/              # Domain events
│   │   ├── metrics-calculated.event.ts
│   │   ├── performance-analyzed.event.ts
│   │   └── alert-triggered.event.ts
│   ├── services/            # Domain services
│   │   ├── metrics-calculator.service.ts
│   │   └── risk-analyzer.service.ts
│   └── repositories/        # Repository interfaces
│       └── metrics-repository.interface.ts

Quick Start

Installation

npm install

Basic Usage

import {
  TradingMetrics,
  MetricId,
  TimeRange,
  ProfitLoss,
} from '@ddd-example/analytics-domain';

// Create metrics for a strategy
const metrics = TradingMetrics.createForStrategy(
  'BTC-Scalping',
  'USDT',
  new Decimal(10000) // initial capital
);

// Update metrics
const realizedPnL = ProfitLoss.fromNumber(150.50, 'USDT', true);
const unrealizedPnL = ProfitLoss.fromNumber(-25.30, 'USDT', false);

metrics.updateMetrics(
  new Decimal(10125.20), // current portfolio value
  realizedPnL,
  unrealizedPnL
);

// Get current metrics
const snapshot = metrics.currentSnapshot;
console.log(`ROI: ${snapshot.roi.toString()}`);
console.log(`Max Drawdown: ${snapshot.maxDrawdown.toString()}`);

Advanced Metrics Calculation

import { MetricsCalculatorService, RiskAnalyzerService } from '@ddd-example/analytics-domain';

const calculator = new MetricsCalculatorService();
const riskAnalyzer = new RiskAnalyzerService();

// Calculate Sharpe Ratio
const sharpeRatio = calculator.calculateSharpeRatio(portfolioSnapshots);

// Risk analysis
const riskMetrics = riskAnalyzer.analyzePortfolioRisk(portfolioSnapshots);
const riskLevel = riskAnalyzer.assessRiskLevel(riskMetrics);

console.log(`Risk Level: ${riskLevel.overall}`);
console.log(`Risk Score: ${riskLevel.score}/100`);

Key Components

Value Objects

MetricId

// Unique metric identifiers
const metricId = MetricId.forMetric('btc_scalping_usdt');
const randomId = MetricId.generate();

TimeRange

// Time ranges for analysis
const lastWeek = TimeRange.lastDays(7);
const thisMonth = TimeRange.thisMonth();
const custom = TimeRange.fromDates(startDate, endDate);

ProfitLoss

// Precise financial calculations
const pnl = ProfitLoss.fromNumber(245.67, 'USDT', true);
console.log(`Is Profit: ${pnl.isProfit}`); // true
console.log(`Amount: ${pnl.amount.toString()}`); // 245.67

ROI

// Return on Investment
const roi = ROI.calculate(
  new Decimal(1000),  // initial amount
  new Decimal(1250),  // final amount
  '30 days'
);
console.log(`ROI: ${roi.toString()}`); // +25.00% ROI (30 days)

SharpeRatio

// Risk-adjusted returns
const sharpe = SharpeRatio.calculate(
  portfolioReturn,
  portfolioVolatility,
  riskFreeRate,
  'daily'
);
console.log(`Quality: ${sharpe.getQualityRating()}`); // 'good'

MaxDrawdown

// Maximum drawdown
const drawdown = MaxDrawdown.fromPortfolioValues(
  portfolioHistory,
  'USDT'
);
console.log(`Severity: ${drawdown.getSeverityLevel()}`); // 'moderate'

Aggregates

TradingMetrics

// Root aggregate for all strategy metrics
const metrics = TradingMetrics.createForStrategy('Strategy1', 'USDT', initialValue);

// Updating metrics generates domain events
metrics.updateMetrics(portfolioValue, realizedPnL, unrealizedPnL, trades);

// Performance analysis
const timeRange = TimeRange.lastDays(30);
metrics.analyzePerformance(timeRange);

// Events for integration
const events = metrics.events;
// [MetricsCalculatedEvent, PerformanceAnalyzedEvent, ...]

Domain Events

MetricsCalculatedEvent

// Automatically generated when metrics are updated
event.isSignificantUpdate(); // true/false
event.getPerformanceCategory(); // 'excellent' | 'good' | 'average' | 'poor' | 'critical'
event.getKeyMetrics(); // { roi, totalPnL, maxDrawdown, winRate, ... }

AlertTriggeredEvent

// Critical changes and thresholds
const alert = AlertTriggeredEvent.createThresholdAlert(
  metricId,
  'SIGNIFICANT_DRAWDOWN',
  'Max Drawdown',
  20, // threshold value 20%
  35, // current value 35%
  'greater_than',
  'critical'
);

Domain Services

MetricsCalculatorService

const calculator = new MetricsCalculatorService();

// Financial calculations
const roi = calculator.calculatePeriodROI(snapshots, timeRange);
const sharpe = calculator.calculateSharpeRatio(snapshots, riskFreeRate);
const drawdown = calculator.calculateMaxDrawdown(snapshots, 'USDT');

// Trading statistics
const tradeStats = calculator.calculateTradeStatistics(trades);
// { totalTrades, winRate, avgWin, profitFactor, expectancy, ... }

// VaR and risk metrics
const var95 = calculator.calculateVaR(snapshots, 0.95, 1);
const volatility = calculator.calculateVolatility(snapshots, true);

RiskAnalyzerService

const riskAnalyzer = new RiskAnalyzerService();

// Comprehensive risk analysis
const riskMetrics = riskAnalyzer.analyzePortfolioRisk(snapshots);
// { maxDrawdown, var95, volatility, beta, calmarRatio, ... }

// Risk classification
const assessment = riskAnalyzer.assessRiskLevel(riskMetrics);
// { overall: 'moderate', factors: {...}, score: 45 }

// Alert generation
const alerts = riskAnalyzer.generateRiskAlerts(riskMetrics, thresholds);

// Concentration risks
const concentration = riskAnalyzer.analyzeConcentrationRisk(portfolio, 0.1);

Alert Types

  • SIGNIFICANT_DRAWDOWN - Critical drawdown level
  • LOW_PROFIT_FACTOR - Low profit factor
  • LOW_WIN_RATE - Low win rate
  • RISK_LIMIT_EXCEEDED - Risk limits exceeded
  • PERFORMANCE_DEGRADATION - Performance deterioration

Design Features

  • Cloud-Native Patterns - Event-driven architecture
  • Enterprise DDD - Aggregate roots, Value objects, Domain events
  • High-Performance - Decimal.js for precise financial calculations
  • Observability - Structured events for monitoring
  • Type Safety - Full TypeScript type coverage
  • Scalability - Repository patterns for large data volumes

Performance Benchmarks

  • ROI calculation: ~0.1ms for 1,000 portfolio snapshots
  • Sharpe Ratio: ~5ms for 252 daily returns
  • Max Drawdown: ~2ms for 1,000 data points
  • VaR 95%: ~10ms for 1,000 returns
  • Risk Analysis: ~50ms full analysis

Testing

npm run test            # Unit tests
npm run test:coverage   # Coverage report

License

MIT

Support

For questions and support, please open an issue on GitHub.

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •