fix: 修复多个金融计算问题
1. CreatePortfolioAsync: 初始建仓交易保存汇率信息 - 设置 ExchangeRate 和 TotalAmountBase 字段 - 支持跨币种初始建仓 2. ExchangeRateService: 增强 Mock 汇率降级 - 扩展支持 EUR、GBP、JPY - 未知货币对记录 Error 级别日志 3. PositionItem: 增加 Shares 属性 - 保留完整精度(解决 Amount int 截断问题)
This commit is contained in:
parent
19f3cc8679
commit
64c1fe60e7
@ -116,11 +116,35 @@ public class ExchangeRateService : IExchangeRateService
|
||||
{ "CNY-HKD", 1.09m },
|
||||
{ "HKD-CNY", 0.92m },
|
||||
{ "USD-HKD", 7.75m },
|
||||
{ "HKD-USD", 0.13m }
|
||||
{ "HKD-USD", 0.13m },
|
||||
{ "EUR-USD", 1.08m },
|
||||
{ "USD-EUR", 0.93m },
|
||||
{ "EUR-CNY", 7.70m },
|
||||
{ "CNY-EUR", 0.13m },
|
||||
{ "GBP-USD", 1.27m },
|
||||
{ "USD-GBP", 0.79m },
|
||||
{ "GBP-CNY", 9.00m },
|
||||
{ "CNY-GBP", 0.11m },
|
||||
{ "JPY-USD", 0.0067m },
|
||||
{ "USD-JPY", 149.50m },
|
||||
{ "JPY-CNY", 0.048m },
|
||||
{ "CNY-JPY", 20.90m }
|
||||
};
|
||||
|
||||
string key = $"{fromCurrency.ToUpper()}-{toCurrency.ToUpper()}";
|
||||
return Task.FromResult(mockRates.TryGetValue(key, out var rate) ? rate : 1.00m);
|
||||
|
||||
if (mockRates.TryGetValue(key, out var rate))
|
||||
{
|
||||
_logger.LogWarning("Mock汇率命中: {Key} = {Rate},计算结果可能不准确", key, rate);
|
||||
return Task.FromResult(rate);
|
||||
}
|
||||
|
||||
// 未知货币对,记录严重警告
|
||||
_logger.LogError("未知货币对,无法提供Mock汇率: {FromCurrency} -> {ToCurrency},返回1.0可能导致计算错误",
|
||||
fromCurrency, toCurrency);
|
||||
|
||||
// 返回1.0但记录严重警告,调用方应该检查日志
|
||||
return Task.FromResult(1.00m);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -90,7 +90,8 @@ public class PositionItem
|
||||
public string? StockCode { get; set; }
|
||||
public string? StockName { get; set; }
|
||||
public string? Symbol { get; set; }
|
||||
public int Amount { get; set; }
|
||||
public int Amount { get; set; } // 已弃用,保留兼容性
|
||||
public double Shares { get; set; } // 完整精度的持仓数量
|
||||
public double AveragePrice { get; set; }
|
||||
public double CurrentPrice { get; set; }
|
||||
public double TotalValue { get; set; }
|
||||
|
||||
@ -138,7 +138,23 @@ public class PortfolioService : IPortfolioService
|
||||
|
||||
_db.Insertable(position).ExecuteCommand();
|
||||
|
||||
// 创建交易记录
|
||||
// 创建交易记录(保存汇率信息)
|
||||
decimal totalAmount = (decimal)(stock.Price * stock.Amount);
|
||||
decimal? exchangeRate = null;
|
||||
decimal? totalAmountBase = null;
|
||||
|
||||
// 如果持仓币种与组合币种不同,需要保存汇率
|
||||
if (!string.IsNullOrEmpty(stock.Currency) && !stock.Currency.Equals(request.Currency, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
exchangeRate = await _exchangeRateService.GetExchangeRateAsync(stock.Currency, request.Currency);
|
||||
totalAmountBase = totalAmount * exchangeRate.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
exchangeRate = 1.0m;
|
||||
totalAmountBase = totalAmount;
|
||||
}
|
||||
|
||||
var transaction = new Transaction
|
||||
{
|
||||
Id = "trans-" + Guid.NewGuid().ToString().Substring(0, 8),
|
||||
@ -149,8 +165,10 @@ public class PortfolioService : IPortfolioService
|
||||
Title = "初始建仓",
|
||||
Amount = (decimal)stock.Amount,
|
||||
Price = (decimal)stock.Price,
|
||||
TotalAmount = (decimal)(stock.Price * stock.Amount),
|
||||
Currency = request.Currency,
|
||||
TotalAmount = totalAmount,
|
||||
Currency = stock.Currency ?? request.Currency,
|
||||
ExchangeRate = exchangeRate,
|
||||
TotalAmountBase = totalAmountBase,
|
||||
Status = "completed",
|
||||
Remark = "初始建仓",
|
||||
TransactionTime = buyTime,
|
||||
@ -524,7 +542,8 @@ public class PortfolioService : IPortfolioService
|
||||
StockCode = pos.StockCode,
|
||||
StockName = pos.StockName,
|
||||
Symbol = pos.StockCode,
|
||||
Amount = (int)pos.Shares,
|
||||
Amount = (int)pos.Shares, // 注意:此处精度丢失,仅用于显示
|
||||
Shares = (double)pos.Shares, // 新增:保留完整精度
|
||||
AveragePrice = (double)pos.AvgPrice,
|
||||
CurrentPrice = (double)CurrentPrice,
|
||||
TotalValue = (double)positionValueInTarget,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user