Skip to content

Commit

Permalink
Fixes for RiskLadder calcs with MC models
Browse files Browse the repository at this point in the history
  • Loading branch information
gavbrennan committed May 10, 2024
1 parent df88ede commit ec1fe87
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 4 deletions.
55 changes: 55 additions & 0 deletions src/Qwack.Core/Cubes/CubeEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,61 @@ public static ICube Difference(this ICube baseCube, ICube cubeToSubtract)
return o;
}

public static ICube Difference(this ICube baseCube, ICube cubeToSubtract, string[] matchFields)
{
var ixsBase = new List<int>();
var ixsSub = new List<int>();
for (var i = 0; i < matchFields.Length; i++)
{
ixsBase.Add(baseCube.GetColumnIndex(matchFields[i]));
ixsSub.Add(cubeToSubtract.GetColumnIndex(matchFields[i]));
}

if (ixsBase.Any(x=>x<0) || ixsSub.Any(x=>x<0))
throw new Exception("Cubes must contain all required fields");

var o = new ResultCube();
o.Initialize(baseCube.DataTypes);
var baseRows = baseCube.GetAllRows().ToList();
var subRows = cubeToSubtract.GetAllRows().ToList();
foreach (var br in baseRows)
{
var rowFound = false;
foreach (var sr in subRows)
{
var thisRowMatched = true;
for(var i=0;i< matchFields.Length; i++)
{
if (br.MetaData[ixsBase[i]] != sr.MetaData[ixsSub[i]])
{
thisRowMatched = false;
break;
}
}
if(thisRowMatched)
{
o.AddRow(br.MetaData, br.Value - sr.Value);
subRows.Remove(sr);
rowFound = true;
break;
}
}

if (!rowFound) //zero to subtract
{
o.AddRow(br.MetaData, br.Value);
}
}

//look at what is left in subrows
foreach (var sr in subRows)
{
o.AddRow(sr.MetaData, -sr.Value);
}

return o;
}

/// <summary>
/// Differences two cubes, assuming same number and same order of rows in both
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Qwack.Models/Risk/BasicMetrics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ public static ICube AssetDeltaSingleCurve(this IPvModel pvModel, string assetId,

var lastDateInBook = subPortfolio.LastSensitivityDate;
model.AttachPortfolio(subPortfolio);
var pvCube = model.PV(curveObj.Currency);
var pvCube = pvModel.PV(curveObj.Currency);
var pvRows = pvCube.GetAllRows();

var tidIx = pvCube.GetColumnIndex(TradeId);
Expand Down
17 changes: 16 additions & 1 deletion src/Qwack.Models/Risk/RiskLadder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ public Dictionary<string, IPvModel> GenerateScenarios(IPvModel model)
return o;
}

private string[] GetCubeMatchingFields(RiskMetric riskMetric) => riskMetric switch
{
RiskMetric.AssetCurveDelta or RiskMetric.AssetVega or RiskMetric.PV01 => ["TradeId", "PointLabel", "AssetId"],
RiskMetric.PV => ["TradeId"],
_ => [],
};

public ICube Generate(IPvModel model, Portfolio portfolio = null)
{
var o = new ResultCube();
Expand All @@ -112,6 +119,7 @@ public ICube Generate(IPvModel model, Portfolio portfolio = null)

ICube baseRiskCube = null;

var matchingFields = GetCubeMatchingFields(Metric);
if (ReturnDifferential)
{
var baseModel = model;
Expand All @@ -138,7 +146,14 @@ public ICube Generate(IPvModel model, Portfolio portfolio = null)
if (ReturnDifferential)
{
result = result.Difference(baseRiskCube);
try
{
result = result.Difference(baseRiskCube, matchingFields);
}
catch (Exception ex)
{
}
}
results[i] = result;
Expand Down
2 changes: 1 addition & 1 deletion version.props
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Project>
<PropertyGroup>
<VersionPrefix>0.7.88</VersionPrefix>
<VersionPrefix>0.7.89</VersionPrefix>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.7.88
0.7.89

0 comments on commit ec1fe87

Please sign in to comment.