SET DEFAULT TO JUSTPATH(SYS(16)) *SET COVERAGE TO speed.txt LOCAL loTest as actFactors loTest = CREATEOBJECT("actFactors" ) time1 = SECONDS() cFile = "C:\Actuariaat\Input\gbmgbv.dbf" FOR m.klm = 1 TO 10000 loTest.actAx1n("gbm6165",4,20,10) loTest.actnEx("gbm6165",4,20,10) loTest.actAxn("gbm6165",4,20,10) ENDFOR ? SECONDS() - time1 DEFINE CLASS ActSymbols as session m.cFieldStructure = [Age I, Lx N(10,4),Qx N(10,8),Dx N(10,4),Nx N(10,4),Sx N(10,4), Cx N(10,4),Mxstreep N(10,4),] + ; [Rxstreep N(10,4)] m.cFile = "C:\Actuariaat\Input\gbmgbv.dbf" m.nMaxTables = 255 m.nMaxAge = 125 FUNCTION Rounding LPARAMETERS tnX, m.tcWay DO CASE CASE EMPTY(m.tcWay) RETURN m.tnX CASE LOWER(ALLTRIM(m.tcWay)) = "lower" RETURN FLOOR(m.tnX) CASE LOWER(ALLTRIM(m.tcWay)) = "upper" RETURN CEILING(m.tnX) OTHERWISE RETURN m.tnX ENDCASE ENDFUNC FUNCTION CheckCursor LPARAMETERS m.cName IF USED(m.cName) RETURN .T. ELSE RETURN .F. ENDIF ENDFUNC FUNCTION ReadLxTables LPARAMETERS m.cFile IF !USED("Gbmgbv") THEN USE (m.cFile) IN 0 SELECT "gbmgbv" ELSE SELECT "gbmgbv" ENDIF ENDFUNC **** Create Mortality table given the name of Mortality table and intrestrate PROCEDURE CreateCommutationTable LPARAMETERS m.cMortTable,m.nIntrestRate LOCAL m.cTableName, m.cIntrest m.cFieldStructure = [Age I, Lx N(10,4),Qx N(10,8),Dx N(10,4),Nx N(10,4),Sx N(10,4), Cx N(10,4),Mxstreep N(10,4),] + ; [Rxstreep N(10,4)] IF EMPTY(m.cMortTable) m.cMortTable = "" ENDIF IF EMPTY(m.nIntrestRate) m.cIntrest= "" ELSE m.cIntrest = ALLTRIM(STR(m.nIntrestRate)) ENDIF m.cTableName = ALLTRIM(m.cMortTable) + ALLTRIM(m.cIntrest) *** Read Table only if it is not used this.ReadLxTables(this.cFile) *** Create commutation table only and only if it doesn't exist IF this.CheckCursor(m.cTableName)= .T. SELECT (m.cTableName) ELSE CREATE CURSOR (m.cTableName)(&cFieldstructure) ENDIF ENDPROC **** Fill table with commutation functions given the name of Mortality table and intrestrate PROCEDURE FillCommTable LPARAMETERS m.cMortTable, m.nIntrest LOCAL m.cTableName,m.cLookUp,m.nLx,m.nLx1,m.Nx, mxstreep,m.Sx,m.Rxstreep,m.i,m.k m.cTableName = IIF(EMPTY(m.cMortTable),"",ALLTRIM(m.cMortTable)) + ; IIF(EMPTY(m.nIntrest),"",ALLTRIM(STR(m.nIntrest))) cLookup = [gbmgbv.] +; IIF(EMPTY(m.cMortTable),"",ALLTRIM(m.cMortTable)) IF this.CheckCursor(m.cTableName) = .F. this.CreateCommutationTable(m.cTableName) *** Fill Lx: FOR m.i = 0 TO this.nMaxAge APPEND BLANK replace age WITH m.i replace lx WITH LOOKUP(&cLookup,age,gbmgbv.leeftijd) ENDFOR *** Fill Cx,Dx,Lx,Qx FOR m.i =0 TO this.nMaxage GOTO i+1 IF lx = 0 REPLACE qx WITH 1 REPLACE dx WITH 0 replace cx WITH 0 ELSE m.Lx = lx GOTO m.i + 2 m.Lx1 = lx GOTO m.i + 1 REPLACE qx WITH (m.Lx - m.Lx1)/m.Lx REPLACE dx WITH (1/(1+m.nIntrest/100))^i*m.Lx/100 REPLACE cx WITH (1/(1+m.nIntrest/100))^(i+1)*(m.Lx-m.Lx1)/100 ENDIF ENDFOR *!* *** Fill Mxstreep , Nx FOR m.i =0 TO this.nMaxage mxstreep =0 m.nx = 0 FOR m.k = m.i TO this.nMaxage GOTO m.k + 1 m.nx = m.nx + dx mxstreep = mxstreep + cx*SQRT(1 + m.nIntrest/100) ENDFOR GOTO m.i + 1 REPLACE mxstreep WITH mxstreep,nx WITH m.nx ENDFOR *!* *** Fill Rxstreep , Sx FOR m.i =0 TO this.nMaxage m.rxstreep =0 m.sx = 0 FOR m.k = m.i TO this.nMaxage GOTO m.k + 1 m.sx = m.sx + nx m.rxstreep = m.rxstreep + mxstreep ENDFOR GOTO m.i + 1 REPLACE rxstreep WITH m.rxstreep,sx WITH m.sx ENDFOR ENDIF ENDPROC FUNCTION GetActSymbol LPARAMETERS m.tcSymbol,m.tcMortTable,m.tnintrest,m.tnAge LOCAL m.cField this.FillCommTable(m.tcMortTable,m.tnintrest) && create table and fill it with data GOTO MIN(this.nMaxAge + 1,m.tnAge + 1) RETURN &tcSymbol ENDFUNC ENDDEFINE DEFINE CLASS ActFactors as ActSymbols FUNCTION actLx LPARAMETERS m.tcMortTable,m.tnintrest,m.tnAge,m.tcWay LOCAL m.lnFactor,m.lnResult,m.lnResultUp,m.lnResultDown m.lnFactor = m.tnAge - FLOOR(m.tnAge) m.lnResultDown = this.GetActSymbol("lx",m.tcMortTable,m.tnintrest,FLOOR(m.tnAge)) m.lnResultUp = this.GetActSymbol("lx",m.tcMortTable,m.tnintrest, ceiling(m.tnAge)) m.lnResult = (1-m.lnFactor)*m.lnResultDown + m.lnFactor *m.lnResultUp IF EMPTY(m.tcWay) m.tcWay ="" ENDIF DO CASE CASE m.tcWay = "lower" m.lnResult = m.lnResultDown CASE m.tcWay = "upper" m.lnResult = m.lnResultUp OTHERWISE m.lnResult = m.lnResult ENDCASE RETURN m.lnResult ENDFUNC FUNCTION actQx LPARAMETERS m.tcMortTable,m.tnintrest,m.tnAge,m.tcWay LOCAL m.lnFactor,m.lnResult,m.lnResultUp,m.lnResultDown m.lnFactor = m.tnAge - FLOOR(m.tnAge) m.lnResultDown = this.GetActSymbol("qx",m.tcMortTable,m.tnintrest,FLOOR(m.tnAge)) m.lnResultUp = this.GetActSymbol("qx",m.tcMortTable,m.tnintrest,ceiling(m.tnAge)) m.lnResult = (1-m.lnFactor)*m.lnResultDown + m.lnFactor *m.lnResultUp IF EMPTY(m.tcWay) m.tcWay ="" ENDIF DO CASE CASE m.tcWay = "lower" m.lnResult = m.lnResultDown CASE m.tcWay = "upper" m.lnResult = m.lnResultUp OTHERWISE m.lnResult = m.lnResult ENDCASE RETURN m.lnResult ENDFUNC FUNCTION actMxstreep LPARAMETERS m.tcMortTable,m.tnintrest,m.tnAge,m.tcWay LOCAL m.lnFactor,m.lnResult,m.lnResultUp,m.lnResultDown m.lnFactor = m.tnAge - FLOOR(m.tnAge) m.lnResultDown = this.GetActSymbol("mxstreep",m.tcMortTable,m.tnintrest,FLOOR(m.tnAge)) m.lnResultUp = this.GetActSymbol("mxstreep",m.tcMortTable,m.tnintrest,CEILING(m.tnAge)) m.lnResult = (1-m.lnFactor)*m.lnResultDown + m.lnFactor*m.lnResultUp IF EMPTY(m.tcWay) m.tcWay ="" ENDIF DO CASE CASE m.tcWay = "lower" m.lnResult = m.lnResultDown CASE m.tcWay = "upper" m.lnResult = m.lnResultUp OTHERWISE m.lnResult = m.lnResult ENDCASE RETURN m.lnResult ENDFUNC FUNCTION actNx LPARAMETERS tcMortTable,m.tnintrest,m.tnAge,m.tcWay LOCAL m.lnFactor,m.lnResult,m.lnResultUp,m.lnResultDown m.lnFactor = m.tnAge - FLOOR(m.tnAge) m.lnResultDown = this.GetActSymbol("nx",m.tcMortTable,m.tnintrest,FLOOR(m.tnAge)) m.lnResultUp = this.GetActSymbol("nx",m.tcMortTable,m.tnintrest,CEILING(m.tnAge)) m.lnResult = (1-m.lnFactor)*m.lnResultDown + m.lnFactor*m.lnResultUp IF EMPTY(m.tcWay) m.tcWay ="" ENDIF DO CASE CASE m.tcWay = "lower" m.lnResult = m.lnResultDown CASE m.tcWay = "upper" m.lnResult = m.lnResultUp OTHERWISE m.lnResult = m.lnResult ENDCASE RETURN m.lnResult ENDFUNC FUNCTION actDx LPARAMETERS tcMortTable,m.tnintrest,m.tnAge,m.tcWay LOCAL m.lnFactor,m.lnResult,m.lnResultUp,m.lnResultDown m.lnFactor = m.tnAge - FLOOR(m.tnAge) m.lnResultDown = this.GetActSymbol("dx",m.tcmorttable,m.tnintrest,FLOOR(m.tnAge)) m.lnResultUp = this.GetActSymbol("dx",m.tcmorttable,m.tnintrest,CEILING(m.tnAge)) m.lnResult = (1-m.lnFactor)*m.lnResultDown + m.lnFactor *m.lnResultUp IF EMPTY(m.tcWay) m.tcWay ="" ENDIF DO CASE CASE m.tcWay = "lower" m.lnResult = m.lnResultDown CASE m.tcWay = "upper" m.lnResult = m.lnResultUp OTHERWISE m.lnResult = m.lnResult ENDCASE RETURN m.lnResult ENDFUNC FUNCTION actRxstreep LPARAMETERS m.tcmorttable,m.tnintrest,m.tnAge,m.tcWay LOCAL m.lnFactor,m.lnResult,m.lnResultUp,m.lnResultDown m.lnFactor = m.tnAge - FLOOR(m.tnAge) m.lnResultDown = this.GetActSymbol("rxstreep",m.tcmorttable,m.tnintrest,FLOOR(m.tnAge)) m.lnResultUp = this.GetActSymbol("rxstreep",m.tcmorttable,m.tnintrest,CEILING(m.tnAge)) m.lnResult = (1-m.lnFactor)*m.lnResultDown + m.lnFactor *m.lnResultUp IF EMPTY(m.tcWay) m.tcWay ="" ENDIF DO CASE CASE m.tcWay = "lower" m.lnResult = m.lnResultDown CASE m.tcWay = "upper" m.lnResult = m.lnResultUp OTHERWISE m.lnResult = m.lnResult ENDCASE RETURN m.lnResult ENDFUNC FUNCTION actSx LPARAMETERS m.tcmorttable,m.tnintrest,m.tnAge,m.tcWay LOCAL m.lnFactor,m.lnResult,m.lnResultUp,m.lnResultDown m.lnFactor = m.tnAge - FLOOR(m.tnAge) m.lnResultDown = this.GetActSymbol("sx",m.tcmorttable,m.tnintrest,FLOOR(m.tnAge)) m.lnResultUp = this.GetActSymbol("sx",m.tcmorttable,m.tnintrest,CEILING(m.tnAge)) m.lnResult = (1-m.lnFactor)*m.lnResultDown + m.lnFactor *m.lnResultUp IF EMPTY(m.tcWay) m.tcWay ="" ENDIF DO CASE CASE m.tcWay = "lower" m.lnResult = m.lnResultDown CASE m.tcWay = "upper" m.lnResult = m.lnResultUp OTHERWISE m.lnResult = m.lnResult ENDCASE RETURN m.lnResult ENDFUNC FUNCTION actCx LPARAMETERS m.tcmorttable,m.tnintrest,m.tnAge,m.tcWay LOCAL m.lnFactor,m.lnResult,m.lnResultUp,m.lnResultDown m.lnFactor = m.tnAge - FLOOR(m.tnAge) m.lnResultDown = this.GetActSymbol("cx",m.tcmorttable,m.tnintrest,FLOOR(m.tnAge)) m.lnResultUp = this.GetActSymbol("cx",m.tcmorttable,m.tnintrest,CEILING(m.tnAge)) m.lnResult = (1-m.lnFactor)*m.lnResultDown + m.lnFactor *m.lnResultUp IF EMPTY(m.tcWay) m.tcWay ="" ENDIF DO CASE CASE m.tcWay = "lower" m.lnResult = m.lnResultDown CASE m.tcWay = "upper" m.lnResult = m.lnResultUp OTHERWISE m.lnResult = m.lnResult ENDCASE RETURN m.lnResult ENDFUNC FUNCTION actnEx LPARAMETERS m.tcmorttable, m.tnintrest,m.tnAge,m.tnDuration,m.tcWay LOCAL m.nAgeBegin, m.nAgeEnd, m.nDx,m.nDxn m.nAgeBegin = m.tnAge m.nAgeEnd = m.tnAge + m.tnDuration m.nDx = this.actDx(m.tcmorttable, m.tnintrest, m.nAgeBegin) m.nDxn = this.actDx(m.tcmorttable, m.tnintrest, m.nAgeEnd) IF m.nDx <= 0 RETURN 0 ELSE RETURN m.nDxn/m.nDx ENDIF ENDFUNC FUNCTION actAx1n LPARAMETERS m.tcmorttable, m.tnintrest,m.tnAge,m.tnDuration,m.tcWay LOCAL m.nAgeBegin, m.nAgeEnd, m.nMx,m.nMxn,m.nDx m.nAgeBegin = m.tnAge m.nAgeEnd = m.tnAge + m.tnDuration m.nMx = this.actMxstreep(m.tcmorttable, m.tnintrest, m.nAgeBegin) m.nMxn = this.actMxstreep(m.tcmorttable, m.tnintrest, m.nAgeEnd) m.nDx = this.actDx(m.tcmorttable, m.tnintrest, m.nAgeBegin) IF m.nDx <= 0 RETURN 0 ELSE RETURN (m.nMx - m.nMxn)/m.nDx ENDIF ENDFUNC FUNCTION actAxn LPARAMETERS m.tcmorttable, m.tnintrest,m.tnAge,m.tnDuration,m.tcWay LOCAL m.nAgeBegin, m.nAgeEnd, m.nMx,m.nMxn,m.nDx m.nAgeBegin = m.tnAge m.nAgeEnd = m.tnAge + m.tnDuration m.nMx = this.actMxstreep(m.tcmorttable, m.tnintrest, m.nAgeBegin) m.nMxn = this.actMxstreep(m.tcmorttable, m.tnintrest, m.nAgeEnd) m.nDx = this.actDx(m.tcmorttable, m.tnintrest, m.nAgeBegin) m.nDxn = this.actDx(m.tcmorttable, m.tnintrest, m.nAgeEnd) IF m.nDx <= 0 RETURN 0 ELSE RETURN (m.nMx - m.nMxn + m.nDxn)/m.nDx ENDIF ENDFUNC FUNCTION actIAx1n LPARAMETERS m.tcmorttable, m.tnintrest,m.tnAge,m.tnDuration,m.tcWay LOCAL m.nAgeBegin, m.nAgeEnd, m.nRx,m.nRxn,m.nDx,m.nMxn m.nAgeBegin = m.tnAge m.nAgeEnd = m.tnAge + m.tnDuration m.nRx = this.actRxstreep(m.tcmorttable, m.tnintrest, m.nAgeBegin) m.nRxn = this.actRxstreep(m.tcmorttable, m.tnintrest, m.nAgeEnd) m.nDx = this.actDx(m.tcmorttable, m.tnintrest, m.nAgeBegin) m.nMxn = this.actMxstreep(m.tcmorttable, m.tnintrest, m.nAgeEnd) IF m.nDx <= 0 RETURN 0 ELSE RETURN (m.nRx - m.nRxn - m.tnDuration*m.nMxn)/m.nDx ENDIF ENDFUNC FUNCTION actIAxn LPARAMETERS m.tcmorttable, m.tnintrest,m.tnAge,m.tnDuration,m.tcWay LOCAL m.nAgeBegin, m.nAgeEnd, m.nRx,m.nRxn,m.nDx,m.nDxn,m.nMxn m.nAgeBegin = m.tnAge m.nAgeEnd = m.tnAge + m.tnDuration m.nRx = this.actRxstreep(m.tcmorttable, m.tnintrest, m.nAgeBegin) m.nRxn = this.actRxstreep(m.tcmorttable, m.tnintrest, m.nAgeEnd) m.nMxn = this.actMxstreep(m.tcmorttable, m.tnintrest, m.nAgeEnd) m.nDx = this.actDx(m.tcmorttable, m.tnintrest, m.nAgeBegin) m.nDxn = this.actDx(m.tcmorttable, m.tnintrest, m.nAgeEnd) IF m.nDx <= 0 RETURN 0 ELSE RETURN (m.nRx - m.nRxn - m.tnDuration*m.nMxn +m.tnDuration *m.nDxn)/m.nDx ENDIF ENDFUNC FUNCTION actDAx1n LPARAMETERS m.tcmorttable, m.tnintrest,m.tnAge,m.tnDuration,m.tcWay LOCAL m.nAgeBegin, m.nAgeEnd, m.nRx,m.nRxn,m.nDx,m.nMx,m.nMxn m.nAgeBegin = m.tnAge m.nAgeEnd = m.tnAge + m.tnDuration m.nRx = this.actRxstreep(m.tcmorttable, m.tnintrest, m.nAgeBegin) m.nRxn = this.actRxstreep(m.tcmorttable, m.tnintrest, m.nAgeEnd) m.nMx = this.actMxstreep(m.tcmorttable, m.tnintrest, m.nAgeBegin) m.nMxn = this.actMxstreep(m.tcmorttable, m.tnintrest, m.nAgeEnd) m.nDx = this.actDx(m.tcmorttable, m.tnintrest, m.nAgeBegin) IF m.nDx <= 0 RETURN 0 ELSE RETURN (m.tnDuration*m.nMx - m.nRx + m.nMx + m.nRxn - m.nMxn)/m.nDx ENDIF ENDFUNC FUNCTION actDAxn LPARAMETERS m.tcmorttable, m.tnintrest,m.tnAge,m.tnDuration LOCAL m.nAgeBegin, m.nAgeEnd, m.nRx,m.nRxn,m.nDx,m.nDxn,m.nMx,m.nMxn m.nAgeBegin = m.tnAge m.nAgeEnd = m.tnAge + m.tnDuration m.nRx = this.actRxstreep(m.tcmorttable, m.tnintrest, m.nAgeBegin) m.nRxn = this.actRxstreep(m.tcmorttable, m.tnintrest, m.nAgeEnd) m.nMx = this.actMxstreep(m.tcmorttable, m.tnintrest, m.nAgeBegin) m.nMxn = this.actMxstreep(m.tcmorttable, m.tnintrest, m.nAgeEnd) m.nDx = this.actDx(m.tcmorttable, m.tnintrest, m.nAgeBegin) m.nDxn = this.actDx(m.tcmorttable, m.tnintrest, m.nAgeEnd) IF m.nDx <= 0 RETURN 0 ELSE RETURN (m.tnDuration*m.nMx - m.nRx + m.nMx + m.nRxn - m.nMxn + m.nDxn)/m.nDx ENDIF ENDFUNC FUNCTION actAaxnPrae LPARAMETERS m.tcmorttable, m.tnintrest,m.tnAge,m.tnDuration,m.tnFreq,m.tcWay LOCAL m.nAgeBegin,m.nAgeEnd,m.nNx,m.nNxn,m.nDx,m.nDxn m.nAgeBegin = m.tnAge m.nAgeEnd = m.tnAge + m.tnDuration m.nNx = this.actNx(m.tcmorttable, m.tnintrest, m.nAgeBegin) m.nNxn = this.actNx(m.tcmorttable, m.tnintrest, m.nAgeEnd) m.nDx = this.actDx(m.tcmorttable, m.tnintrest, m.nAgeBegin) m.nDxn = this.actDx(m.tcmorttable, m.tnintrest, m.nAgeEnd) IF m.nDx <= 0 RETURN 0 ELSE RETURN (m.nNx - m.nNxn) / m.nDx - (1 - m.nDxn / m.nDx) * (m.tnFreq - 1) / (2 * m.tnFreq) ENDIF ENDFUNC FUNCTION actAaxnPost LPARAMETERS m.tcmorttable, m.tnintrest,m.tnAge,m.tnDuration,m.tnFreq,m.tcWay LOCAL m.nAgeBegin,m.nAgeEnd,m.nNx,nNxn1,m.nDx,m.nDxn m.nAgeBegin = m.tnAge m.nAgeEnd = m.tnAge + tnDuration m.nNx = this.actNx(m.tcmorttable, m.tnintrest, m.nAgeBegin) nNxn1 = this.actNx(m.tcmorttable, m.tnintrest, MIN(this.nMaxAge, m.nAgeEnd+1)) m.nDx = this.actDx(m.tcmorttable, m.tnintrest, m.nAgeBegin) m.nDxn = this.actDx(m.tcmorttable, m.tnintrest, nAgeEnd) IF m.nDx <= 0 RETURN 0 ELSE RETURN (m.nNx - m.nDx - nNxn1) / m.nDx - (1 - m.nDxn / m.nDx) * (tnFreq - 1) / (2 * tnFreq) ENDIF ENDFUNC ENDDEFINE