- 将除权除息相关数值字段从 double 类型改为 decimal 类型以提高精度 - 重构了红利比率计算方法 GetRatio,新增 GetRatioDecimal 方法使用 decimal 计算 - 修改价格和持仓数量计算逻辑,统一使用 decimal 进行高精度运算 - 更新数据库查询逻辑,将篮子标的判断从 IsBasket() 方法改为 CommodityCode 条件 - 优化 AddDividendInfos 方法中的批量处理逻辑,增加业务键冲突检测 - 添加数据源标识字段 DataSource 和来源更新时间字段 SourceUpdatedAt - 新增 FindExDividendByBusinessKey 和 MergeNonZeroDividendValues 辅助方法 - 更新结算服务中除权除息信息的获取方式,使用字典查找替代 LINQ JOIN - 修复前端保存除权信息时的响应处理逻辑 - 为基金类型也开放除权功能,不仅限于股票类型 - 添加单元测试验证篮子标的查询翻译逻辑的正确性
185 lines
5.9 KiB
C#
185 lines
5.9 KiB
C#
using YLErp.Configuration;
|
|
using YLErp.Modules.EodModule.SettlementModule;
|
|
using YLErp.Modules.TradeModule.DealModule;
|
|
|
|
namespace YLErp.Modules.EodModule
|
|
{
|
|
[TestClass]
|
|
public class EodSettlementTaskTest : UnitTestBase
|
|
{
|
|
|
|
|
|
[TestMethod]
|
|
public void TestEodTask()
|
|
{
|
|
var eodDate = new DateTime(2020, 9, 2);
|
|
|
|
var task = new EodTask
|
|
{
|
|
StartDate = eodDate,
|
|
EndDate = eodDate,
|
|
VolTypes = "持仓",//"持仓,开仓,对冲";
|
|
PriceType = EodSettlePriceType.ClosePrice
|
|
};
|
|
EodTaskRunner.ExecuteDebugAsync(task).Wait();
|
|
Assert.IsTrue(task.TaskState == EodTaskState.completed, task.TaskResult);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TestReadTrade()
|
|
{
|
|
var date = new DateTime(2020, 07, 01);
|
|
var eodArr = new YLContext().eod_trade.Where(O => O.ValueDate == date).ToArray();
|
|
var tradeArr = eodArr.Select(O => O.trade).ToArray();
|
|
}
|
|
|
|
/// <summary>
|
|
/// GetFixingString 测试
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void GetFixingString()
|
|
{
|
|
var underlyingCode = "A00";
|
|
var settlementType = 1;
|
|
var futurePriceList = new YLContext().eod_commodity_future_price
|
|
.Where(e => e.UnderlyingCode == underlyingCode)
|
|
//.Where(e => e.ValueDate >= startDate)
|
|
//.Where(e => e.ValueDate >= exerciseDate)
|
|
.Select(e => new
|
|
{
|
|
e.ValueDate,
|
|
e.ClosePrice,
|
|
e.SettlePrice,
|
|
e.ReferencePrice
|
|
}).ToList();
|
|
|
|
var query = from e in futurePriceList
|
|
orderby e.ValueDate
|
|
select e.ValueDate + "," + GetPrice(settlementType, e.ClosePrice, e.SettlePrice, e.ReferencePrice);
|
|
|
|
var fixing = string.Join(";", query.ToArray());
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// GetFixingString 测试
|
|
/// </summary>
|
|
[TestMethod]
|
|
public void ClientBalanceCalc()
|
|
{
|
|
var request = new EodSettlementRequest(GetOptUser())
|
|
{
|
|
VolType = null,
|
|
UseClosePrice = true,
|
|
ClientIds = null,
|
|
SettleDate = DateTime.Today
|
|
};
|
|
CancellationTokenSource cancellationTokenSource;
|
|
EodSettlementContextV2 _context;
|
|
cancellationTokenSource = new CancellationTokenSource();
|
|
var settlementConfig = new SettlementConfig
|
|
{
|
|
Version = "V1",
|
|
CalcPnlExplain = false,
|
|
PriceType = 3,
|
|
SupportPart = false,
|
|
VolTypes = "持仓,开仓,对冲,光证,BidAskVol"
|
|
};
|
|
_context = new EodSettlementContextV2(request, settlementConfig, cancellationTokenSource.Token);
|
|
new EodClientBalanceCalc(_context).ClientBalanceCalc();
|
|
}
|
|
|
|
private double GetPrice(int settlementType, double closePrice, double settlePrice, double? referencePrice)
|
|
{
|
|
var price = closePrice;
|
|
if (settlementType == (int)SettlementTypeEnum.SettlePrice)
|
|
{
|
|
price = settlePrice;
|
|
}
|
|
else if (settlementType == (int)SettlementTypeEnum.ReferencePrice)
|
|
{
|
|
price = referencePrice ?? closePrice;
|
|
}
|
|
return price;
|
|
}
|
|
|
|
public enum SettlementTypeEnum
|
|
{
|
|
|
|
ClosePrice = 0,
|
|
|
|
SettlePrice = 1,
|
|
|
|
|
|
ReferencePrice = 2,
|
|
}
|
|
|
|
[TestMethod]
|
|
public void TestDividend()
|
|
{
|
|
var service = new DividendService(OptUserInfo.UnitTestUser);
|
|
|
|
var info = new ex_dividend_info()
|
|
{
|
|
UnderlyingCode = "002043.SZ",
|
|
ExDividendDate = new DateTime(2020, 7, 6),
|
|
GiveCashAmount = 2.5m,
|
|
GiveShareAmount = 0,
|
|
RationedSharesAmount = 0,
|
|
RationedSharesPrice = 0,
|
|
};
|
|
var price = service.GetPrice(8.8, info);
|
|
Assert.IsTrue((price - 8.6126) < 1e-4);
|
|
|
|
info = new ex_dividend_info()
|
|
{
|
|
UnderlyingCode = "600406.SH",
|
|
ExDividendDate = new DateTime(2020, 7, 8),
|
|
GiveCashAmount = 2.9m,
|
|
GiveShareAmount = 0,
|
|
RationedSharesAmount = 0,
|
|
RationedSharesPrice = 0,
|
|
};
|
|
price = service.GetPrice(20.1893, info);
|
|
Assert.IsTrue((price - 19.9785) < 1e-4);
|
|
|
|
info = new ex_dividend_info()
|
|
{
|
|
UnderlyingCode = "600406.SH",
|
|
ExDividendDate = new DateTime(2020, 7, 8),
|
|
GiveCashAmount = 2.9m,
|
|
GiveShareAmount = 0,
|
|
RationedSharesAmount = 0,
|
|
RationedSharesPrice = 0,
|
|
};
|
|
price = service.GetPrice(19.9454, info);
|
|
Assert.IsTrue((price - 19.7371) < 1e-4);
|
|
|
|
info = new ex_dividend_info()
|
|
{
|
|
UnderlyingCode = "601021.SH",
|
|
ExDividendDate = new DateTime(2020, 7, 8),
|
|
GiveCashAmount = 2.0006m,
|
|
GiveShareAmount = 0,
|
|
RationedSharesAmount = 0,
|
|
RationedSharesPrice = 0,
|
|
};
|
|
price = service.GetPrice(37.13, info);
|
|
Assert.IsTrue((price - 36.9776) < 1e-4);
|
|
|
|
info = new ex_dividend_info()
|
|
{
|
|
UnderlyingCode = "300001.SZ",
|
|
ExDividendDate = new DateTime(2020, 7, 13),
|
|
GiveCashAmount = 0.2m,
|
|
GiveShareAmount = 0,
|
|
RationedSharesAmount = 0,
|
|
RationedSharesPrice = 0,
|
|
};
|
|
price = service.GetPrice(20.381, info);
|
|
Assert.IsTrue((price - 20.3681) < 1e-4);
|
|
}
|
|
}
|
|
}
|
|
|