2ba8def9bb
WBS-9.3 - NULL Policy CI Gate / NULL Policy Validation (push) Has been cancelled
Quant Engine CI/CD Pipeline / validate-core (pull_request) Has been cancelled
Quant Engine CI/CD Pipeline / validate-ui-and-storage (pull_request) Has been cancelled
WBS-9.3 - NULL Policy CI Gate / NULL Policy Validation (pull_request) Has been cancelled
64 lines
2.2 KiB
C#
64 lines
2.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace QuantEngine.Core.Domain
|
|
{
|
|
public class SellPriceSanityResult
|
|
{
|
|
public string SellPriceSanityStatus { get; set; } = "PASS";
|
|
public List<string> SellPriceSanityIssues { get; set; } = new List<string>();
|
|
public bool HtsAllowed { get; set; } = true;
|
|
public bool ShadowLedger { get; set; }
|
|
public string Ticker { get; set; } = string.Empty;
|
|
}
|
|
|
|
public static class SellPriceSanityChecker
|
|
{
|
|
public static SellPriceSanityResult CheckSellPriceSanity(
|
|
double sellLimitPrice,
|
|
double? stopLossPrice,
|
|
double prevClose,
|
|
string ticker = "")
|
|
{
|
|
var issues = new List<string>();
|
|
string status = "PASS";
|
|
|
|
if (stopLossPrice.HasValue && sellLimitPrice < stopLossPrice.Value)
|
|
{
|
|
issues.Add($"INVALID_PRICE_INVERSION: sell={sellLimitPrice:N0} < stop={stopLossPrice.Value:N0}");
|
|
status = "INVALID_PRICE_INVERSION";
|
|
}
|
|
|
|
double upperLimit = prevClose * 1.30;
|
|
if (sellLimitPrice > upperLimit)
|
|
{
|
|
issues.Add($"INVALID_UNREALISTIC_PRICE: sell={sellLimitPrice:N0} > prev_close*1.30={upperLimit:N0}");
|
|
if (status == "PASS")
|
|
{
|
|
status = "INVALID_UNREALISTIC_PRICE";
|
|
}
|
|
}
|
|
|
|
int tickUnit = KrxTickNormalizer.GetTickUnit(sellLimitPrice);
|
|
if (sellLimitPrice % tickUnit != 0)
|
|
{
|
|
double corrected = KrxTickNormalizer.NormalizeTick(sellLimitPrice);
|
|
issues.Add($"INVALID_TICK: sell={sellLimitPrice:N0} 호가단위={tickUnit}원 → 정규화={corrected:N0}");
|
|
if (status == "PASS")
|
|
{
|
|
status = "INVALID_TICK";
|
|
}
|
|
}
|
|
|
|
return new SellPriceSanityResult
|
|
{
|
|
SellPriceSanityStatus = status,
|
|
SellPriceSanityIssues = issues,
|
|
HtsAllowed = status == "PASS",
|
|
ShadowLedger = status != "PASS",
|
|
Ticker = ticker
|
|
};
|
|
}
|
|
}
|
|
}
|