Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 52 additions & 1 deletion src/config/swagger.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,18 @@ export function setupSwagger(app: INestApplication): void {
const config = new DocumentBuilder()
.setTitle("StellAIverse Backend API")
.setDescription(
"Comprehensive API documentation for StellAIverse backend services including agent management, oracle submissions, compute operations, and audit trails",
"Comprehensive API documentation for StellAIverse backend services including " +
"portfolio management, agent management, oracle submissions, compute operations, " +
"and audit trails.\n\n" +
"## Portfolio Management\n" +
"Endpoints for portfolio CRUD operations, asset management, optimization, " +
"rebalancing, performance analytics, backtesting, and ML predictions.\n\n" +
"### Rate Limiting\n" +
"- **Global**: 100 requests/minute\n" +
"- **Trading (Portfolio)**: 20 requests/minute\n" +
"- **Auth**: 5 requests/minute\n\n" +
"### Authentication\n" +
"All portfolio endpoints require JWT Bearer token authentication.",
)
.setVersion("1.0.0")
.setContact(
Expand Down Expand Up @@ -41,6 +52,44 @@ export function setupSwagger(app: INestApplication): void {
.addTag("Oracle", "Oracle data submissions")
.addTag("Audit", "Audit trail and logging")
.addTag("Profile", "User profile management")
.addTag(
"Portfolio Management",
"Portfolio CRUD, optimization, rebalancing, and analytics. " +
"Includes endpoints for creating, reading, updating, and archiving portfolios, " +
"managing assets, running optimizations, and tracking performance.",
)
.addTag(
"Portfolio Assets",
"Asset (holding) management within portfolios. " +
"Supports multi-chain assets with cost basis tracking and unrealized gain/loss.",
)
.addTag(
"Portfolio Optimization",
"Portfolio optimization using Modern Portfolio Theory, " +
"Black-Litterman model, risk parity, and ML-based strategies.",
)
.addTag(
"Portfolio Rebalancing",
"Portfolio rebalancing triggers, execution, and history. " +
"Supports manual, time-based, threshold-based, and ML-triggered rebalancing.",
)
.addTag(
"Portfolio Analytics",
"Performance analytics including returns, volatility, Sharpe ratio, " +
"Sortino ratio, VaR, drawdown, and benchmark comparison.",
)
.addTag(
"Portfolio Backtesting",
"Historical backtesting of portfolio strategies with performance metrics.",
)
.addTag(
"ML Predictions",
"Machine learning-based price predictions for portfolio assets.",
)
.addTag(
"Portfolio Transactions",
"Transaction recording, history, cost basis calculation, and export.",
)
.build();

const document = SwaggerModule.createDocument(app, config, {
Expand All @@ -66,6 +115,8 @@ export function setupSwagger(app: INestApplication): void {
defaultModelsExpandDepth: 2,
defaultModelExpandDepth: 2,
tryItOutEnabled: true,
tagsSorter: "alpha",
operationsSorter: "alpha",
},
});
}
92 changes: 91 additions & 1 deletion src/portfolio/dto/backtest.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,63 +5,153 @@ import {
IsDateString,
IsEnum,
IsArray,
Min,
} from "class-validator";
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import { BacktestStatus } from "../entities/backtest-result.entity";

export class CreateBacktestDto {
@ApiProperty({
description: "Backtest name",
example: "BTC/ETH 60/40 Strategy Test",
})
@IsString()
name: string;

@ApiPropertyOptional({
description: "Backtest description",
example: "Testing balanced crypto allocation over 1 year",
})
@IsOptional()
@IsString()
description?: string;

@ApiProperty({
description: "Backtest start date (ISO 8601)",
example: "2025-01-01",
})
@IsDateString()
startDate: string;

@ApiProperty({
description: "Backtest end date (ISO 8601)",
example: "2026-01-01",
})
@IsDateString()
endDate: string;

@ApiProperty({
description: "Initial capital in USD",
example: 100000,
minimum: 0,
})
@IsNumber()
@Min(0)
initialCapital: number;

@ApiProperty({
description: "Strategy name or description",
example: "equal_weight",
})
@IsString()
strategy: string;

@ApiProperty({
description: "Asset weights for backtest",
example: [
{ ticker: "BTC", weight: 60 },
{ ticker: "ETH", weight: 40 },
],
})
@IsArray()
assets: Array<{ ticker: string; weight: number }>;

@ApiPropertyOptional({
description: "Benchmark ticker for comparison",
example: "SPY",
})
@IsOptional()
@IsString()
benchmarkTicker?: string;

@ApiPropertyOptional({
description: "Rebalancing frequency in months",
example: 3,
minimum: 1,
})
@IsOptional()
@IsNumber()
rebalanceFrequency?: number; // months
@Min(1)
rebalanceFrequency?: number;
}

export class BacktestResultResponseDto {
@ApiProperty({ description: "Backtest UUID" })
id: string;

@ApiProperty({ description: "Backtest name" })
name: string;

@ApiPropertyOptional({ description: "Backtest description" })
description?: string;

@ApiProperty({ description: "Backtest status", enum: BacktestStatus })
status: BacktestStatus;

@ApiProperty({ description: "Backtest start date" })
startDate: Date;

@ApiProperty({ description: "Backtest end date" })
endDate: Date;

@ApiProperty({ description: "Initial capital in USD" })
initialCapital: number;

@ApiPropertyOptional({ description: "Final portfolio value in USD" })
finalValue?: number;

@ApiPropertyOptional({ description: "Total return percentage" })
totalReturn?: number;

@ApiPropertyOptional({ description: "Annualized return percentage" })
annualizedReturn?: number;

@ApiPropertyOptional({ description: "Annualized volatility" })
volatility?: number;

@ApiPropertyOptional({ description: "Sharpe ratio" })
sharpeRatio?: number;

@ApiPropertyOptional({ description: "Sortino ratio" })
sortinoRatio?: number;

@ApiPropertyOptional({ description: "Maximum drawdown percentage" })
maxDrawdown?: number;

@ApiPropertyOptional({ description: "Benchmark total return" })
benchmarkReturn?: number;

@ApiPropertyOptional({ description: "Alpha vs benchmark" })
alpha?: number;

@ApiPropertyOptional({ description: "Beta vs benchmark" })
beta?: number;

@ApiPropertyOptional({ description: "Correlation with benchmark" })
Correlation?: number;

@ApiPropertyOptional({ description: "Total number of trades" })
totalTrades?: number;

@ApiPropertyOptional({ description: "Win rate (0-1)" })
winRate?: number;

@ApiPropertyOptional({ description: "Profit factor" })
profitFactor?: number;

@ApiProperty({ description: "Creation timestamp" })
createdAt: Date;

@ApiPropertyOptional({ description: "Completion timestamp" })
completedAt?: Date;
}
81 changes: 81 additions & 0 deletions src/portfolio/dto/optimization.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,78 +7,159 @@ import {
IsJSON,
IsDateString,
} from "class-validator";
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import {
OptimizationMethod,
OptimizationStatus,
} from "../entities/optimization-history.entity";

export class CreateOptimizationDto {
@ApiProperty({
description: "Portfolio optimization method",
enum: OptimizationMethod,
example: OptimizationMethod.MEAN_VARIANCE,
})
@IsEnum(OptimizationMethod)
method: OptimizationMethod;

@ApiProperty({
description: "Portfolio UUID to optimize",
example: "550e8400-e29b-41d4-a716-446655440000",
})
@IsString()
portfolioId: string;

@ApiPropertyOptional({
description: "Custom optimization parameters",
example: { riskFreeRate: 0.02, maxIterations: 1000 },
})
@IsOptional()
@IsJSON()
parameters?: Record<string, any>;

@ApiPropertyOptional({
description: "Risk profile UUID to apply",
example: "660e8400-e29b-41d4-a716-446655440001",
})
@IsOptional()
@IsString()
riskProfileId?: string;

@ApiPropertyOptional({
description: "Target annual return (0-1)",
example: 0.12,
minimum: 0,
maximum: 1,
})
@IsOptional()
@IsNumber()
targetReturn?: number;

@ApiPropertyOptional({
description: "Maximum allowable volatility",
example: 0.2,
minimum: 0,
})
@IsOptional()
@IsNumber()
maxVolatility?: number;

@ApiPropertyOptional({
description: "Asset-level allocation constraints",
example: [{ asset: "BTC", min: 0.1, max: 0.4 }],
})
@IsOptional()
@IsArray()
constraints?: Array<{ asset: string; min: number; max: number }>;
}

export class ApproveOptimizationDto {
@ApiProperty({
description: "Optimization UUID to approve",
example: "770e8400-e29b-41d4-a716-446655440002",
})
@IsString()
optimizationId: string;

@ApiPropertyOptional({
description: "Approval notes",
example: "Looks good, implementing allocation changes",
})
@IsOptional()
@IsString()
notes?: string;
}

export class RejectOptimizationDto {
@ApiProperty({
description: "Optimization UUID to reject",
})
@IsString()
optimizationId: string;

@ApiProperty({
description: "Rejection reason",
example: "Too aggressive for current market conditions",
})
@IsString()
rejectionReason: string;
}

export class ImplementOptimizationDto {
@ApiProperty({
description: "Optimization UUID to implement",
})
@IsString()
optimizationId: string;

@ApiPropertyOptional({
description: "Execution notes",
})
@IsOptional()
@IsString()
executionNotes?: string;
}

export class OptimizationHistoryResponseDto {
@ApiProperty({ description: "Optimization UUID" })
id: string;

@ApiProperty({ description: "Optimization method", enum: OptimizationMethod })
method: OptimizationMethod;

@ApiProperty({ description: "Optimization status", enum: OptimizationStatus })
status: OptimizationStatus;

@ApiProperty({ description: "Suggested allocation map" })
suggestedAllocation: Record<string, number>;

@ApiPropertyOptional({ description: "Expected annual return" })
expectedReturn?: number;

@ApiPropertyOptional({ description: "Expected volatility" })
expectedVolatility?: number;

@ApiPropertyOptional({ description: "Expected Sharpe ratio" })
expectedSharpeRatio?: number;

@ApiPropertyOptional({ description: "Value at Risk (95%)" })
valueAtRisk?: number;

@ApiPropertyOptional({ description: "Maximum drawdown" })
maxDrawdown?: number;

@ApiPropertyOptional({ description: "Improvement score vs current allocation (%)" })
improvementScore?: number;

@ApiPropertyOptional({ description: "Backtested performance metrics" })
backtestedMetrics?: Record<string, number>;

@ApiProperty({ description: "Creation timestamp" })
createdAt: Date;

@ApiPropertyOptional({ description: "Completion timestamp" })
completedAt?: Date;

@ApiPropertyOptional({ description: "Implementation timestamp" })
implementedAt?: Date;
}
Loading
Loading