Skip to content

Commit

Permalink
Risk matrix FX delta fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
gavbrennan committed Nov 21, 2022
1 parent 3446d16 commit deed698
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/Qwack.Models/Models/FundingModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,8 @@ public static IFundingModel RemapBaseCurrency(IFundingModel input, Currency newB
var homeToBase = mf.FxMatrix.SpotRates[newBaseCurrency];
var ccys = mf.FxMatrix.SpotRates.Keys.ToList()
.Concat(new[] { mf.FxMatrix.BaseCurrency })
.Where(x => x != newBaseCurrency);
.Where(x => x != newBaseCurrency)
.Distinct();
var newRateDict = new Dictionary<Currency, double>();
foreach (var ccy in ccys)
{
Expand Down
31 changes: 29 additions & 2 deletions src/Qwack.Models/Risk/RiskLadder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,24 @@
using Qwack.Core.Cubes;
using Qwack.Core.Instruments;
using Qwack.Core.Models;
using Qwack.Dates;
using Qwack.Models.Risk.Mutators;
using Qwack.Utils.Parallel;

namespace Qwack.Models.Risk
{
public class RiskLadder
{
public ICurrencyProvider CurrencyProvider { get; set; }

public string AssetId { get; private set; }
public MutationType ShiftType { get; private set; }
public RiskMetric Metric { get; private set; }
public double ShiftSize { get; private set; }
public int NScenarios { get; private set; }
public bool ReturnDifferential { get; private set; }
public Currency Ccy { get; private set; }
public FxPair FxPair { get; private set; }

public RiskLadder(string assetId, MutationType shiftType, RiskMetric metric, double shiftStepSize, int nScenarios, bool returnDifferential = true)
{
Expand All @@ -40,6 +44,16 @@ public RiskLadder(Currency ccy, MutationType shiftType, RiskMetric metric, doubl
ReturnDifferential = returnDifferential;
}

public RiskLadder(FxPair pair, MutationType shiftType, RiskMetric metric, double shiftStepSize, int nScenarios, bool returnDifferential = true)
{
FxPair = pair;
ShiftType = shiftType;
Metric = metric;
ShiftSize = shiftStepSize;
NScenarios = nScenarios;
ReturnDifferential = returnDifferential;
}

public Dictionary<string, IPvModel> GenerateScenarios(IPvModel model)
{
var o = new Dictionary<string, IPvModel>();
Expand All @@ -48,12 +62,12 @@ public Dictionary<string, IPvModel> GenerateScenarios(IPvModel model)
ParallelUtils.Instance.For(-NScenarios, NScenarios + 1, 1, (i) =>
{
var thisShift = i * ShiftSize;
var thisLabel = (string.IsNullOrWhiteSpace(AssetId) ? Ccy.Ccy : AssetId) + "~" + thisShift;
var thisLabel = (string.IsNullOrWhiteSpace(AssetId) ? (FxPair?.ToString() ?? Ccy.Ccy ) : AssetId) + "~" + thisShift;
if (thisShift == 0)
results[i + NScenarios] = new KeyValuePair<string, IPvModel>(thisLabel, model);
else
{
if (string.IsNullOrWhiteSpace(AssetId))
if (string.IsNullOrWhiteSpace(AssetId) && FxPair==null)
{
var shifted = ShiftType switch
{
Expand All @@ -62,6 +76,15 @@ public Dictionary<string, IPvModel> GenerateScenarios(IPvModel model)
};
results[i + NScenarios] = new KeyValuePair<string, IPvModel>(thisLabel, shifted);
}
else if (FxPair != null)
{
var shifted = ShiftType switch
{
MutationType.FlatShift => FlatShiftMutator.FxSpotShift(FxPair, thisShift, model),
_ => throw new Exception($"Unable to process shift type {ShiftType}"),
};
results[i + NScenarios] = new KeyValuePair<string, IPvModel>(thisLabel, shifted);
}
else
{
var shifted = ShiftType switch
Expand Down Expand Up @@ -136,7 +159,11 @@ public ICube Generate(IPvModel model, Portfolio portfolio = null)
RiskMetric.AssetVega => model.AssetVega(model.VanillaModel.FundingModel.FxMatrix.BaseCurrency),
RiskMetric.PV => model.PV(model.VanillaModel.FundingModel.FxMatrix.BaseCurrency),
RiskMetric.PV01 => model.AssetIrDelta(model.VanillaModel.FundingModel.FxMatrix.BaseCurrency),
RiskMetric.FxDelta => model.FxDelta(FxPair?.Foreign ?? Ccy ?? model.VanillaModel.FundingModel.FxMatrix.BaseCurrency, CurrencyProvider, false, ShouldInvert(FxPair?.Foreign ?? Ccy ?? model.VanillaModel.FundingModel.FxMatrix.BaseCurrency)),
_ => throw new Exception($"Unable to process risk metric {Metric}"),
};

static string[] _inverseCcys = new[] { "EUR", "GBP", "AUD", "NZD" };
private static bool ShouldInvert(string ccy) => !_inverseCcys.Contains(ccy);
}
}
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.9</VersionPrefix>
<VersionPrefix>0.7.10</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.9
0.7.10

0 comments on commit deed698

Please sign in to comment.