using YLErp.Model; using YLErp.Models; namespace YLErp.Modules.RiskHedgingModule { /// /// 自动对冲规则服务 /// public class TradeAutoRuleService : YLBaseService { public TradeAutoRuleService(OptUserInfo userInfo) : base(userInfo) { } /// /// 为风险对冲页面应用自动对冲规则 /// public void ApplyAutoRuleForShowing(int userId, IEnumerable groupRisks) { var autoRuleDic = DbContext.trade_autorule.Where(n => n.OptId == userId && n.Enable) .Select(n => new trade_autoruleDto { UnderlyingCode = n.UnderlyingCode, DeltaPercent = n.DeltaPercent / 100, PnlAdjust = n.PnlAdjust, PnlAdjustType = n.PnlAdjustType }).ToDictionary(n => n.UnderlyingCode, StringComparer.OrdinalIgnoreCase); if (!autoRuleDic.Any()) { return; } foreach (var g in groupRisks ?? Enumerable.Empty()) { if (g.viewList == null || !autoRuleDic.TryGetValue(g.UnderlyingCode, out var rule)) { continue; } double notionalSum = 0, deltaSum = 0, deltaLotsSum = 0; foreach (var item in g.viewList) { //对冲交易应用规则 if (ConsTrade.TradeTypesForHedge.Contains(item.TradeType)) { if (double.IsNaN(item.ExercisePnl) || double.IsInfinity(item.ExercisePnl)) { item.ExercisePnl = 0; } if (double.IsNaN(item.TotalPnl) || double.IsInfinity(item.TotalPnl)) { item.TotalPnl = 0; } if (rule.PnlAdjustType == "固定") { item.TotalPnl += rule.PnlAdjust; item.ExercisePnl += rule.PnlAdjust; } else if (rule.PnlAdjustType == "比例") { item.TotalPnl *= 1 + rule.PnlAdjust / 100; item.ExercisePnl *= 1 + rule.PnlAdjust / 100; } if (rule.DeltaPercent > 0) { item.Delta /= rule.DeltaPercent; item.DeltaInLots /= rule.DeltaPercent; } } else if (!double.IsNaN(item.Notional) && !double.IsInfinity(item.Notional)) { notionalSum += item.Notional; } if (!double.IsNaN(item.Delta) && !double.IsInfinity(item.Delta)) { deltaSum += item.Delta; deltaLotsSum += item.DeltaInLots; } } //设置组数据 g.Delta = deltaSum; g.DeltaInLots = deltaLotsSum; g.DeltaPercent = deltaSum / notionalSum; if (double.IsNaN(g.ExercisePnl) || double.IsInfinity(g.ExercisePnl)) { g.ExercisePnl = 0; } if (double.IsNaN(g.TotalPnl) || double.IsInfinity(g.TotalPnl)) { g.TotalPnl = 0; } if (rule.PnlAdjustType == "固定") { g.TotalPnl += rule.PnlAdjust; g.ExercisePnl += rule.PnlAdjust; } else if (rule.PnlAdjustType == "比例") { g.TotalPnl *= 1 + rule.PnlAdjust / 100; g.ExercisePnl *= 1 + rule.PnlAdjust / 100; } } } /// /// 为风险对冲交易应用自动对冲规则 /// public void ApplyAutoRuleForHedging(int userId, IEnumerable groupRisks) { var autoRuleDic = DbContext.trade_autorule.Where(n => n.OptId == userId && n.Enable) .Select(n => new trade_autoruleDto { UnderlyingCode = n.UnderlyingCode, DeltaPercent = n.DeltaPercent / 100 }).ToDictionary(n => n.UnderlyingCode, StringComparer.OrdinalIgnoreCase); foreach (var g in groupRisks) { g.DeltaPercent = 1; if (g.viewList == null || !autoRuleDic.TryGetValue(g.UnderlyingCode, out var rule) || rule.DeltaPercent < 0.00001) { continue; } double otcDeltaInLotsSum = 0, hedgingDeltaInLotsSum = 0, ruleDeltaSum = 0; foreach (var item in g.viewList) { if (ConsTrade.TradeTypesForHedge.Contains(item.TradeType)) { if (double.IsNaN(item.Delta) || double.IsInfinity(item.Delta)) { item.Delta = 0; } if (double.IsNaN(item.DeltaInLots) || double.IsInfinity(item.DeltaInLots)) { item.DeltaInLots = 0; } hedgingDeltaInLotsSum += item.DeltaInLots; item.Delta /= rule.DeltaPercent; item.DeltaInLots /= rule.DeltaPercent; } else { otcDeltaInLotsSum += item.DeltaInLots; } if (!double.IsNaN(item.Delta) && !double.IsInfinity(item.Delta)) { ruleDeltaSum += item.Delta; } } //设置组数据 g.Delta = ruleDeltaSum; g.DeltaPercent = rule.DeltaPercent; g.DeltaInLots = hedgingDeltaInLotsSum + otcDeltaInLotsSum * rule.DeltaPercent; } } } }