| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- using System.ComponentModel.DataAnnotations;
- namespace Domain.Entities.Stocks;
- /// <summary>
- /// SEIBro 파생결합증권 종목 정보 (getDerivCombiIsinInfo) — 원금보전·만기·발행잔량·기초자산수 (Wave 5). PK Isin.
- /// rolling per-ISIN 대상 = DerivIssuance.Isin. ELS/DLS 상세 조회의 주 마스터. 발행잔량(IssuRemq)·만기(XpirDt) 는 리스크 지표.
- /// 소수/금액 precision 은 넉넉히(파생결합증권.md NUMBER(18,2)/NUMBER(13,10)/NUMBER(6,3)). 재수집 시 스냅샷 갱신.
- /// </summary>
- public class DerivMaster
- {
- /// <summary>종목코드 (ISIN) — PK</summary>
- [Key]
- [MaxLength(12)]
- public string Isin { get; private set; } = default!;
- /// <summary>한글종목명 (KOR_SECN_NM)</summary>
- public string? KorSecnNm { get; private set; }
- /// <summary>발행회사고객번호 (ISSUCO_CUSTNO)</summary>
- public int? IssucoCustno { get; private set; }
- /// <summary>종목구분명 (SECN_KANM) — ELS/ELB/ELW/DLS/DLB/ETN</summary>
- public string? SecnKanm { get; private set; }
- /// <summary>발행통화코드 (ISSU_CUR_CD) — KRW</summary>
- public string? IssuCurCd { get; private set; }
- /// <summary>모집방법코드 (RECU_WHCD) — 11공모 21사모</summary>
- public string? RecuWhcd { get; private set; }
- /// <summary>최초발행수량 (FIRST_ISSU_QTY)</summary>
- public decimal? FirstIssuQty { get; private set; }
- /// <summary>발행잔량 (ISSU_REMQ)</summary>
- public decimal? IssuRemq { get; private set; }
- /// <summary>납입금액비율 (PAYIN_AMT_RATIO)</summary>
- public decimal? PayinAmtRatio { get; private set; }
- /// <summary>납입금액 (PAYIN_AMT)</summary>
- public decimal? PayinAmt { get; private set; }
- /// <summary>발행일자 (ISSU_DT)</summary>
- public DateOnly? IssuDt { get; private set; }
- /// <summary>계약일자 (CONT_DT)</summary>
- public DateOnly? ContDt { get; private set; }
- /// <summary>만기일자 (XPIR_DT)</summary>
- public DateOnly? XpirDt { get; private set; }
- /// <summary>중도상환가능여부 (MIDRED_POSS_YN, Y/N)</summary>
- public bool? MidredPossYn { get; private set; }
- /// <summary>상환일자 (RED_DT) — 실제 상환일</summary>
- public DateOnly? RedDt { get; private set; }
- /// <summary>파생증권권리행사구분코드 (DERISEC_EXER_TPCD) — 2만기 3조기</summary>
- public string? DerisecExerTpcd { get; private set; }
- /// <summary>원금보전구분코드 (PRCP_PRSV_TPCD) — 1원금보장 2부분보장 3비보장 4기타 9해당없음</summary>
- public string? PrcpPrsvTpcd { get; private set; }
- /// <summary>원금보전율 (PRCP_PRSV_RATE)</summary>
- public decimal? PrcpPrsvRate { get; private set; }
- /// <summary>담보설정구분코드 (COLAT_SETUP_TPCD) — 1설정 2미설정</summary>
- public string? ColatSetupTpcd { get; private set; }
- /// <summary>기초자산 개수 (BASSET_CNT)</summary>
- public int? BassetCnt { get; private set; }
- /// <summary>월지급여부 (MM_PAY_YN, Y/N)</summary>
- public bool? MmPayYn { get; private set; }
- public DateTime UpdatedAt { get; private set; } = DateTime.UtcNow;
- private DerivMaster() { }
- public static DerivMaster Create(string isin, DerivMasterFields f)
- {
- if (string.IsNullOrWhiteSpace(isin))
- {
- throw new ArgumentException("isin required", nameof(isin));
- }
- var entity = new DerivMaster { Isin = isin.Trim() };
- entity.Apply(f);
- return entity;
- }
- /// <summary>재수집 반영 (PK Isin 은 불변) — 스냅샷 갱신, 변경 시에만 UpdatedAt</summary>
- public void Update(DerivMasterFields f)
- {
- Apply(f);
- }
- private void Apply(DerivMasterFields f)
- {
- var changed = false;
- changed |= Set(Trimmed(f.KorSecnNm), KorSecnNm, v => KorSecnNm = v);
- changed |= Set(f.IssucoCustno, IssucoCustno, v => IssucoCustno = v);
- changed |= Set(Trimmed(f.SecnKanm), SecnKanm, v => SecnKanm = v);
- changed |= Set(Trimmed(f.IssuCurCd), IssuCurCd, v => IssuCurCd = v);
- changed |= Set(Trimmed(f.RecuWhcd), RecuWhcd, v => RecuWhcd = v);
- changed |= Set(f.FirstIssuQty, FirstIssuQty, v => FirstIssuQty = v);
- changed |= Set(f.IssuRemq, IssuRemq, v => IssuRemq = v);
- changed |= Set(f.PayinAmtRatio, PayinAmtRatio, v => PayinAmtRatio = v);
- changed |= Set(f.PayinAmt, PayinAmt, v => PayinAmt = v);
- changed |= Set(f.IssuDt, IssuDt, v => IssuDt = v);
- changed |= Set(f.ContDt, ContDt, v => ContDt = v);
- changed |= Set(f.XpirDt, XpirDt, v => XpirDt = v);
- changed |= Set(f.MidredPossYn, MidredPossYn, v => MidredPossYn = v);
- changed |= Set(f.RedDt, RedDt, v => RedDt = v);
- changed |= Set(Trimmed(f.DerisecExerTpcd), DerisecExerTpcd, v => DerisecExerTpcd = v);
- changed |= Set(Trimmed(f.PrcpPrsvTpcd), PrcpPrsvTpcd, v => PrcpPrsvTpcd = v);
- changed |= Set(f.PrcpPrsvRate, PrcpPrsvRate, v => PrcpPrsvRate = v);
- changed |= Set(Trimmed(f.ColatSetupTpcd), ColatSetupTpcd, v => ColatSetupTpcd = v);
- changed |= Set(f.BassetCnt, BassetCnt, v => BassetCnt = v);
- changed |= Set(f.MmPayYn, MmPayYn, v => MmPayYn = v);
- if (changed)
- {
- UpdatedAt = DateTime.UtcNow;
- }
- }
- private static string? Trimmed(string? value)
- {
- return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
- }
- private static bool Set<T>(T incoming, T current, Action<T> assign)
- {
- if (EqualityComparer<T>.Default.Equals(incoming, current))
- {
- return false;
- }
- assign(incoming);
- return true;
- }
- }
- /// <summary>DerivMaster 필드 묶음 (getDerivCombiIsinInfo 필드 다수 — 생성/갱신 인자 축약)</summary>
- public sealed record DerivMasterFields(
- string? KorSecnNm,
- int? IssucoCustno,
- string? SecnKanm,
- string? IssuCurCd,
- string? RecuWhcd,
- decimal? FirstIssuQty,
- decimal? IssuRemq,
- decimal? PayinAmtRatio,
- decimal? PayinAmt,
- DateOnly? IssuDt,
- DateOnly? ContDt,
- DateOnly? XpirDt,
- bool? MidredPossYn,
- DateOnly? RedDt,
- string? DerisecExerTpcd,
- string? PrcpPrsvTpcd,
- decimal? PrcpPrsvRate,
- string? ColatSetupTpcd,
- int? BassetCnt,
- bool? MmPayYn
- );
|