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
67 lines
2.3 KiB
C#
67 lines
2.3 KiB
C#
using System;
|
|
|
|
namespace QuantEngine.Core.Domain
|
|
{
|
|
public class ProfitLockResult
|
|
{
|
|
public string RatchetStage { get; set; } = "NORMAL";
|
|
public double? AutoTrailingStop { get; set; }
|
|
public string TpLadderAction { get; set; } = "적용 안함";
|
|
public bool ApexSuperActive { get; set; }
|
|
}
|
|
|
|
public static class ProfitLockCalculator
|
|
{
|
|
public static string ClassifyProfitLockStage(double profitPct)
|
|
{
|
|
if (profitPct >= 60) return "APEX_SUPER";
|
|
if (profitPct >= 40) return "APEX_TRAILING";
|
|
if (profitPct >= 30) return "PROFIT_LOCK_30";
|
|
if (profitPct >= 20) return "PROFIT_LOCK_20";
|
|
if (profitPct >= 10) return "PROFIT_LOCK_10";
|
|
if (profitPct >= 0) return "BREAKEVEN_RATCHET";
|
|
return "NORMAL";
|
|
}
|
|
|
|
public static ProfitLockResult ComputeTrailingStop(
|
|
double profitPct,
|
|
double highestClose,
|
|
double atr20,
|
|
double? ratchetStop,
|
|
double averageCost)
|
|
{
|
|
string stage = ClassifyProfitLockStage(profitPct);
|
|
double baseStop = ratchetStop ?? averageCost;
|
|
double? trailingStop = null;
|
|
string tpAction = "적용 안함";
|
|
|
|
if (stage == "APEX_SUPER")
|
|
{
|
|
double raw = highestClose - 1.2 * atr20;
|
|
trailingStop = KrxTickNormalizer.NormalizeTick(Math.Max(baseStop, raw));
|
|
tpAction = "강제 10% 익절 권고";
|
|
}
|
|
else if (stage == "APEX_TRAILING")
|
|
{
|
|
double raw = highestClose - 1.5 * atr20;
|
|
trailingStop = KrxTickNormalizer.NormalizeTick(Math.Max(baseStop, raw));
|
|
tpAction = "부분익절 검토";
|
|
}
|
|
else if (stage == "PROFIT_LOCK_30" || stage == "PROFIT_LOCK_20")
|
|
{
|
|
double raw = highestClose - 2.0 * atr20;
|
|
trailingStop = KrxTickNormalizer.NormalizeTick(Math.Max(baseStop, raw));
|
|
tpAction = "래칫 유지";
|
|
}
|
|
|
|
return new ProfitLockResult
|
|
{
|
|
RatchetStage = stage,
|
|
AutoTrailingStop = trailingStop,
|
|
TpLadderAction = tpAction,
|
|
ApexSuperActive = stage == "APEX_SUPER"
|
|
};
|
|
}
|
|
}
|
|
}
|