| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- using System.ComponentModel.DataAnnotations;
- using Domain.Entities.Stocks.ValueObject;
- namespace Domain.Entities.Stocks;
- /// <summary>
- /// 채권(국채전문유통/일반채권/소액채권) 일별매매 시세 (KRX OpenAPI bon 엔드포인트) — (BondMarket, Code, TradeDate) UNIQUE.
- /// 세 시장을 한 테이블에 담고 BondMarket 으로 구분한다. 채권은 가격 + 수익률(YD) 쌍으로 제공되며 주식/증권상품과 필드가 다르다:
- /// - 가격/전일대비: CLSPRC/OPNPRC/HGPRC/LWPRC + CMPPREVDD_PRC (주식의 TDD_* 아님). 등락률(FLUC_RT)·시가총액·상장주식수는 미제공.
- /// - 수익률(YD): CLSPRC_YD(만기수익률=종가수익률), OPNPRC_YD/HGPRC_YD/LWPRC_YD — 모두 nullable(미체결 시 "").
- /// - 국채전문(KtsGovt)만: MaturityYears(BND_EXP_TP_NM 만기년수), IssueType(GOVBND_ISU_TP_NM 종목구분 예: "지표"/"경과"). 일반/소액은 null.
- /// 단축코드(ISU_CD)는 12자리 ISIN(예: KR103503GE96) — 6자리 정규화 없이 원문 유지. 가격은 decimal(18,2), 수익률은 decimal(9,3)%.
- /// </summary>
- public class BondDailyTrade
- {
- [Key]
- public long ID { get; private set; }
- /// <summary>채권 시장 구분 (1=국채전문유통, 2=일반채권, 3=소액채권)</summary>
- public BondMarket BondMarket { get; private set; }
- /// <summary>단축코드 (ISU_CD) — 12자리 ISIN(예: KR103503GE96)</summary>
- public string Code { get; private set; } = default!;
- /// <summary>종목명 (ISU_NM)</summary>
- public string Name { get; private set; } = default!;
- /// <summary>거래일 (BAS_DD)</summary>
- public DateOnly TradeDate { get; private set; }
- /// <summary>종가 가격 (CLSPRC)</summary>
- public decimal Close { get; private set; }
- /// <summary>시가 가격 (OPNPRC)</summary>
- public decimal Open { get; private set; }
- /// <summary>고가 가격 (HGPRC)</summary>
- public decimal High { get; private set; }
- /// <summary>저가 가격 (LWPRC)</summary>
- public decimal Low { get; private set; }
- /// <summary>전일 대비 (CMPPREVDD_PRC) — 미제공("") 시 0</summary>
- public decimal ChangeAmount { get; private set; }
- /// <summary>만기수익률 % (CLSPRC_YD 종가수익률) — 미체결 시 null</summary>
- public decimal? YieldToMaturity { get; private set; }
- /// <summary>시가 수익률 % (OPNPRC_YD) — 미체결 시 null</summary>
- public decimal? OpenYield { get; private set; }
- /// <summary>고가 수익률 % (HGPRC_YD) — 미체결 시 null</summary>
- public decimal? HighYield { get; private set; }
- /// <summary>저가 수익률 % (LWPRC_YD) — 미체결 시 null</summary>
- public decimal? LowYield { get; private set; }
- /// <summary>거래량 (ACC_TRDVOL)</summary>
- public long Volume { get; private set; }
- /// <summary>거래대금 (ACC_TRDVAL, 원)</summary>
- public long TradeValue { get; private set; }
- /// <summary>만기년수 (BND_EXP_TP_NM) — 국채전문만. 일반/소액은 null</summary>
- public string? MaturityYears { get; private set; }
- /// <summary>종목구분 (GOVBND_ISU_TP_NM 예: "지표"/"경과") — 국채전문만. 일반/소액은 null</summary>
- public string? IssueType { get; private set; }
- public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
- private BondDailyTrade() { }
- public static BondDailyTrade Create(
- BondMarket bondMarket,
- string code,
- string name,
- DateOnly tradeDate,
- decimal close,
- decimal open,
- decimal high,
- decimal low,
- decimal changeAmount,
- decimal? yieldToMaturity,
- decimal? openYield,
- decimal? highYield,
- decimal? lowYield,
- long volume,
- long tradeValue,
- string? maturityYears = null,
- string? issueType = null
- ) {
- if (!Enum.IsDefined(bondMarket))
- {
- throw new ArgumentOutOfRangeException(nameof(bondMarket));
- }
- if (string.IsNullOrWhiteSpace(code))
- {
- throw new ArgumentException("code required", nameof(code));
- }
- if (string.IsNullOrWhiteSpace(name))
- {
- throw new ArgumentException("name required", nameof(name));
- }
- return new BondDailyTrade
- {
- BondMarket = bondMarket,
- Code = code.Trim(),
- Name = name.Trim(),
- TradeDate = tradeDate,
- Close = close,
- Open = open,
- High = high,
- Low = low,
- ChangeAmount = changeAmount,
- YieldToMaturity = yieldToMaturity,
- OpenYield = openYield,
- HighYield = highYield,
- LowYield = lowYield,
- Volume = volume,
- TradeValue = tradeValue,
- MaturityYears = maturityYears,
- IssueType = issueType
- };
- }
- /// <summary>동일 (BondMarket, Code, TradeDate) 재수집 시 값 갱신 (upsert)</summary>
- public void Update(
- string name,
- decimal close,
- decimal open,
- decimal high,
- decimal low,
- decimal changeAmount,
- decimal? yieldToMaturity,
- decimal? openYield,
- decimal? highYield,
- decimal? lowYield,
- long volume,
- long tradeValue,
- string? maturityYears = null,
- string? issueType = null
- ) {
- Name = name.Trim();
- Close = close;
- Open = open;
- High = high;
- Low = low;
- ChangeAmount = changeAmount;
- YieldToMaturity = yieldToMaturity;
- OpenYield = openYield;
- HighYield = highYield;
- LowYield = lowYield;
- Volume = volume;
- TradeValue = tradeValue;
- MaturityYears = maturityYears;
- IssueType = issueType;
- }
- }
|