167 lines
6.4 KiB
C#
167 lines
6.4 KiB
C#
using YLErp.Model;
|
|
using YLErp.Models;
|
|
|
|
namespace YLErp.Modules.RiskHedgingModule
|
|
{
|
|
/// <summary>
|
|
/// 自动对冲规则服务
|
|
/// </summary>
|
|
public class TradeAutoRuleService : YLBaseService
|
|
{
|
|
public TradeAutoRuleService(OptUserInfo userInfo) : base(userInfo)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// 为风险对冲页面应用自动对冲规则
|
|
/// </summary>
|
|
public void ApplyAutoRuleForShowing(int userId, IEnumerable<TradingRiskParameter> 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<TradingRiskParameter>())
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 为风险对冲交易应用自动对冲规则
|
|
/// </summary>
|
|
public void ApplyAutoRuleForHedging(int userId, IEnumerable<TradingRiskParameter> 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;
|
|
}
|
|
}
|
|
}
|
|
}
|