后端实现:
- 新增PortfolioNavHistory实体,记录每日净值、成本、收益率
- 实现IPortfolioNavService接口,支持净值计算和历史回填
- 支持基于交易记录完整计算历史净值(买入卖出都会更新)
- 计算统计指标:最大回撤、夏普比率、波动率
新增API:
- GET /api/v1/portfolio/{id}/nav-history - 获取净值曲线
- POST /api/v1/portfolio/{id}/nav-history/backfill - 回填历史净值
- POST /api/v1/portfolio/{id}/nav-history/calculate - 计算当日净值
数据库:
- 新增portfolio_nav_history表迁移脚本
- 支持组合级别的净值历史记录
211 lines
6.3 KiB
C#
Executable File
211 lines
6.3 KiB
C#
Executable File
namespace AssetManager.Models.DTOs;
|
|
|
|
public class CreatePortfolioRequest
|
|
{
|
|
public string? name { get; set; }
|
|
public string? strategyId { get; set; }
|
|
public string? currency { get; set; }
|
|
public List<StockItem>? stocks { get; set; }
|
|
}
|
|
|
|
public class StockItem
|
|
{
|
|
public string? name { get; set; }
|
|
public string? code { get; set; }
|
|
public double price { get; set; }
|
|
public int amount { get; set; }
|
|
public string? date { get; set; }
|
|
public string? currency { get; set; }
|
|
public string assetType { get; set; } = "Stock"; // Stock / Crypto
|
|
}
|
|
|
|
public class CreatePortfolioResponse
|
|
{
|
|
public string? id { get; set; }
|
|
public double totalValue { get; set; }
|
|
public double returnRate { get; set; }
|
|
public string? currency { get; set; }
|
|
public string? createdAt { get; set; }
|
|
}
|
|
|
|
public class PortfolioDetailResponse
|
|
{
|
|
public string? id { get; set; }
|
|
public string? name { get; set; }
|
|
public string? currency { get; set; }
|
|
public string? status { get; set; }
|
|
public StrategyInfo? strategy { get; set; }
|
|
public double portfolioValue { get; set; }
|
|
public double totalReturn { get; set; }
|
|
public double todayProfit { get; set; }
|
|
public double historicalChange { get; set; }
|
|
public double dailyVolatility { get; set; }
|
|
public string? todayProfitCurrency { get; set; }
|
|
public string? logicModel { get; set; }
|
|
public string? logicModelStatus { get; set; }
|
|
public string? logicModelDescription { get; set; }
|
|
public int totalItems { get; set; }
|
|
public double totalRatio { get; set; }
|
|
public List<PositionItem>? positions { get; set; }
|
|
}
|
|
|
|
public class StrategyInfo
|
|
{
|
|
public string? id { get; set; }
|
|
public string? name { get; set; }
|
|
public string? description { get; set; }
|
|
}
|
|
|
|
public class PositionItem
|
|
{
|
|
public string? id { get; set; }
|
|
public string? stockCode { get; set; }
|
|
public string? stockName { get; set; }
|
|
public string? symbol { get; set; }
|
|
public int amount { get; set; }
|
|
public double averagePrice { get; set; }
|
|
public double currentPrice { get; set; }
|
|
public double totalValue { get; set; }
|
|
public double profit { get; set; }
|
|
public double profitRate { get; set; }
|
|
public double changeAmount { get; set; }
|
|
public double ratio { get; set; }
|
|
public double deviationRatio { get; set; }
|
|
public string? currency { get; set; }
|
|
}
|
|
|
|
public class TransactionItem
|
|
{
|
|
public string? id { get; set; }
|
|
public string? portfolioId { get; set; }
|
|
public string? date { get; set; }
|
|
public string? time { get; set; }
|
|
public string? type { get; set; }
|
|
public string? title { get; set; }
|
|
public string? stockCode { get; set; }
|
|
public double amount { get; set; }
|
|
public string? currency { get; set; }
|
|
public string? status { get; set; }
|
|
public string? remark { get; set; }
|
|
}
|
|
|
|
public class GetTransactionsRequest
|
|
{
|
|
public string? portfolioId { get; set; }
|
|
public int limit { get; set; }
|
|
public int offset { get; set; }
|
|
}
|
|
|
|
public class GetTransactionsResponse
|
|
{
|
|
public List<TransactionItem>? items { get; set; }
|
|
public int total { get; set; }
|
|
public int page { get; set; }
|
|
public int pageSize { get; set; }
|
|
}
|
|
|
|
public class CreateTransactionRequest
|
|
{
|
|
public string? portfolioId { get; set; }
|
|
public string? type { get; set; }
|
|
public string? stockCode { get; set; }
|
|
public int amount { get; set; }
|
|
public double price { get; set; }
|
|
public string? currency { get; set; }
|
|
public string? remark { get; set; }
|
|
public string assetType { get; set; } = "Stock"; // Stock / Crypto
|
|
public string? transactionTime { get; set; } // 实际交易时间,可选
|
|
public string? transactionDate { get; set; } // 交易日期,前端传入 YYYY-MM-DD 格式
|
|
}
|
|
|
|
public class CreateTransactionResponse
|
|
{
|
|
public string? id { get; set; }
|
|
public double totalAmount { get; set; }
|
|
public string? status { get; set; }
|
|
public string? createdAt { get; set; }
|
|
}
|
|
|
|
public class PortfolioListItem
|
|
{
|
|
public string? id { get; set; }
|
|
public string? name { get; set; }
|
|
public string? tags { get; set; }
|
|
public string? status { get; set; }
|
|
public string? statusType { get; set; }
|
|
public string? iconChar { get; set; }
|
|
public string? iconBgClass { get; set; }
|
|
public string? iconTextClass { get; set; }
|
|
public double value { get; set; }
|
|
public string? currency { get; set; }
|
|
public double returnRate { get; set; }
|
|
public string? returnType { get; set; }
|
|
}
|
|
|
|
public class GetPortfoliosResponse
|
|
{
|
|
public List<PortfolioListItem>? items { get; set; }
|
|
}
|
|
|
|
public class TotalAssetsResponse
|
|
{
|
|
public double totalValue { get; set; }
|
|
public string? currency { get; set; }
|
|
public double todayProfit { get; set; }
|
|
public string? todayProfitCurrency { get; set; }
|
|
public double totalReturnRate { get; set; }
|
|
}
|
|
|
|
// ===== 净值历史相关 DTO =====
|
|
|
|
public class NavHistoryRequest
|
|
{
|
|
public DateTime? startDate { get; set; }
|
|
public DateTime? endDate { get; set; }
|
|
public string? interval { get; set; } = "daily"; // daily, weekly, monthly
|
|
}
|
|
|
|
public class NavHistoryResponse
|
|
{
|
|
public string? portfolioId { get; set; }
|
|
public string? currency { get; set; }
|
|
public List<NavItem>? navHistory { get; set; }
|
|
public NavStatistics? statistics { get; set; }
|
|
}
|
|
|
|
public class NavItem
|
|
{
|
|
public string? date { get; set; }
|
|
public double nav { get; set; }
|
|
public double totalValue { get; set; }
|
|
public double totalCost { get; set; }
|
|
public double dailyReturn { get; set; }
|
|
public double cumulativeReturn { get; set; }
|
|
}
|
|
|
|
public class NavStatistics
|
|
{
|
|
public double maxReturn { get; set; }
|
|
public double minReturn { get; set; }
|
|
public double maxDrawdown { get; set; }
|
|
public double sharpeRatio { get; set; }
|
|
public double volatility { get; set; }
|
|
public double totalReturn { get; set; }
|
|
public int tradingDays { get; set; }
|
|
}
|
|
|
|
public class BackfillNavRequest
|
|
{
|
|
public string? portfolioId { get; set; }
|
|
public bool force { get; set; } = false; // 是否强制重新计算
|
|
}
|
|
|
|
public class BackfillNavResponse
|
|
{
|
|
public string? portfolioId { get; set; }
|
|
public int recordsCreated { get; set; }
|
|
public DateTime? startDate { get; set; }
|
|
public DateTime? endDate { get; set; }
|
|
public string? message { get; set; }
|
|
}
|