Author: Guy Shepherd
Since my series of articles last year on running Mo.net projections from within a Python script, I’ve had a couple of requests from clients who are keen to change the assumptions tables used by the projection at runtime. This short article explains how to do this, building upon the original scripts from last year.
While the original scripts demonstrated how to override a single parameter at runtime, the process of changing an assumption table is a little more involved.
Before attempting to do this, it’s also worth noting that changing an assumption table at runtime could easily cause the projection to fail or produce unusual results. It’s essential that the format and structure of the replacement assumption table mirrors the original table.
Python Script
import sys import clr # define path to the Mo.net Linked DLL and add this to system path # make sure the Mo.net DLL has been compiled in MDS 7.6 or later or it will not work assembly_path = r"C:\Mo.net Projects\LinkedFundsForPython770\Linked_DLL" sys.path.append(assembly_path) # add Mo.net kernel assembly references to the CLR clr.AddReference("Sal.CalculationEngine.GenCore") clr.AddReference("Sal.CalculationEngine.GenDataAccess") clr.AddReference("Sal.CalculationEngine.GenLookUp") clr.AddReference("Sal.CalculationEngine.Interfaces.Entities") clr.AddReference("Sal.CalculationEngine.ExcelReporting.TabularValues") from GenDataAccess import DataRequest # add Mo.net projection DLL reference to the CLR clr_ref = clr.AddReference("Linked_Monet") monet_type = clr_ref.GetType('Monet') # invoke Mo.net interface methods initCmdLine_method = monet_type.GetMethod('InitCommandLine') initCmdLine_method.Invoke(None, [None]) init_method = monet_type.GetMethod('Initialise') init_method.Invoke(None, [True]) initProj_method = monet_type.GetMethod('InitialiseProjections') initProj_method.Invoke(None, []) # obtain a reference to the projection inside the DLL projections = monet_type.GetProperty('Projections') # override the default value for the SterlInt projection parameter linkedproj = projections.GetValue(None).Linked linkedproj.SterlInt = 0.1 # input array is really a two dimensional list (or a list of lists) inputarray = [['PolNo', 'Sex1', 'AgeEnt1', 'PremFreq', 'FundType', 'SumAssured', 'PeriodIF', 'Term', 'PremInit'], ['1', '1', '54', '4', 'Equity', '100,000', '0', '20', '0']] # Passing in the list requires the new constructor available in MDS 7.6.0 and later linkedproj.InputsTable = DataRequest(inputarray) # Use alternative assumption table newtablepath = r"C:\Mo.net Projects\LinkedFundsForPython770\Tables\ValBasisAmended.txt" # Need to access the existing instance of ValBasis, which is a ProjectObject project_obj_instance = clr_ref.GetType('ProjectObjects') valbasis_prop = project_obj_instance.GetProperty('ValBasis') valbasis_instance = valbasis_prop.GetValue(project_obj_instance, None) # Now override using the new table location - override if not required valbasis_instance.RefreshData(DataRequest(newtablepath)) # run the projection linkedproj.Run() # show the inputs - to check they have been overridden print(f'PolNo = {linkedproj.Record.PolNo}') print(f'Sex1 = {linkedproj.Record.Sex1}') print(f'AgeEnt1 = {linkedproj.Record.AgeEnt1}') # show a value from the valbasis table print(f'ValBasis("Equity","RenExpEsc") = {valbasis_instance.get_Value("Equity","RenExpEsc")}') # show the sterling result at time=0 print(f'SterlInt = {linkedproj.SterlInt}') print(f'SterlRes(0) = {linkedproj.SterlRes(0)}')
What’s Going On?
The main script amendments are as follows:
Line Number | Commentary |
---|---|
15 | Add an additional reference – this time to GenLookUp, which contains various table functions, including those required to access an assumption table and change the source of the table |
56 | Define the location of the replacement assumptions table |
60-62 | Retrieve the .NET Type object that represents the class named ProjectObjects, access the ValBasis property of the ProjectObjects type using reflection, and finally get the value of the ValBasis property from the object project_obj_instance |
66 | Call the RefreshData method of the ValBasis table passing in the new table file / location defined above |
80 | Show a specific value from the ValBasis table that is known to have changed between versions – just to reassure the user that the code is using the new assumptions table |
Conclusion
I hope this is a useful enhancement to the original scripts. In the near future I will explore some of the ways that Mo.net projections can be run from custom .NET solutions.
Comments are closed.