Skip to content

Commit

Permalink
Underlying in PnL attribution
Browse files Browse the repository at this point in the history
  • Loading branch information
gavbrennan committed Aug 14, 2024
1 parent 642d5ce commit 080f903
Show file tree
Hide file tree
Showing 14 changed files with 76 additions and 39 deletions.
1 change: 1 addition & 0 deletions src/Qwack.Core/Basic/Consts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public static class Cubes
public static string SubSubStep = "SubSubStep";
public static string PointLabel = "PointLabel";
public static string PointDate = "PointDate";
public static string Underlying = "Underlying";
}
}
}
13 changes: 9 additions & 4 deletions src/Qwack.Models/Models/AttributionSteps/ActivityStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class ActivityStep(Portfolio startPortfolio, Portfolio endPortfolio) : IP
var newTradesPnL = model.PV(reportingCcy);
var tidIx = newTradesPnL.GetColumnIndex(TradeId);
var tTypeIx = newTradesPnL.GetColumnIndex(TradeType);
var r_UlIx = newTradesPnL.GetColumnIndex(Underlying);
foreach (var t in newTradesPnL.GetAllRows())
{
var tid = (string)t.MetaData[tidIx];
Expand All @@ -35,7 +36,8 @@ public class ActivityStep(Portfolio startPortfolio, Portfolio endPortfolio) : IP
{ SubStep, "New" },
{ SubSubStep, string.Empty },
{ PointLabel, string.Empty },
{ "Portfolio", pfEndDict[tid]}
{ "Portfolio", pfEndDict[tid]},
{ Underlying, r_UlIx<0 ? string.Empty : t.MetaData[r_UlIx] }
};
resultsCube.AddRow(row, t.Value);
}
Expand All @@ -48,7 +50,7 @@ public class ActivityStep(Portfolio startPortfolio, Portfolio endPortfolio) : IP

var tidIx = removedTradesPnL.GetColumnIndex(TradeId);
var tTypeIx = removedTradesPnL.GetColumnIndex(TradeType);

var r_UlIx = removedTradesPnL.GetColumnIndex(Underlying);
foreach (var t in removedTradesPnL.GetAllRows())
{
var tid = (string)t.MetaData[tidIx];
Expand All @@ -60,7 +62,8 @@ public class ActivityStep(Portfolio startPortfolio, Portfolio endPortfolio) : IP
{ SubStep, "Removed" },
{ SubSubStep, string.Empty },
{ PointLabel, string.Empty },
{ "Portfolio", pfStartDict[tid]}
{ "Portfolio", pfStartDict[tid]},
{ Underlying, r_UlIx<0 ? string.Empty : t.MetaData[r_UlIx] }
};
resultsCube.AddRow(row, -t.Value);
}
Expand All @@ -76,6 +79,7 @@ public class ActivityStep(Portfolio startPortfolio, Portfolio endPortfolio) : IP

var tidIx = amendedTradesPnLStart.GetColumnIndex(TradeId);
var tTypeIx = amendedTradesPnLStart.GetColumnIndex(TradeType);
var r_UlIx = amendedTradesPnLStart.GetColumnIndex(Underlying);

foreach (var t in amendedPnL.GetAllRows())
{
Expand All @@ -88,7 +92,8 @@ public class ActivityStep(Portfolio startPortfolio, Portfolio endPortfolio) : IP
{ SubStep, "Ammended" },
{ SubSubStep, string.Empty },
{ PointLabel, string.Empty },
{ "Portfolio", pfStartDict[tid]}
{ "Portfolio", pfStartDict[tid]},
{ Underlying, r_UlIx<0 ? string.Empty : t.MetaData[r_UlIx] }
};
resultsCube.AddRow(row, t.Value);
}
Expand Down
9 changes: 6 additions & 3 deletions src/Qwack.Models/Models/AttributionSteps/AtmVegaCurveStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public class AtmVegaCurveStep : IPnLAttributionStep
var r_tidIx = riskCube.GetColumnIndex(TradeId);
var r_plIx = riskCube.GetColumnIndex(PointLabel);
var r_tTypeIx = riskCube.GetColumnIndex(TradeType);
var r_pdIx = riskCube.GetColumnIndex("PointDate");
var r_pdIx = riskCube.GetColumnIndex(PointDate);
var r_UlIx = riskCube.GetColumnIndex(Underlying);

var startCurve = model.VanillaModel.GetVolSurface(surfaceName);
var endCurve = endModel.VanillaModel.GetVolSurface(surfaceName);
Expand All @@ -44,7 +45,8 @@ public class AtmVegaCurveStep : IPnLAttributionStep
{ SubStep, surfaceName },
{ SubSubStep, "Vega" },
{ PointLabel, r.MetaData[r_plIx] },
{ "PointDate", r.MetaData[r_pdIx] }
{ PointDate, r.MetaData[r_pdIx] },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
resultsCube.AddRow(row, explained);

Expand Down Expand Up @@ -72,7 +74,8 @@ public class AtmVegaCurveStep : IPnLAttributionStep
{ SubStep, surfaceName },
{ SubSubStep, "Unexplained" },
{ PointLabel, "Unexplained" },
{ "PointDate", endModel.VanillaModel.BuildDate }
{ PointDate, endModel.VanillaModel.BuildDate },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
explainedByTrade.TryGetValue((string)r.MetaData[r_tidIx], out var explained);
resultsCube.AddRow(row, r.Value - explained);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public class DeltaFlatSpreadGammaCurveStep(bool ignoreGamma = false) : IPnLAttri
var r_tidIx = riskCube.GetColumnIndex(TradeId);
var r_plIx = riskCube.GetColumnIndex(PointLabel);
var r_tTypeIx = riskCube.GetColumnIndex(TradeType);
var r_pdIx = riskCube.GetColumnIndex("PointDate");
var r_pdIx = riskCube.GetColumnIndex(PointDate);
var r_UlIx = riskCube.GetColumnIndex(Underlying);

var startCurve = model.VanillaModel.GetPriceCurve(curveName);
var endCurve = endModel.VanillaModel.GetPriceCurve(curveName);
Expand Down Expand Up @@ -51,7 +52,8 @@ public class DeltaFlatSpreadGammaCurveStep(bool ignoreGamma = false) : IPnLAttri
{ SubStep, curveName },
{ SubSubStep, "DeltaFlat" },
{ PointLabel, r.MetaData[r_plIx] },
{ "PointDate", r.MetaData[r_pdIx] }
{ PointDate, r.MetaData[r_pdIx] },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
var rowSpread = new Dictionary<string, object>
{
Expand All @@ -61,7 +63,8 @@ public class DeltaFlatSpreadGammaCurveStep(bool ignoreGamma = false) : IPnLAttri
{ SubStep, curveName },
{ SubSubStep, "DeltaSpread" },
{ PointLabel, r.MetaData[r_plIx] },
{ "PointDate", r.MetaData[r_pdIx] }
{ PointDate, r.MetaData[r_pdIx] },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};

resultsCube.AddRow(rowFlat, explainedFlat);
Expand Down Expand Up @@ -100,7 +103,8 @@ public class DeltaFlatSpreadGammaCurveStep(bool ignoreGamma = false) : IPnLAttri
{ SubStep, curveName },
{ SubSubStep, "GammaFlat" },
{ PointLabel, "Flat" },
{ "PointDate", endModel.VanillaModel.BuildDate }
{ PointDate, endModel.VanillaModel.BuildDate },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
resultsCube.AddRow(row, explained);

Expand Down Expand Up @@ -128,7 +132,8 @@ public class DeltaFlatSpreadGammaCurveStep(bool ignoreGamma = false) : IPnLAttri
{ SubStep, curveName },
{ SubSubStep, "Unexplained" },
{ PointLabel, "Unexplained" },
{ "PointDate", endModel.VanillaModel.BuildDate }
{ PointDate, endModel.VanillaModel.BuildDate },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
explainedByTrade.TryGetValue((string)r.MetaData[r_tidIx], out var explained);
resultsCube.AddRow(row, r.Value - explained);
Expand Down
12 changes: 8 additions & 4 deletions src/Qwack.Models/Models/AttributionSteps/DeltaGammaCurveStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public class DeltaGammaCurveStep : IPnLAttributionStep
var r_tidIx = riskCube.GetColumnIndex(TradeId);
var r_plIx = riskCube.GetColumnIndex(PointLabel);
var r_tTypeIx = riskCube.GetColumnIndex(TradeType);
var r_pdIx = riskCube.GetColumnIndex("PointDate");
var r_pdIx = riskCube.GetColumnIndex(PointDate);
var r_UlIx = riskCube.GetColumnIndex(Underlying);

var startCurve = model.VanillaModel.GetPriceCurve(curveName);
var endCurve = endModel.VanillaModel.GetPriceCurve(curveName);
Expand All @@ -47,7 +48,8 @@ public class DeltaGammaCurveStep : IPnLAttributionStep
{ SubStep, curveName },
{ SubSubStep, "Delta" },
{ PointLabel, r.MetaData[r_plIx] },
{ "PointDate", r.MetaData[r_pdIx] }
{ PointDate, r.MetaData[r_pdIx] },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
resultsCube.AddRow(row, explained);

Expand Down Expand Up @@ -76,7 +78,8 @@ public class DeltaGammaCurveStep : IPnLAttributionStep
{ SubStep, curveName },
{ SubSubStep, "Gamma" },
{ PointLabel, r.MetaData[r_plIx] },
{ "PointDate", r.MetaData[r_pdIx] }
{ PointDate, r.MetaData[r_pdIx] },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
resultsCube.AddRow(row, explained);

Expand All @@ -103,7 +106,8 @@ public class DeltaGammaCurveStep : IPnLAttributionStep
{ SubStep, curveName },
{ SubSubStep, "Unexplained" },
{ PointLabel, "Unexplained" },
{ "PointDate", endModel.VanillaModel.BuildDate }
{ PointDate, endModel.VanillaModel.BuildDate },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
explainedByTrade.TryGetValue((string)r.MetaData[r_tidIx], out var explained);
resultsCube.AddRow(row, r.Value - explained);
Expand Down
4 changes: 3 additions & 1 deletion src/Qwack.Models/Models/AttributionSteps/FinalStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class FinalStep() : IPnLAttributionStep
{
var newPvCube = endModel.PV(reportingCcy);
var step = newPvCube.QuickDifference(lastPvCube);
var r_UlIx = riskCube.GetColumnIndex(Underlying);

foreach (var r in step.GetAllRows())
{
Expand All @@ -29,7 +30,8 @@ public class FinalStep() : IPnLAttributionStep
{ SubStep, "Unexplained" },
{ SubSubStep, "Unexplained" },
{ PointLabel, string.Empty },
{ "PointDate", endModel.VanillaModel.BuildDate }
{ PointDate, endModel.VanillaModel.BuildDate },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
resultsCube.AddRow(row, r.Value);
}
Expand Down
12 changes: 8 additions & 4 deletions src/Qwack.Models/Models/AttributionSteps/FxSpotsStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ public class FxSpotsStep : IPnLAttributionStep
var r_tidIx = riskCube.GetColumnIndex(TradeId);
var r_plIx = riskCube.GetColumnIndex(PointLabel);
var r_tTypeIx = riskCube.GetColumnIndex(TradeType);
var r_pdIx = riskCube.GetColumnIndex("PointDate");
var r_pdIx = riskCube.GetColumnIndex(PointDate);
var r_UlIx = riskCube.GetColumnIndex(Underlying);

foreach (var fxSpot in endModel.VanillaModel.FundingModel.FxMatrix.SpotRates)
{
Expand Down Expand Up @@ -43,7 +44,8 @@ public class FxSpotsStep : IPnLAttributionStep
{ SubStep, fxPair },
{ SubSubStep, "Delta" },
{ PointLabel, string.Empty },
{ "PointDate", endModel.VanillaModel.BuildDate }
{ PointDate, endModel.VanillaModel.BuildDate },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
resultsCube.AddRow(row, explained);

Expand Down Expand Up @@ -74,7 +76,8 @@ public class FxSpotsStep : IPnLAttributionStep
{ SubStep, fxPair },
{ SubSubStep, "Gamma" },
{ PointLabel, string.Empty },
{ "PointDate", endModel.VanillaModel.BuildDate }
{ PointDate, endModel.VanillaModel.BuildDate },
{ Underlying, r_UlIx < 0 ? string.Empty : r.MetaData[r_UlIx] }
};
resultsCube.AddRow(row, explained);

Expand All @@ -101,7 +104,8 @@ public class FxSpotsStep : IPnLAttributionStep
{ SubStep, fxPair },
{ SubSubStep, "Unexplained" },
{ PointLabel, "Unexplained" },
{ "PointDate", endModel.VanillaModel.BuildDate }
{ PointDate, endModel.VanillaModel.BuildDate },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
explainedByTrade.TryGetValue((string)r.MetaData[r_tidIx], out var explained);
resultsCube.AddRow(row, r.Value - explained);
Expand Down
9 changes: 6 additions & 3 deletions src/Qwack.Models/Models/AttributionSteps/FxVolsStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ public class FxVolsStep : IPnLAttributionStep
var r_tidIx = riskCube.GetColumnIndex(TradeId);
var r_plIx = riskCube.GetColumnIndex(PointLabel);
var r_tTypeIx = riskCube.GetColumnIndex(TradeType);
var r_pdIx = riskCube.GetColumnIndex("PointDate");
var r_pdIx = riskCube.GetColumnIndex(PointDate);
var r_UlIx = riskCube.GetColumnIndex(Underlying);

foreach (var fxSurface in endModel.VanillaModel.FundingModel.VolSurfaces)
{
Expand Down Expand Up @@ -43,7 +44,8 @@ public class FxVolsStep : IPnLAttributionStep
{ SubStep, fxSurface.Key },
{ SubSubStep, "Vega" },
{ PointLabel,r.MetaData[r_plIx]},
{ "PointDate",r.MetaData[r_pdIx] }
{ PointDate,r.MetaData[r_pdIx] },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
riskCube.AddRow(row, explained);

Expand All @@ -70,7 +72,8 @@ public class FxVolsStep : IPnLAttributionStep
{ SubStep, fxSurface.Key },
{ SubSubStep, "Unexplained" },
{ PointLabel, "Unexplained" },
{ "PointDate", endModel.VanillaModel.BuildDate }
{ PointDate, endModel.VanillaModel.BuildDate },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
explainedByTrade.TryGetValue((string)r.MetaData[r_tidIx], out var explained);
resultsCube.AddRow(row, r.Value - explained);
Expand Down
12 changes: 8 additions & 4 deletions src/Qwack.Models/Models/AttributionSteps/IrCurveStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ public class IrCurveStep : IPnLAttributionStep
var r_tidIx = riskCube.GetColumnIndex(TradeId);
var r_plIx = riskCube.GetColumnIndex(PointLabel);
var r_tTypeIx = riskCube.GetColumnIndex(TradeType);
var r_pdIx = riskCube.GetColumnIndex("PointDate");
var r_pdIx = riskCube.GetColumnIndex(PointDate);
var r_UlIx = riskCube.GetColumnIndex(Underlying);

foreach (var irCurve in endModel.VanillaModel.FundingModel.Curves)
{
Expand All @@ -42,7 +43,8 @@ public class IrCurveStep : IPnLAttributionStep
{ SubStep, irCurve.Key },
{ SubSubStep, string.Empty },
{ PointLabel,r.MetaData[r_plIx]},
{ "PointDate", point }
{ PointDate, point },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
resultsCube.AddRow(row, explained);

Expand Down Expand Up @@ -74,7 +76,8 @@ public class IrCurveStep : IPnLAttributionStep
{ SubStep, irCurve.Key },
{ SubSubStep, "Unexplained"},
{ PointLabel, "Unexplained" },
{ "PointDate", endModel.VanillaModel.BuildDate }
{ PointDate, endModel.VanillaModel.BuildDate },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
resultsCube.AddRow(row, r.Value - explained);
}
Expand All @@ -90,7 +93,8 @@ public class IrCurveStep : IPnLAttributionStep
{ SubStep, irCurve.Key },
{ SubSubStep, "Unexplained"},
{ PointLabel, "Unexplained" },
{ "PointDate", endModel.VanillaModel.BuildDate }
{ PointDate, endModel.VanillaModel.BuildDate },
{ Underlying, string.Empty }
};
resultsCube.AddRow(row, -kv.Value);
}
Expand Down
12 changes: 8 additions & 4 deletions src/Qwack.Models/Models/AttributionSteps/TimeRollStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public class TimeRollStep(ICurrencyProvider currencyProvider, IFutureSettingsPro
var r_tidIx = riskCube.GetColumnIndex(TradeId);
var r_plIx = riskCube.GetColumnIndex(PointLabel);
var r_tTypeIx = riskCube.GetColumnIndex(TradeType);
var r_pdIx = riskCube.GetColumnIndex("PointDate");
var r_UlIx = riskCube.GetColumnIndex(Underlying);
var r_pdIx = riskCube.GetColumnIndex(PointDate);

var cashCube = model.Portfolio.FlowsT0(model.VanillaModel, reportingCcy);
var cashRows = cashCube.GetAllRows();
Expand All @@ -41,7 +42,8 @@ public class TimeRollStep(ICurrencyProvider currencyProvider, IFutureSettingsPro
{ SubStep, "TimeRoll" },
{ SubSubStep, string.Empty },
{ PointLabel, string.Empty },
{ "PointDate", endModel.VanillaModel.BuildDate }
{ PointDate, endModel.VanillaModel.BuildDate },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
resultsCube.AddRow(row, r.Value);
}
Expand All @@ -60,7 +62,8 @@ public class TimeRollStep(ICurrencyProvider currencyProvider, IFutureSettingsPro
{ SubStep, "CashMove" },
{ SubSubStep, string.Empty },
{ PointLabel, string.Empty },
{ "PointDate", endModel.VanillaModel.BuildDate }
{ PointDate, endModel.VanillaModel.BuildDate },
{ Underlying, r_UlIx<0 ? string.Empty : cashRows[i].MetaData[r_UlIx] }
};
resultsCube.AddRow(row, cash);
}
Expand Down Expand Up @@ -90,7 +93,8 @@ public class TimeRollStep(ICurrencyProvider currencyProvider, IFutureSettingsPro
{ SubStep, fixingDictName ?? "Unknown" },
{ SubSubStep, string.Empty },
{ PointLabel, string.Empty },
{ "PointDate", endModel.VanillaModel.BuildDate }
{ PointDate, endModel.VanillaModel.BuildDate },
{ Underlying, r_UlIx<0 ? string.Empty : r.MetaData[r_UlIx] }
};
resultsCube.AddRow(row, r.Value);
}
Expand Down
3 changes: 2 additions & 1 deletion src/Qwack.Models/Models/PnLAttribution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1506,12 +1506,13 @@ public static ICube ExplainAttribution(this Portfolio startPortfolio, Portfolio
var dataTypes = new Dictionary<string, Type>
{
{ TradeId, typeof(string) },
{ Underlying, typeof(string) },
{ TradeType, typeof(string) },
{ Step, typeof(string) },
{ SubStep, typeof(string) },
{ SubSubStep, typeof(string) },
{ PointLabel, typeof(string) },
{ "PointDate", typeof(DateTime) },
{ PointDate, typeof(DateTime) },
};

cube.Initialize(dataTypes);
Expand Down
Loading

0 comments on commit 080f903

Please sign in to comment.