Third-party analytics software usually requires specific set of market data for performing its calculations. In this post, I am publishing one of my utility Python programs for creating different types of stress scenario markets, based on given base market and set of prepared XML configurations. The complete program can be found in my
GitHub repository.
Configurations
The following screenshot shows configurations for this program.
SourceFilePath attribute captures the source market data CSV file and
TargetFolderPath captures the folder, into which all market scenario files will be created. Finally,
ScenarioConfigurationsPath captures the folder, which contains all XML scenario configuration files.
This configuration XML file should be stored in a chosen directory.
<Configurations>
<!-- attributes for scenario generator settings -->
<ScenarioConfigurationsPath>\\Temp\ScenarioConfigurations\</ScenarioConfigurationsPath>
<SourceFilePath>\\Temp\baseMarket.csv</SourceFilePath>
<TargetFolderPath>\\Temp\Scenarios\</TargetFolderPath>
</Configurations>
Market data
The following screenshot shows given base market data. Due to brevity reasons,
only EUR swap curve has been used here as an example. All market data points are defined here as key-value pairs (ticker,
value).
IR.EUR-EURIBOR.CASH-1BD.MID,-0.00365
IR.EUR-EURIBOR.CASH-1W.MID,-0.00373
IR.EUR-EURIBOR.CASH-1M.MID,-0.00363
IR.EUR-EURIBOR.CASH-2M.MID,-0.00336
IR.EUR-EURIBOR.CASH-3M.MID,-0.00309
IR.EUR-EURIBOR.CASH-6M.MID,-0.00237
IR.EUR-EURIBOR-6M.FRA-1M-7M.MID,-0.00231
IR.EUR-EURIBOR-6M.FRA-2M-8M.MID,-0.00227
IR.EUR-EURIBOR-6M.FRA-3M-9M.MID,-0.002255
IR.EUR-EURIBOR-6M.FRA-4M-10M.MID,-0.00218
IR.EUR-EURIBOR-6M.FRA-5M-11M.MID,-0.00214
IR.EUR-EURIBOR-6M.FRA-6M-12M.MID,-0.002075
IR.EUR-EURIBOR-6M.FRA-7M-13M.MID,-0.00198
IR.EUR-EURIBOR-6M.FRA-8M-14M.MID,-0.00186
IR.EUR-EURIBOR-6M.FRA-9M-15M.MID,-0.001775
IR.EUR-EURIBOR-6M.FRA-10M-16M.MID,-0.00169
IR.EUR-EURIBOR-6M.FRA-11M-17M.MID,-0.00159
IR.EUR-EURIBOR-6M.FRA-12M-18M.MID,-0.00141
IR.EUR-EURIBOR-6M.SWAP-2Y.MID,-0.001603
IR.EUR-EURIBOR-6M.SWAP-3Y.MID,-0.000505
IR.EUR-EURIBOR-6M.SWAP-4Y.MID,0.00067
IR.EUR-EURIBOR-6M.SWAP-5Y.MID,0.00199
IR.EUR-EURIBOR-6M.SWAP-6Y.MID,0.003315
IR.EUR-EURIBOR-6M.SWAP-7Y.MID,0.0046
IR.EUR-EURIBOR-6M.SWAP-8Y.MID,0.00584
IR.EUR-EURIBOR-6M.SWAP-9Y.MID,0.00698
IR.EUR-EURIBOR-6M.SWAP-10Y.MID,0.00798
IR.EUR-EURIBOR-6M.SWAP-11Y.MID,0.00895
IR.EUR-EURIBOR-6M.SWAP-12Y.MID,0.009775
IR.EUR-EURIBOR-6M.SWAP-15Y.MID,0.01165
IR.EUR-EURIBOR-6M.SWAP-20Y.MID,0.013245
IR.EUR-EURIBOR-6M.SWAP-25Y.MID,0.013725
IR.EUR-EURIBOR-6M.SWAP-30Y.MID,0.01378
We can clearly see, that the system used for constructing market data tickers leads to scheme, in which every market data point will have
one and only one unique ticker. This will then guarantee, that we can
drill down and stress individual market data points with
regex expressions, if so desired. This data should be copied into CSV file (directory has been defined in previous configuration file).
Scenario configurations
The following
screenshot shows XML configurations for one market scenario. One such
scenario can have several different scenario items (Say, stress these
rates up, stress those rates down, apply these changes to all FX rates
against EUR and set hard-coded values for all CDS curves). From these
configurations, ID and description are self-explainable. Attribute
regExpression
captures all regex expressions (scenario items), which will be searched
from risk factor tickers. As soon as regex match is found, the program
will use corresponding
operationType attribute to
identify desired stress operation (addition, multiplication or
hard-coded value). Finally, the amount of change which will be applied
in risk factor value is defined within
stressValue attribute. This XML configuration should be stored (directory has been defined in program configuration file).
<!-- operation types : 0 = ADDITION, 1 = MULTIPLICATION, 2 = HARD-CODED VALUE -->
<Scenario>
<ID>CURVE.STRESS</ID>
<description>custom stress scenario for EUR swap curve</description>
<regExpression>^IR.EUR-EURIBOR.CASH,^IR.EUR-EURIBOR-6M.FRA,^IR.EUR-EURIBOR-6M.SWAP</regExpression>
<operationType>1,0,2</operationType>
<stressValue>1.25,0.015,0.05</stressValue>
</Scenario>
Finally, the following screenshot shows resulting market data, when all configured scenario items have been applied.
This is the content of output CSV file, created by this Python program.
IR.EUR-EURIBOR.CASH-1BD.MID,-0.0045625
IR.EUR-EURIBOR.CASH-1W.MID,-0.0046625
IR.EUR-EURIBOR.CASH-1M.MID,-0.0045375
IR.EUR-EURIBOR.CASH-2M.MID,-0.004200000000000001
IR.EUR-EURIBOR.CASH-3M.MID,-0.0038624999999999996
IR.EUR-EURIBOR.CASH-6M.MID,-0.0029625000000000003
IR.EUR-EURIBOR-6M.FRA-1M-7M.MID,0.01269
IR.EUR-EURIBOR-6M.FRA-2M-8M.MID,0.01273
IR.EUR-EURIBOR-6M.FRA-3M-9M.MID,0.012745
IR.EUR-EURIBOR-6M.FRA-4M-10M.MID,0.01282
IR.EUR-EURIBOR-6M.FRA-5M-11M.MID,0.01286
IR.EUR-EURIBOR-6M.FRA-6M-12M.MID,0.012924999999999999
IR.EUR-EURIBOR-6M.FRA-7M-13M.MID,0.01302
IR.EUR-EURIBOR-6M.FRA-8M-14M.MID,0.013139999999999999
IR.EUR-EURIBOR-6M.FRA-9M-15M.MID,0.013224999999999999
IR.EUR-EURIBOR-6M.FRA-10M-16M.MID,0.013309999999999999
IR.EUR-EURIBOR-6M.FRA-11M-17M.MID,0.01341
IR.EUR-EURIBOR-6M.FRA-12M-18M.MID,0.01359
IR.EUR-EURIBOR-6M.SWAP-2Y.MID,0.05
IR.EUR-EURIBOR-6M.SWAP-3Y.MID,0.05
IR.EUR-EURIBOR-6M.SWAP-4Y.MID,0.05
IR.EUR-EURIBOR-6M.SWAP-5Y.MID,0.05
IR.EUR-EURIBOR-6M.SWAP-6Y.MID,0.05
IR.EUR-EURIBOR-6M.SWAP-7Y.MID,0.05
IR.EUR-EURIBOR-6M.SWAP-8Y.MID,0.05
IR.EUR-EURIBOR-6M.SWAP-9Y.MID,0.05
IR.EUR-EURIBOR-6M.SWAP-10Y.MID,0.05
IR.EUR-EURIBOR-6M.SWAP-11Y.MID,0.05
IR.EUR-EURIBOR-6M.SWAP-12Y.MID,0.05
IR.EUR-EURIBOR-6M.SWAP-15Y.MID,0.05
IR.EUR-EURIBOR-6M.SWAP-20Y.MID,0.05
IR.EUR-EURIBOR-6M.SWAP-25Y.MID,0.05
IR.EUR-EURIBOR-6M.SWAP-30Y.MID,0.05
Handy way to create and test regex expressions is to use any online
tool available. As an example, the first scenario item (
^IR.EUR-EURIBOR.CASH) has been applied to a given base market data. The last screenshot below shows all regex matches.
Have a great start for the year 2019 and thanks a lot again for reading my blog.
-Mike