#EQD-6948 国联民生-实现保证金规则(2)追保金额的产生与收盘计算 ETF 子类分档(转债ETF/科创债ETF)
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
using YLErp.DBModels;
|
||||
using YLErp.Enums;
|
||||
using YLErp.Modules.MarginModule;
|
||||
|
||||
namespace YLErp.Modules.CalcModules
|
||||
{
|
||||
/// <summary>
|
||||
/// ETF 子类分档取数(MarginTemplateV2RateHelper.PreferCategoryRows 纯函数):
|
||||
/// 标的有 EtfSubType(基金类,分类判定钩子实装=读 underlying_manager.EtfSubType)时,
|
||||
/// 期限档匹配结果内优先取 EtfKind=子类 的行;未命中时回落"子类+BondTerm 空"行;
|
||||
/// 均无则维持原期限档匹配结果(基金通配行兜底)。
|
||||
/// </summary>
|
||||
[TestClass]
|
||||
public class MarginTemplateV2EtfKindMatchTest
|
||||
{
|
||||
private static margin_template_detail Row(int id, UnderlyingTypeEnum ut, string etfKind, string bondTerm)
|
||||
=> new()
|
||||
{
|
||||
id = id,
|
||||
UnderlyingType = ut,
|
||||
SpanConfigJson = null,
|
||||
SpanConfig = new SpanConfig { EtfKind = etfKind, BondTerm = bondTerm }
|
||||
};
|
||||
|
||||
private const string CB = "可转债 ETF";
|
||||
private const string STAR = "科创债 ETF";
|
||||
|
||||
[TestMethod]
|
||||
public void EK_001_期限档命中子类行_优先取子类()
|
||||
{
|
||||
//期限档匹配结果内既有 子类行又有 通配行:取子类行
|
||||
var termMatched = new List<margin_template_detail>
|
||||
{
|
||||
Row(1, UnderlyingTypeEnum.Fund, CB, "<5y"), //子类+精确档
|
||||
Row(2, UnderlyingTypeEnum.Fund, null, "<5y"), //通配+精确档
|
||||
};
|
||||
var all = new List<margin_template_detail>(termMatched);
|
||||
var matched = MarginTemplateV2RateHelper.PreferCategoryRows(termMatched, all, CB);
|
||||
Assert.AreEqual(1, matched.Count);
|
||||
Assert.AreEqual(1, matched[0].id);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void EK_002_期限档未命中子类行_回落子类空档行()
|
||||
{
|
||||
//期限档匹配(>30y)结果内无子类行 → 取"子类+BondTerm 空"的未分档行
|
||||
var termMatched = new List<margin_template_detail>
|
||||
{
|
||||
Row(2, UnderlyingTypeEnum.Fund, null, null), //通配(BondTerm 空兜底命中)
|
||||
};
|
||||
var all = new List<margin_template_detail>
|
||||
{
|
||||
Row(1, UnderlyingTypeEnum.Fund, CB, "<5y"),
|
||||
Row(3, UnderlyingTypeEnum.Fund, CB, null), //子类未分档行(兜底候选)
|
||||
Row(2, UnderlyingTypeEnum.Fund, null, null),
|
||||
};
|
||||
var matched = MarginTemplateV2RateHelper.PreferCategoryRows(termMatched, all, CB);
|
||||
Assert.AreEqual(1, matched.Count);
|
||||
Assert.AreEqual(3, matched[0].id);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void EK_003_无子类行_维持原期限档匹配结果()
|
||||
{
|
||||
//模板无该子类任何行:维持原结果(通配兜底)
|
||||
var termMatched = new List<margin_template_detail>
|
||||
{
|
||||
Row(2, UnderlyingTypeEnum.Fund, null, null),
|
||||
};
|
||||
var all = new List<margin_template_detail>(termMatched)
|
||||
{
|
||||
Row(4, UnderlyingTypeEnum.Fund, STAR, "5y-10y"), //别的子类不相关
|
||||
};
|
||||
var matched = MarginTemplateV2RateHelper.PreferCategoryRows(termMatched, all, CB);
|
||||
Assert.AreEqual(1, matched.Count);
|
||||
Assert.AreEqual(2, matched[0].id);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void EK_004_多子类并存_各自命中不串()
|
||||
{
|
||||
//转债ETF 与 科创债ETF 各自成组:转债标的只命中转债行
|
||||
var termMatched = new List<margin_template_detail>
|
||||
{
|
||||
Row(1, UnderlyingTypeEnum.Fund, CB, "<5y"),
|
||||
Row(4, UnderlyingTypeEnum.Fund, STAR, "<5y"),
|
||||
Row(2, UnderlyingTypeEnum.Fund, null, "<5y"),
|
||||
};
|
||||
var all = new List<margin_template_detail>(termMatched);
|
||||
var cbMatched = MarginTemplateV2RateHelper.PreferCategoryRows(termMatched, all, CB);
|
||||
Assert.AreEqual(1, cbMatched.Count);
|
||||
Assert.AreEqual(1, cbMatched[0].id);
|
||||
var starMatched = MarginTemplateV2RateHelper.PreferCategoryRows(termMatched, all, STAR);
|
||||
Assert.AreEqual(1, starMatched.Count);
|
||||
Assert.AreEqual(4, starMatched[0].id);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void EK_005_子类行但期限档不带BondTerm_不视为未分档兜底()
|
||||
{
|
||||
//子类+分档行(EtfKind=CB + BondTerm 非空)不能当"子类+空档"兜底候选
|
||||
var termMatched = new List<margin_template_detail>
|
||||
{
|
||||
Row(2, UnderlyingTypeEnum.Fund, null, null),
|
||||
};
|
||||
var all = new List<margin_template_detail>
|
||||
{
|
||||
Row(1, UnderlyingTypeEnum.Fund, CB, "<5y"), //分档行不是兜底候选
|
||||
Row(2, UnderlyingTypeEnum.Fund, null, null),
|
||||
};
|
||||
var matched = MarginTemplateV2RateHelper.PreferCategoryRows(termMatched, all, CB);
|
||||
Assert.AreEqual(1, matched.Count);
|
||||
Assert.AreEqual(2, matched[0].id);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user