using System.ComponentModel.DataAnnotations; namespace Domain.Entities.Stocks; /// /// SEIBro 종목별 대차거래 현황 (getSlbDealingByIsin) — 대차잔고·외국인/내국인 대여·차입 금액·비율 (Wave 2 ★P1). /// KSD 중개거래 한함. 자연키 UNIQUE (Isin, StdDt) — 한 종목·기준일당 1행. /// 요청은 ISIN + STD_DT 둘 다 필수라 per-ISIN×일 rolling 으로 수집한다. /// 금액은 NUMBER(16), 비율은 NUMBER(5,2) — 비율은 decimal(6,2) 로 안전 저장(음수 없음). /// public class SecuritiesLending { [Key] public int ID { get; private set; } /// 종목코드 (ISIN) public string Isin { get; private set; } = default!; /// 기준일 (STD_DT) public DateOnly StdDt { get; private set; } /// 총발행주식수 (TOT_ISSU_STKQTY) public long? TotIssuStkqty { get; private set; } /// 일일거래량 (TR_QTY) public long? TrQty { get; private set; } /// 대차체결량 (MATC_QTY) public long? MatcQty { get; private set; } /// 대차상환량 (RED_QTY) public long? RedQty { get; private set; } /// 대차잔고주수 (SLB_TR_REM_QTY) — 기준일 현재 잔고 public long? SlbTrRemQty { get; private set; } /// 외국인 대여잔고금액 (FRINER_LEND_REM_AMT) public long? FrinerLendRemAmt { get; private set; } /// 외국인 대여잔고비율 (FRINER_LEND_REM_RATIO) public decimal? FrinerLendRemRatio { get; private set; } /// 내국인 대여잔고금액 (NATIVE_LEND_REM_AMT) public long? NativeLendRemAmt { get; private set; } /// 내국인 대여잔고비율 (NATIVE_LEND_REM_RATIO) public decimal? NativeLendRemRatio { get; private set; } /// 외국인 차입잔고금액 (FRINER_BRW_REM_AMT) public long? FrinerBrwRemAmt { get; private set; } /// 외국인 차입잔고비율 (FRINER_BRW_REM_RATIO) public decimal? FrinerBrwRemRatio { get; private set; } /// 내국인 차입잔고금액 (NATIVE_BRW_REM_AMT) public long? NativeBrwRemAmt { get; private set; } /// 내국인 차입잔고비율 (NATIVE_BRW_REM_RATIO) public decimal? NativeBrwRemRatio { get; private set; } public DateTime UpdatedAt { get; private set; } = DateTime.UtcNow; private SecuritiesLending() { } public static SecuritiesLending Create( string isin, DateOnly stdDt, long? totIssuStkqty, long? trQty, long? matcQty, long? redQty, long? slbTrRemQty, long? frinerLendRemAmt, decimal? frinerLendRemRatio, long? nativeLendRemAmt, decimal? nativeLendRemRatio, long? frinerBrwRemAmt, decimal? frinerBrwRemRatio, long? nativeBrwRemAmt, decimal? nativeBrwRemRatio) { if (string.IsNullOrWhiteSpace(isin)) { throw new ArgumentException("isin required", nameof(isin)); } return new SecuritiesLending { Isin = isin.Trim(), StdDt = stdDt, TotIssuStkqty = totIssuStkqty, TrQty = trQty, MatcQty = matcQty, RedQty = redQty, SlbTrRemQty = slbTrRemQty, FrinerLendRemAmt = frinerLendRemAmt, FrinerLendRemRatio = frinerLendRemRatio, NativeLendRemAmt = nativeLendRemAmt, NativeLendRemRatio = nativeLendRemRatio, FrinerBrwRemAmt = frinerBrwRemAmt, FrinerBrwRemRatio = frinerBrwRemRatio, NativeBrwRemAmt = nativeBrwRemAmt, NativeBrwRemRatio = nativeBrwRemRatio }; } /// 재수집 반영 — 변경 필드가 있을 때만 UpdatedAt 갱신 (무변경 upsert 는 no-op) public void Update( long? totIssuStkqty, long? trQty, long? matcQty, long? redQty, long? slbTrRemQty, long? frinerLendRemAmt, decimal? frinerLendRemRatio, long? nativeLendRemAmt, decimal? nativeLendRemRatio, long? frinerBrwRemAmt, decimal? frinerBrwRemRatio, long? nativeBrwRemAmt, decimal? nativeBrwRemRatio) { var changed = false; if (TotIssuStkqty != totIssuStkqty) { TotIssuStkqty = totIssuStkqty; changed = true; } if (TrQty != trQty) { TrQty = trQty; changed = true; } if (MatcQty != matcQty) { MatcQty = matcQty; changed = true; } if (RedQty != redQty) { RedQty = redQty; changed = true; } if (SlbTrRemQty != slbTrRemQty) { SlbTrRemQty = slbTrRemQty; changed = true; } if (FrinerLendRemAmt != frinerLendRemAmt) { FrinerLendRemAmt = frinerLendRemAmt; changed = true; } if (FrinerLendRemRatio != frinerLendRemRatio) { FrinerLendRemRatio = frinerLendRemRatio; changed = true; } if (NativeLendRemAmt != nativeLendRemAmt) { NativeLendRemAmt = nativeLendRemAmt; changed = true; } if (NativeLendRemRatio != nativeLendRemRatio) { NativeLendRemRatio = nativeLendRemRatio; changed = true; } if (FrinerBrwRemAmt != frinerBrwRemAmt) { FrinerBrwRemAmt = frinerBrwRemAmt; changed = true; } if (FrinerBrwRemRatio != frinerBrwRemRatio) { FrinerBrwRemRatio = frinerBrwRemRatio; changed = true; } if (NativeBrwRemAmt != nativeBrwRemAmt) { NativeBrwRemAmt = nativeBrwRemAmt; changed = true; } if (NativeBrwRemRatio != nativeBrwRemRatio) { NativeBrwRemRatio = nativeBrwRemRatio; changed = true; } if (changed) { UpdatedAt = DateTime.UtcNow; } } }