后端实现:
- 新增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表迁移脚本
- 支持组合级别的净值历史记录
83 lines
2.4 KiB
C#
83 lines
2.4 KiB
C#
using SqlSugar;
|
||
|
||
namespace AssetManager.Data;
|
||
|
||
/// <summary>
|
||
/// 组合净值历史表 - 记录每日净值和收益
|
||
/// </summary>
|
||
[SugarTable("portfolio_nav_history")]
|
||
public class PortfolioNavHistory
|
||
{
|
||
/// <summary>
|
||
/// 主键
|
||
/// </summary>
|
||
[SugarColumn(IsPrimaryKey = true, IsIdentity = false)]
|
||
public string? Id { get; set; }
|
||
|
||
/// <summary>
|
||
/// 所属组合ID
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "portfolio_id", IndexGroupNameList = new string[] { "idx_portfolio_date" })]
|
||
public string? PortfolioId { get; set; }
|
||
|
||
/// <summary>
|
||
/// 净值日期
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "nav_date", IndexGroupNameList = new string[] { "idx_portfolio_date" })]
|
||
public DateTime NavDate { get; set; }
|
||
|
||
/// <summary>
|
||
/// 总资产价值(组合本位币)
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "total_value", ColumnDataType = "decimal(18,4)")]
|
||
public decimal TotalValue { get; set; }
|
||
|
||
/// <summary>
|
||
/// 总投入成本(组合本位币)
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "total_cost", ColumnDataType = "decimal(18,4)")]
|
||
public decimal TotalCost { get; set; }
|
||
|
||
/// <summary>
|
||
/// 单位净值(初始=1.0)
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "nav", ColumnDataType = "decimal(18,8)")]
|
||
public decimal Nav { get; set; }
|
||
|
||
/// <summary>
|
||
/// 日收益率(%)
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "daily_return", ColumnDataType = "decimal(10,4)")]
|
||
public decimal DailyReturn { get; set; }
|
||
|
||
/// <summary>
|
||
/// 累计收益率(%)
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "cumulative_return", ColumnDataType = "decimal(10,4)")]
|
||
public decimal CumulativeReturn { get; set; }
|
||
|
||
/// <summary>
|
||
/// 本位币
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "currency", Length = 10)]
|
||
public string? Currency { get; set; }
|
||
|
||
/// <summary>
|
||
/// 持仓数量
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "position_count")]
|
||
public int PositionCount { get; set; }
|
||
|
||
/// <summary>
|
||
/// 数据来源(calculated/backfill/estimated)
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "source", Length = 20)]
|
||
public string? Source { get; set; }
|
||
|
||
/// <summary>
|
||
/// 创建时间
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "created_at")]
|
||
public DateTime CreatedAt { get; set; }
|
||
}
|