| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- using System.ComponentModel.DataAnnotations;
- namespace Domain.Entities.Stocks;
- /// <summary>
- /// SEIBro 파생결합증권 기초자산 정보 (getAssetInfo) — 기초자산명·행사기준가·평가일 (Wave 5). 자연키 UNIQUE (Isin, AssetSeq).
- /// rolling per-ISIN(DerivMaster 있는 것). 한 파생결합증권이 여러 기초자산(AssetSeq)을 가진다.
- /// ⚠️ 표준기초자산코드(StndBassetCd)는 getBassetUnredScale 입력 13종(KSD02*)과 다른 체계(KSD31*/KR7*)로 반환될 수 있어 **원문 그대로 저장**(매핑 흡수 금지).
- /// 소수 precision 은 넉넉히(파생결합증권.md 행사기준가 NUMBER(26,10)). Isin 은 응답에 있으나(가이드 누락분) 없으면 요청값 스탬핑.
- /// </summary>
- public class DerivAsset
- {
- [Key]
- public int ID { get; private set; }
- /// <summary>종목코드 (ISIN, 스탬핑) — getDerivCombiIsinInfo 연계</summary>
- public string Isin { get; private set; } = default!;
- /// <summary>자산일련번호 (ASSET_SEQ)</summary>
- public int AssetSeq { get; private set; }
- /// <summary>표준기초자산코드 (STND_BASSET_CD) — 원문 (KSD31*·KR7* 등 반환 체계 상이할 수 있음)</summary>
- public string? StndBassetCd { get; private set; }
- /// <summary>표준기초자산명 (STND_BASSET_NM) — 예 Hang Seng China Enterprises Index</summary>
- public string? StndBassetNm { get; private set; }
- /// <summary>행사기준가 (XRC_STDPRC)</summary>
- public decimal? XrcStdprc { get; private set; }
- /// <summary>행사정지하한비율 (XRC_STOP_LOLMT_RATIO)</summary>
- public decimal? XrcStopLolmtRatio { get; private set; }
- /// <summary>행사정지하한가격 (XRC_STOP_LOLMT_PRICE)</summary>
- public decimal? XrcStopLolmtPrice { get; private set; }
- /// <summary>행사정지상한비율 (XRC_STOP_UPLMT_RATIO)</summary>
- public decimal? XrcStopUplmtRatio { get; private set; }
- /// <summary>행사정지상한가격 (XRC_STOP_UPLMT_PRICE)</summary>
- public decimal? XrcStopUplmtPrice { get; private set; }
- /// <summary>기초자산최초평가구분코드 (BASSET_FIRST_VALAT_TPCD) — 1종가 2산술평균 3장중가 9기타</summary>
- public string? BassetFirstValatTpcd { get; private set; }
- /// <summary>기초자산최종평가구분코드 (BASSET_LAST_VALAT_TPCD)</summary>
- public string? BassetLastValatTpcd { get; private set; }
- /// <summary>최초기준가결정시작일자 (FIRST_STDPRC_DECSN_BEGIN_DT)</summary>
- public DateOnly? FirstStdprcDecsnBeginDt { get; private set; }
- /// <summary>최초기준가결정종료일자 (FIRST_STDPRC_DECSN_EXPRY_DT)</summary>
- public DateOnly? FirstStdprcDecsnExpryDt { get; private set; }
- /// <summary>최종기준가결정시작일자 (LAST_STDPRC_DECSN_BEGIN_DT)</summary>
- public DateOnly? LastStdprcDecsnBeginDt { get; private set; }
- /// <summary>최종기준가결정종료일자 (LAST_STDPRC_DECSN_EXPRY_DT)</summary>
- public DateOnly? LastStdprcDecsnExpryDt { get; private set; }
- /// <summary>절상절사구분코드 (RVLT_SEVER_TPCD) — 1올림 2버림 3반올림 9해당없음</summary>
- public string? RvltSeverTpcd { get; private set; }
- public DateTime UpdatedAt { get; private set; } = DateTime.UtcNow;
- private DerivAsset() { }
- public static DerivAsset Create(string isin, int assetSeq, DerivAssetFields f)
- {
- if (string.IsNullOrWhiteSpace(isin))
- {
- throw new ArgumentException("isin required", nameof(isin));
- }
- var entity = new DerivAsset { Isin = isin.Trim(), AssetSeq = assetSeq };
- entity.Apply(f);
- return entity;
- }
- /// <summary>재수집 반영 — 변경 필드가 있을 때만 UpdatedAt 갱신 (자연키 Isin/AssetSeq 은 불변)</summary>
- public void Update(DerivAssetFields f)
- {
- Apply(f);
- }
- private void Apply(DerivAssetFields f)
- {
- var changed = false;
- changed |= Set(Trimmed(f.StndBassetCd), StndBassetCd, v => StndBassetCd = v);
- changed |= Set(Trimmed(f.StndBassetNm), StndBassetNm, v => StndBassetNm = v);
- changed |= Set(f.XrcStdprc, XrcStdprc, v => XrcStdprc = v);
- changed |= Set(f.XrcStopLolmtRatio, XrcStopLolmtRatio, v => XrcStopLolmtRatio = v);
- changed |= Set(f.XrcStopLolmtPrice, XrcStopLolmtPrice, v => XrcStopLolmtPrice = v);
- changed |= Set(f.XrcStopUplmtRatio, XrcStopUplmtRatio, v => XrcStopUplmtRatio = v);
- changed |= Set(f.XrcStopUplmtPrice, XrcStopUplmtPrice, v => XrcStopUplmtPrice = v);
- changed |= Set(Trimmed(f.BassetFirstValatTpcd), BassetFirstValatTpcd, v => BassetFirstValatTpcd = v);
- changed |= Set(Trimmed(f.BassetLastValatTpcd), BassetLastValatTpcd, v => BassetLastValatTpcd = v);
- changed |= Set(f.FirstStdprcDecsnBeginDt, FirstStdprcDecsnBeginDt, v => FirstStdprcDecsnBeginDt = v);
- changed |= Set(f.FirstStdprcDecsnExpryDt, FirstStdprcDecsnExpryDt, v => FirstStdprcDecsnExpryDt = v);
- changed |= Set(f.LastStdprcDecsnBeginDt, LastStdprcDecsnBeginDt, v => LastStdprcDecsnBeginDt = v);
- changed |= Set(f.LastStdprcDecsnExpryDt, LastStdprcDecsnExpryDt, v => LastStdprcDecsnExpryDt = v);
- changed |= Set(Trimmed(f.RvltSeverTpcd), RvltSeverTpcd, v => RvltSeverTpcd = 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>DerivAsset 필드 묶음 (getAssetInfo — 자연키 AssetSeq 제외 필드)</summary>
- public sealed record DerivAssetFields(
- string? StndBassetCd,
- string? StndBassetNm,
- decimal? XrcStdprc,
- decimal? XrcStopLolmtRatio,
- decimal? XrcStopLolmtPrice,
- decimal? XrcStopUplmtRatio,
- decimal? XrcStopUplmtPrice,
- string? BassetFirstValatTpcd,
- string? BassetLastValatTpcd,
- DateOnly? FirstStdprcDecsnBeginDt,
- DateOnly? FirstStdprcDecsnExpryDt,
- DateOnly? LastStdprcDecsnBeginDt,
- DateOnly? LastStdprcDecsnExpryDt,
- string? RvltSeverTpcd
- );
|