| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- using System.ComponentModel.DataAnnotations;
- using System.ComponentModel.DataAnnotations.Schema;
- namespace Domain.Entities.Paper;
- /// <summary>
- /// 모의투자 체결 결과 — 주문당 1건(OrderID UNIQUE)으로 재실행 멱등을 보장한다 (d4 §③).
- /// 배치(M2)가 TargetDate 시세로 기표한다. 매도 시 RealizedPnL(실현손익)을 기록.
- /// </summary>
- public class PaperFill
- {
- [ForeignKey(nameof(OrderID))]
- public virtual PaperOrder Order { get; private set; } = null!;
- [Key]
- public int ID { get; private set; }
- public int OrderID { get; private set; }
- /// <summary>체결가 (18,0)</summary>
- public decimal Price { get; private set; }
- public int Quantity { get; private set; }
- /// <summary>수수료 (토큰 sink)</summary>
- public decimal Fee { get; private set; }
- /// <summary>거래세 (매도 시, 토큰 sink)</summary>
- public decimal Tax { get; private set; }
- /// <summary>체결 총액 (Price × Quantity ± 수수료/세금 반영은 핸들러/배치 정책)</summary>
- public decimal Amount { get; private set; }
- /// <summary>매도 확정 손익 (매수는 null)</summary>
- public decimal? RealizedPnL { get; private set; }
- /// <summary>체결가 기준일</summary>
- public DateOnly PriceDate { get; private set; }
- public DateTime FilledAt { get; private set; } = DateTime.UtcNow;
- private PaperFill() { }
- public static PaperFill Create(
- int orderID,
- decimal price,
- int quantity,
- decimal fee,
- decimal tax,
- decimal amount,
- DateOnly priceDate,
- decimal? realizedPnL = null
- ) {
- if (orderID <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(orderID));
- }
- if (quantity <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(quantity));
- }
- return new PaperFill
- {
- OrderID = orderID,
- Price = price,
- Quantity = quantity,
- Fee = fee,
- Tax = tax,
- Amount = amount,
- PriceDate = priceDate,
- RealizedPnL = realizedPnL
- };
- }
- /// <summary>
- /// 신규 주문(ID 미확정) 케이스 — Order 내비게이션으로 생성해 EF 가 저장 시 FK(OrderID)를 자동 채우게 한다.
- /// 상폐 강제청산 등 시스템 주문+체결을 한 번에 저장할 때 사용 (d4 §⑨).
- /// </summary>
- public static PaperFill CreateFor(
- PaperOrder order,
- decimal price,
- int quantity,
- decimal fee,
- decimal tax,
- decimal amount,
- DateOnly priceDate,
- decimal? realizedPnL = null
- ) {
- ArgumentNullException.ThrowIfNull(order);
- if (quantity <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(quantity));
- }
- return new PaperFill
- {
- Order = order,
- Price = price,
- Quantity = quantity,
- Fee = fee,
- Tax = tax,
- Amount = amount,
- PriceDate = priceDate,
- RealizedPnL = realizedPnL
- };
- }
- }
|