关键修复: 1. BackfillNavHistoryInternalAsync 汇率处理bug - holdings 存储目标币种成本,避免卖出时用当前汇率重转历史成本 - 优先使用交易时保存的汇率 2. Transaction 表新增字段 - exchange_rate: 交易时汇率 - total_amount_base: 本位币金额 - 创建交易时自动保存汇率 3. CalculateAndSaveDailyNavAsync - 优先使用 TotalAmountBase 字段计算成本 - 回退到当前汇率(兼容历史数据) 4. 新增迁移脚本 sql/migrate_financial_fields.sql
109 lines
3.2 KiB
C#
109 lines
3.2 KiB
C#
using SqlSugar;
|
||
|
||
namespace AssetManager.Data;
|
||
|
||
/// <summary>
|
||
/// 交易流水表
|
||
/// </summary>
|
||
[SugarTable("transactions")]
|
||
public class Transaction
|
||
{
|
||
/// <summary>
|
||
/// 主键
|
||
/// </summary>
|
||
[SugarColumn(IsPrimaryKey = true, IsIdentity = false)]
|
||
public string? Id { get; set; }
|
||
|
||
/// <summary>
|
||
/// 所属组合ID
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "portfolio_id", IndexGroupNameList = new string[] { "idx_portfolio_id" })]
|
||
public string? PortfolioId { get; set; }
|
||
|
||
/// <summary>
|
||
/// 交易类型 (buy/sell)
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "type", Length = 20)]
|
||
public string? Type { get; set; }
|
||
|
||
/// <summary>
|
||
/// 标的代码
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "stock_code", Length = 50)]
|
||
public string? StockCode { get; set; }
|
||
|
||
/// <summary>
|
||
/// 资产类型 (Stock/Crypto)
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "asset_type", Length = 20)]
|
||
public string? AssetType { get; set; }
|
||
|
||
/// <summary>
|
||
/// 交易标题 (如: 定期定投)
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "title", Length = 200)]
|
||
public string? Title { get; set; }
|
||
|
||
/// <summary>
|
||
/// 交易数量
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "amount", ColumnDataType = "decimal(18,8)")]
|
||
public decimal Amount { get; set; }
|
||
|
||
/// <summary>
|
||
/// 成交价格
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "price", ColumnDataType = "decimal(18,4)")]
|
||
public decimal Price { get; set; }
|
||
|
||
/// <summary>
|
||
/// 交易总金额(原始币种)
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "total_amount", ColumnDataType = "decimal(18,4)")]
|
||
public decimal TotalAmount { get; set; }
|
||
|
||
/// <summary>
|
||
/// 交易币种
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "currency", Length = 10)]
|
||
public string? Currency { get; set; }
|
||
|
||
/// <summary>
|
||
/// 交易时汇率(原始币种 -> 组合本位币)
|
||
/// 用于精确计算历史净值,避免汇率变化影响
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "exchange_rate", ColumnDataType = "decimal(18,6)", IsNullable = true)]
|
||
public decimal? ExchangeRate { get; set; }
|
||
|
||
/// <summary>
|
||
/// 交易总金额(组合本位币)
|
||
/// = TotalAmount * ExchangeRate,用于精确计算
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "total_amount_base", ColumnDataType = "decimal(18,4)", IsNullable = true)]
|
||
public decimal? TotalAmountBase { get; set; }
|
||
|
||
/// <summary>
|
||
/// 交易状态 (processing/completed)
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "status", Length = 50)]
|
||
public string? Status { get; set; }
|
||
|
||
/// <summary>
|
||
/// 交易备注
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "remark", Length = 500, IsNullable = true)]
|
||
public string? Remark { get; set; }
|
||
|
||
/// <summary>
|
||
/// 交易发生时间
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "transaction_time")]
|
||
public DateTime TransactionTime { get; set; }
|
||
|
||
/// <summary>
|
||
/// 记录创建时间
|
||
/// </summary>
|
||
[SugarColumn(ColumnName = "created_at")]
|
||
public DateTime CreatedAt { get; set; }
|
||
}
|