在FSI系统中当一个calculator开始进行计算的时候需要把他的status变成busy,而当计算结束(成功或抛出异常)需要把这个calculator的status变成idle。下面是这个FSI系统对这个calculator的实现。
package com.fsillc.remote.server;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.GregorianCalendar;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Category;
import com.fsillc.calculatordata.EspCMOCallOptionSpecStruct;
import com.fsillc.calculatordata.EspIROptionDescStruct;
import com.fsillc.calculatordata.EspIRTreeParamsStruct;
import com.fsillc.calculatordata.EspMBSCalcInputStruct;
import com.fsillc.calculatordata.EspMBSIOPOStripStruct;
import com.fsillc.calculatordata.EspMBSValuationStruct;
import com.fsillc.calculatordata.EspMarketVolatilityDataStruct;
import com.fsillc.calculatordata.EspSetOfCurvePointsStruct;
import com.fsillc.calculatordata.EspTreeSizeSpecStruct;
import com.fsillc.calculatordata.FixedIncomeSecurityDescription;
import com.fsillc.calculatordata.HowToFitPrepayMultiplersAndInitialGuess;
import com.fsillc.calculatordata.MBSCalculatorException;
import com.fsillc.calculatordata.MBSDollarRollStruct;
import com.fsillc.calculatordata.OptionaInputToCFGenerator;
import com.fsillc.calculatordata.OptionalModelManipulationData;
import com.fsillc.calculatordata.YieldCurveException;
import com.fsillc.constants.CFSIBondYieldType;
import com.fsillc.constants.CFSICouponFrequencyType;
import com.fsillc.constants.CFSIDataSource;
import com.fsillc.constants.CFSIDerivativeType;
import com.fsillc.constants.CFSIDiscounting;
import com.fsillc.constants.CFSIIndexType;
import com.fsillc.constants.CFSIMBSTypes;
import com.fsillc.constants.CFSIMortgageRateType;
import com.fsillc.constants.CFSIPrepaySpeedUnit;
import com.fsillc.dataclasses.CFSICashFlowMatrix;
import com.fsillc.dataclasses.CFSIDynamicMeasuresCashFlowMatrixManager;
import com.fsillc.dataclasses.CFSIPartialDurationCashFlowMatrixManager;
import com.fsillc.dataclasses.CFSITotalReturnCashFlowMatrixManager;
import com.fsillc.exceptions.InvalidDataPathException;
import com.fsillc.exceptions.SecurityNotFoundException;
import com.fsillc.interfaces.IFSIBondResults;
import com.fsillc.interfaces.IFSICMOCallOptionSpec;
import com.fsillc.interfaces.IFSICalculationOptions;
import com.fsillc.interfaces.IFSICorpBond;
import com.fsillc.interfaces.IFSIDerivatives;
import com.fsillc.interfaces.IFSIEuroDollarFuture;
import com.fsillc.interfaces.IFSIFixedIncomeSecurityDescription;
import com.fsillc.interfaces.IFSIFutureOption;
import com.fsillc.interfaces.IFSIInterestRateTreeParams;
import com.fsillc.interfaces.IFSIMBSDollarRoll;
import com.fsillc.interfaces.IFSIMBSPrepaymentHistory;
import com.fsillc.interfaces.IFSIMBSResults;
import com.fsillc.interfaces.IFSIMarketVolatility;
import com.fsillc.interfaces.IFSIMortgageBackedSecurity;
import com.fsillc.interfaces.IFSIMortgageCollateralDescription;
import com.fsillc.interfaces.IFSIObjectManager;
import com.fsillc.interfaces.IFSIOptionalModelManipulationData;
import com.fsillc.interfaces.IFSIPrepayLoanLevelDescription;
import com.fsillc.interfaces.IFSIPrepayModelMatrix;
import com.fsillc.interfaces.IFSISecurity;
import com.fsillc.interfaces.IFSISecurityDataSource;
import com.fsillc.interfaces.IFSISynthetic;
import com.fsillc.interfaces.IFSISysConfigParameters;
import com.fsillc.interfaces.IFSITotalReturnInput;
import com.fsillc.interfaces.IFSITotalReturnResults;
import com.fsillc.interfaces.IFSITreeSizeSpec;
import com.fsillc.interfaces.IFSIYieldCurves;
import com.fsillc.natif.release5.BondCalculator;
import com.fsillc.natif.release5.DerivativeCalculator;
import com.fsillc.natif.release5.GetMarketData;
import com.fsillc.natif.release5.MBSCalculator;
import com.fsillc.natif.release5.NewMBSCalculator;
import com.fsillc.natif.release5.SecurityCalculator;
import com.fsillc.natif.release5.MBSCalculator.NoDLLException;
import com.fsillc.remote.interfaces.Calculator;
import com.fsillc.remote.interfaces.FSIHeartBeat;
import com.fsillc.remote.interfaces.FSINamingContext;
import com.fsillc.remote.util.CalcStatus;
import com.fsillc.remote.util.JNDIHelper;
import com.fsillc.securities.CFSICorpBond;
import com.fsillc.securities.SecurityUtils;
import com.fsillc.securities.MBS.CFSIMortgageBackedSecurity;
import com.fsillc.utils.FSISingleton;
public class CalculatorImplementation extends UnicastRemoteObject implements Calculator
{
//
// Member variables
//
private static final long serialVersionUID = 3978706181671630387L;
// Logger
private static Category m_oLogger = Category.getInstance(CalculatorImplementation.class);
MBSCalculator mbsCalculator;
NewMBSCalculator newMBSCalculator;
BondCalculator bondCalculator;
DerivativeCalculator derivativeCalculator;
SecurityCalculator securityCalculator;
private final String calcName;
private String strHostName;
GetMarketData getMarketData;
long timeOfLastFunctionCall;
private FSIHeartBeat m_fsiGUIHeartBeat;
private FSIHeartBeat m_fsiManagerHeartBeat;
private final int calcType;
static public final long defaultExpirationTimeInMilliSeconds = 7200000; // 80 minutes
String strScenarioInitializationId;
// Bigegg -- Added this field to represent if the calculator running on a linux
private boolean isWindows = true;
// This id is used to distinguish two calculators with the same name
private final long id;
/**
* Constructor.
*
* @param calcName name of this Calculator
* @param calcType type of this Calculator
* @throws RemoteException
* @throws MBSCalculator.NoDLLException
* @throws MBSCalculatorException
*/
public CalculatorImplementation (String calcName, int calcType)
throws RemoteException, MBSCalculator.NoDLLException, MBSCalculatorException
{
id = System.currentTimeMillis();
this.calcName = calcName;
this.calcType = calcType;
isWindows = isWindowsPlatform();
init();
}
//
// Calculator implementation
//
public long getFreeMemory ()
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getFreeMemory", "");
Runtime oRuntime = Runtime.getRuntime();
long lFreeMemory = oRuntime.freeMemory();
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
return lFreeMemory;
}
public long getTotalMemory ()
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getTotalMemory", "");
Runtime oRuntime = Runtime.getRuntime();
long lTotalMemory = oRuntime.totalMemory();
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
return lTotalMemory;
}
public String getName ()
throws RemoteException
{
// Bigegg - We dont bother this unnecessary call to JNDI server
// We only need to adjust the last call timestamp
// updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getName", "");
// updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
m_oLogger.debug("in Calculator.getName()");
setTimeOfLastFunctionCall();
return calcName;
}
public long getId() throws RemoteException {
return id;
}
public void gc ()
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "gc", "");
try
{
Runtime oRuntime = Runtime.getRuntime();
oRuntime.gc();
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
}
public void setScenarioInitializationId (String strId)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "setScenarioInitializationId", "");
strScenarioInitializationId = strId;
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
public String getScenarioInitializationId ()
throws RemoteException
{
// Bigegg - We dont bother this unnecessary call to JNDI server.
// We only need to adjust the last call timestamp
// updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getScenarioInitializationId", "");
// updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
m_oLogger.debug("in Calculator.getScenarioInitializationId()");
setTimeOfLastFunctionCall();
return strScenarioInitializationId;
}
public int copyIfAliveAndAvailable (int i, FSIHeartBeat guiHeartBeat)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "copyIfAliveAndAvailable", "");
int ret = i - 1;
try
{
String requestingGUI = guiHeartBeat.getHostname();
String lockingGUI = getGUIHeartBeat().getHostname();
m_oLogger.info("Requesting GUI is " + requestingGUI + ", locking GUI is " + lockingGUI);
if (requestingGUI.equalsIgnoreCase(lockingGUI))
{
ret = i;
}
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public String getHostName ()
throws RemoteException
{
// Bigegg - We dont bother this unnecessary call to JNDI server
// We only need to adjust the last call timestamp
// updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getHostName", "");
// updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
m_oLogger.debug("in Calculator.getHostName()");
setTimeOfLastFunctionCall();
return strHostName;
}
/**
* This method is synchronized.
*/
public synchronized boolean setUnavailable (FSIHeartBeat hb)
throws RemoteException
{
String hostname = getHostFromHeartBeat(hb);
m_oLogger.info("in setUnavailable(" + hostname + ")");
if (hostname == "")
{
m_oLogger.warn("Wrong GUI heart beat, we will not lock this Calculator");
}
if (getGUIHeartBeat() == null)
{
// We can lock this Calculator
m_oLogger.debug("[" + calcName + "]This calculator will be locked by " + hostname);
setGUIHeartBeat(hb);
// We always call this method in JNDI server, and the server will update the status
// accordingly. So we dont need to call it here to save some network roundtrip.
// updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
return true;
}
else
{
// Calculator already locked
m_oLogger.warn("[" + calcName + "]Failed to lock the Calculator for " + hostname);
return false;
}
}
/**
* This method is synchronized.
*/
public synchronized boolean setAvailable (FSIHeartBeat guiHeartBeat)
throws RemoteException
{
String hostname = getHostFromHeartBeat(guiHeartBeat);
m_oLogger.info("in setAvailable(" + hostname + ")");
if (hostname == "")
{
m_oLogger.warn("Wrong GUI heart beat, we will not unlock this Calculator");
}
String lockingGUI = getHostFromHeartBeat(getGUIHeartBeat());
if (hostname.equalsIgnoreCase(lockingGUI))
{
// The locking GUI calling this method
m_oLogger.debug("[" + calcName + "]The locking GUI is " + lockingGUI +
", we are going to release this Calculator");
setGUIHeartBeat(null); // Real unlock happens here
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
return true;
}
else
{
// The calling GUI is not the owning GUI
m_oLogger.warn("[" + calcName + "]The locking GUI is " + lockingGUI +
", has no rights to release this Calculator");
return false;
}
}
public boolean isAboutToExpire ()
throws RemoteException
{
m_oLogger.debug("in Calculator.isAboutToExpire()");
long timeSinceLastFunctionCall = System.currentTimeMillis() - timeOfLastFunctionCall;
// if 5 minutes before calculator is to expire and become available once again.
if (timeSinceLastFunctionCall > defaultExpirationTimeInMilliSeconds - 300000)
{
return true;
}
return false;
}
public void refreshAllPrepayParameters ()
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "RefreshAllPrepayParameters", "");
try
{
MBSCalculator.RefreshAllPrepayParameters();
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
}
public int obtainTreeId (EspSetOfCurvePointsStruct ycDiscStruct,
EspTreeSizeSpecStruct treeSpec,
EspMarketVolatilityDataStruct mvdsp,
EspIRTreeParamsStruct irpp)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "obtainTreeId", "");
int retVal = 0;
try
{
retVal = mbsCalculator.obtainTreeId(ycDiscStruct, treeSpec, mvdsp, irpp);
}
catch (MBSCalculator.NoDLLException e)
{
System.out.println("No Calculator!");
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return retVal;
}
public int obtainTreeId (IFSIYieldCurves fsiYieldCurve,
IFSITreeSizeSpec fsiTreeSizeSpec,
IFSIMarketVolatility fsiVolatility,
IFSIInterestRateTreeParams fsiIRTreeParams,
IFSISysConfigParameters fsiSysConfig)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "obtainTreeId", "");
int ret = 0;
try
{
ret = bondCalculator.obtainTreeId(fsiYieldCurve, fsiTreeSizeSpec, fsiVolatility,
fsiIRTreeParams, fsiSysConfig);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public int obtainTreeId (IFSIYieldCurves fsiYieldCurve,
IFSIYieldCurves fsiHorizonYC,
IFSITreeSizeSpec fsiTreeSizeSpec,
IFSIMarketVolatility fsiVolatility,
IFSIMarketVolatility fsiHorizonVol,
IFSIInterestRateTreeParams fsiIRTreeParams,
IFSISysConfigParameters fsiSysConfig)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "obtainTreeId", "");
int ret = 0;
try
{
ret = bondCalculator.obtainTreeId(fsiYieldCurve, fsiHorizonYC, fsiTreeSizeSpec,
fsiVolatility, fsiHorizonVol, fsiIRTreeParams, fsiSysConfig);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public void resetPaths (IFSIPrepayModelMatrix fsiPrepayMatrix, IFSISecurityDataSource fsiSource)
throws Exception
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "resetPaths", "");
try
{
String sPrepayModelPath = "";
String sCMOPath = "";
if (isWindows)
{
sPrepayModelPath = fsiPrepayMatrix.getPrepayModelParameterPath();
sCMOPath = fsiSource.getPath() + ' ' + fsiSource.getPath2();
}
else
{
sPrepayModelPath = fsiPrepayMatrix.getPrepayModelParameterPathUnix();
sCMOPath = fsiSource.getPathUnix() + ' ' + fsiSource.getPathUnix2();
}
internalResetPaths(sPrepayModelPath, sCMOPath);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
}
public void resetPaths (String prepayModelPath, String cmoDataVendorPath)
throws Exception
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "resetPaths", "");
try
{
internalResetPaths(prepayModelPath, cmoDataVendorPath);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
}
public EspMBSValuationStruct[] calcStaticMeasuresVector (String whatToCalculate,
int optionFlag,
int mbsType,
EspMBSCalcInputStruct calcInputStruct,
OptionalModelManipulationData optionalModelData,
OptionaInputToCFGenerator optionaInputToCFGenerator,
EspCMOCallOptionSpecStruct espCMOCallOptionSpecStruct, EspMBSValuationStruct[] givenValues)
throws MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "calcStaticMeasuresVector", "");
EspMBSValuationStruct[] retVal = null;
try
{
retVal = mbsCalculator.calcStaticMeasures_Vector(whatToCalculate, optionFlag,
mbsType, calcInputStruct, optionalModelData, optionaInputToCFGenerator,
espCMOCallOptionSpecStruct, givenValues);
}
catch (MBSCalculator.NoDLLException e)
{
m_oLogger.error("No DLL", e);
}
catch (Exception ex)
{
m_oLogger.error("Error when calculating static measure", ex);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return retVal;
} // end calcStaticMeasuresVector
public EspMBSValuationStruct calcDynamicMeasures (int random_seed,
int number_of_sampling_paths,
double yield_curve_shift_in_bps,
int mbsType,
EspMBSCalcInputStruct calcInputStruct,
CFSIDiscounting useCMTAsDiscountRateFlag,
int mortgageRateModelFlag,
OptionalModelManipulationData optionalModelData,
OptionaInputToCFGenerator optionaInputToCFGenerator,
EspCMOCallOptionSpecStruct espCMOCallOptionSpecStruct,
String whatToCalculate,
EspMBSValuationStruct givenValues)
throws MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "calcDynamicMeasures", "");
EspMBSValuationStruct retVal = null;
try
{
retVal = mbsCalculator.calcDynamicMeasures(random_seed, number_of_sampling_paths,
yield_curve_shift_in_bps, mbsType, calcInputStruct,
useCMTAsDiscountRateFlag, mortgageRateModelFlag,
optionalModelData, optionaInputToCFGenerator,
espCMOCallOptionSpecStruct, whatToCalculate,
givenValues);
}
catch (MBSCalculator.NoDLLException e)
{
m_oLogger.error("No Calculator", e);
}
catch (Exception ex)
{
m_oLogger.error("Error when calculating dynamic measures", ex);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return retVal;
}
public EspMBSValuationStruct[] calcDynamicMeasuresVector (int random_seed,
int number_of_sampling_paths,
double yield_curve_shift_in_bps,
int mbsType,
EspMBSCalcInputStruct calcInputStruct,
CFSIDiscounting useCMTAsDiscountRateFlag,
int mortgageRateModelFlag,
OptionalModelManipulationData optionalModelData,
OptionaInputToCFGenerator optionaInputToCFGenerator,
EspCMOCallOptionSpecStruct espCMOCallOptionSpecStruct,
String whatToCalculate,
EspMBSValuationStruct[] givenValues)
throws MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "calcDynamicMeasuresVector", "");
EspMBSValuationStruct[] retVal = null;
try
{
retVal = mbsCalculator.calcDynamicMeasures_Vector(random_seed, number_of_sampling_paths,
yield_curve_shift_in_bps, mbsType, calcInputStruct, useCMTAsDiscountRateFlag,
mortgageRateModelFlag, optionalModelData, optionaInputToCFGenerator,
espCMOCallOptionSpecStruct, whatToCalculate, givenValues);
}
catch (MBSCalculator.NoDLLException e)
{
m_oLogger.debug("No Calculator", e);
}
catch (Exception ex)
{
m_oLogger.debug("Error when calculating dynamic measures vector", ex);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return retVal;
}
public EspMBSCalcInputStruct retrieveCMOPoolInfo (int isCusipInput,
String cusip,
String dealName,
String trancheName,
long settleDate,
int wamBuckets,
int wacBuckets)
throws MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "retrieveCMOPoolInfo", "");
EspMBSCalcInputStruct returnStruct = null;
try
{
returnStruct = mbsCalculator.retrieveCMOPoolInfo(isCusipInput,
cusip, dealName, trancheName, settleDate,
wamBuckets, wacBuckets);
//For collateral override:
if (returnStruct != null &&
returnStruct.mbs_collat_desc_struct != null)
{
returnStruct.mbs_collat_desc_struct.collatAgencyName =
returnStruct.mbs_collat_desc_struct.agencyName;
}
}
catch (MBSCalculator.NoDLLException e)
{
m_oLogger.error("No Calculator", e);
}
catch (Exception ex)
{
m_oLogger.debug("Error when retrieving CMO pool info", ex);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return returnStruct;
}
public EspMBSIOPOStripStruct fitPrepayMultiplierForIOPOStrip (
int randomSeed,
CFSIDiscounting useCMTAsDiscRateFlag,
int mortRateModelFlag,
int numberOfSamplingPaths,
int mbsType,
EspMBSIOPOStripStruct stripStruct,
MBSDollarRollStruct dollarRollStruct)
throws MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "fitPrepayMultiplierForIOPOStrip", "");
EspMBSIOPOStripStruct returnStruct = null;
try
{
returnStruct = mbsCalculator.fitPrepayMultiplierForIOPOStrip(
randomSeed, useCMTAsDiscRateFlag, mortRateModelFlag,
numberOfSamplingPaths, mbsType, stripStruct,
dollarRollStruct);
}
catch (MBSCalculator.NoDLLException e)
{
m_oLogger.error("No Calculator", e);
}
catch (Exception ex)
{
m_oLogger.error("Error when fitting prepay multiplier", ex);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return returnStruct;
}
public FixedIncomeSecurityDescription getCMOBondInfo (long settleDate,
String cusip,
String dealName,
String trancheName)
throws MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getCMOBondInfo", "");
FixedIncomeSecurityDescription returnStruct = null;
try
{
returnStruct = mbsCalculator.getCMOBondInfo(settleDate, cusip,
dealName, trancheName);
}
catch (MBSCalculator.NoDLLException e)
{
m_oLogger.error("No Calculator", e);
}
catch (Exception ex)
{
m_oLogger.error("Error when getting CMO bond info", ex);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return returnStruct;
}
public EspIROptionDescStruct[] calcIROptionPrice (
EspIROptionDescStruct[] securities,
int blackFlag,
int setStrikePriceAtMoneyFlag)
throws MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "calcIROptionPrice", "");
EspIROptionDescStruct[] returnStructs = null;
try
{
returnStructs = mbsCalculator.calcIROptionPrice(securities,
blackFlag, setStrikePriceAtMoneyFlag);
}
catch (MBSCalculator.NoDLLException e)
{
m_oLogger.error("No Calculator", e);
}
catch (Exception ex)
{
m_oLogger.error("Error when calculating IR option price", ex);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return returnStructs;
}
public EspIROptionDescStruct[] fitTermStructureVolatility (
EspIROptionDescStruct[] securities,
int blackFlag,
int setStrikePriceAtMoneyFlag,
int fitOnlyOverallFactorFlag,
int autoChooseStartingVolatCurvesFlag,
int fitMeanReversionCurveFlag,
int restrictFittingProcessFlag)
throws MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "fitTermStructureVolatility", "");
EspIROptionDescStruct[] returnValue = null;
try
{
returnValue = mbsCalculator.fitTermStructureVolatility(securities,
blackFlag, setStrikePriceAtMoneyFlag, fitOnlyOverallFactorFlag,
autoChooseStartingVolatCurvesFlag, fitMeanReversionCurveFlag,
restrictFittingProcessFlag);
}
catch (MBSCalculator.NoDLLException e)
{
m_oLogger.error("No Calculator", e);
}
catch (Exception ex)
{
m_oLogger.error("Error when fitting volatility structure", ex);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return returnValue;
}
public EspMarketVolatilityDataStruct getCurrentEspMarketVolatilityDataStruct (
int treeId)
throws MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getCurrentEspMarketVolatilityDataStruct", "");
EspMarketVolatilityDataStruct returnStruct = null;
try
{
returnStruct = mbsCalculator.getCurrentEspMarketVolatilityDataStruct(treeId);
}
catch (MBSCalculator.NoDLLException e)
{
m_oLogger.error("No Calculator", e);
}
catch (Exception ex)
{
m_oLogger.error("Error when getting current ESP market volatility", ex);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return returnStruct;
}
public double[] calcVolatilityCorrelation (double[] timesInYear)
throws MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "calcVolatilityCorrelation", "");
double[] returnArray = null;
try
{
returnArray = mbsCalculator.calcVolatilityCorrelation(timesInYear);
}
catch (MBSCalculator.NoDLLException e)
{
m_oLogger.error("No Calculator", e);
}
catch (Exception ex)
{
m_oLogger.error("Error when calculating volatility correlation", ex);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return returnArray;
}
public EspSetOfCurvePointsStruct getYieldCurveFrom (
long _date,
String vendor,
String user,
String password)
throws RemoteException, YieldCurveException, GetMarketData.NoDLLException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getYieldCurveFrom", "");
EspSetOfCurvePointsStruct returnObj = null;
try
{
returnObj = getMarketData.getYieldCurveFrom(_date, vendor, user, password);
}
catch (GetMarketData.NoDLLException e)
{
m_oLogger.error("No Calculator", e);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return returnObj;
}
public EspIROptionDescStruct[] getIROption (String[] arrTickers,
int[] arrBondTypes,
long _date,
String vendor,
String user,
String password)
throws RemoteException, YieldCurveException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getIROption", "");
EspIROptionDescStruct[] returnObjs = null;
try
{
returnObjs = getMarketData.getIROption(arrTickers, arrBondTypes,
_date, vendor, user, password);
}
catch (GetMarketData.NoDLLException e)
{
m_oLogger.error("No Calculator", e);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return returnObjs;
}
public IFSIMortgageBackedSecurity loadMBSFromBloomberg (
String sSecurityName,
IFSIMortgageBackedSecurity fsiMBS,
IFSIFixedIncomeSecurityDescription fsiDescription)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "loadMBSFromBloomberg", sSecurityName);
IFSIMortgageBackedSecurity returnObjs = null;
try
{
returnObjs = getMarketData.loadMBSFromBloomberg(sSecurityName, fsiMBS, fsiDescription);
}
catch (GetMarketData.NoDLLException e)
{
m_oLogger.error("No Calculator", e);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return returnObjs;
}
public IFSIMortgageBackedSecurity loadMBSFromCacheOrBloomberg (
String sSecurityName)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "loadMBSFromCacheOrBloomberg", sSecurityName);
IFSIMortgageBackedSecurity fsiMBS = null;
try
{
IFSIObjectManager om = new CFSIMortgageBackedSecurity(
FSISingleton.getFSISession());
((CFSIMortgageBackedSecurity) om).openFromBloomberg(
sSecurityName, this);
fsiMBS = (IFSIMortgageBackedSecurity) om.getManagedObject();
if (fsiMBS == null)
{
throw new RemoteException("Security not found.");
}
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return fsiMBS;
}
public Object[] fitPrepayMultipliersToMBSList (int nRandomSeed,
int nuNmberOfSamplingPath,
CFSIDiscounting fsiUseCMTAsDiscountRate,
CFSIMortgageRateType fsiMortgageRateModel,
IFSIMortgageBackedSecurity[] arrMBSList,
IFSIMBSResults[] arrMBSValuation,
double[] arrTargetOAS,
HowToFitPrepayMultiplersAndInitialGuess
espFittingParams, int nWhatToCalculate)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "fitPrepayMultipliersToMBSList", "");
Object[] arrReturn = null;
try
{
if (arrMBSList.length > 0 &&
CFSIDataSource.INTEX.equals(arrMBSList[0].getDataSource()))
{
checkCMOPaths(arrMBSList[0].getCMOProviderDataDirectoryPath());
}
arrReturn = newMBSCalculator.fitPrepayMultipliersToMBSList(
nRandomSeed, nuNmberOfSamplingPath, fsiUseCMTAsDiscountRate,
fsiMortgageRateModel, arrMBSList, arrMBSValuation,
arrTargetOAS, espFittingParams, nWhatToCalculate);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return arrReturn;
}
public IFSIMBSPrepaymentHistory loadPrepaymentHistory (
IFSISecurityDataSource fsiSource,
IFSIMBSPrepaymentHistory history)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "loadPrepaymentHistory", "");
IFSIMBSPrepaymentHistory ret = null;
try
{
String sCMOPath;
if (isWindows)
{
sCMOPath = fsiSource.getPath() + ' ' + fsiSource.getPath2();
}
else
{
sCMOPath = fsiSource.getPathUnix() + ' ' + fsiSource.getPathUnix2();
}
ret = loadPrepaymentHistory(sCMOPath, history);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public IFSIMBSPrepaymentHistory loadPrepaymentHistory (String dataPath,
IFSIMBSPrepaymentHistory history)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "loadPrepaymentHistory", "");
IFSIMBSPrepaymentHistory ret = null;
try
{
ret = newMBSCalculator.loadPrepaymentHistory(dataPath, history);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public IFSIMBSPrepaymentHistory loadPrepaymentHistoryFromBloomberg (
IFSIMBSPrepaymentHistory history)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "loadPrepaymentHistoryFromBloomberg", "");
IFSIMBSPrepaymentHistory ret = null;
try
{
ret = newMBSCalculator.loadPrepaymentHistoryFromBloomberg(history);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public IFSIMortgageBackedSecurity loadMBS (boolean isCusipInput,
String cusip,
String dealName,
String trancheName,
IFSIMortgageBackedSecurity fsiMBS,
IFSIFixedIncomeSecurityDescription fsiDescription,
GregorianCalendar gcSettleDate,
int wamBuckets,
int wacBuckets)
throws RemoteException, SecurityNotFoundException, InvalidDataPathException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "loadMBS", cusip);
IFSIMortgageBackedSecurity ret = null;
try
{
// Bigegg -- Reset the path according to the running OS
resetPaths(fsiMBS);
checkCMOPaths(fsiMBS.getCMOProviderDataDirectoryPath());
fsiMBS.setARM(true);
ret = newMBSCalculator.loadMBS(isCusipInput, cusip, dealName,
trancheName, fsiMBS,
fsiDescription, gcSettleDate, wamBuckets, wacBuckets);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public IFSIMBSResults[] calculateDynamicMeasures (
int nRandomSeed,
int nSamplingPaths,
double dYieldCurveShiftInBps,
IFSIMortgageBackedSecurity fsiCalcInputStruct,
CFSIDiscounting fsiUseCMTAsDiscountRate,
CFSIMortgageRateType fsiMortgageRateModel,
IFSIOptionalModelManipulationData fsiOptionalModelData,
IFSICMOCallOptionSpec fsiCMOCallOptionSpec,
long lInputOptions,
long lOutputOptions,
IFSIMBSResults arrValues[])
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY,
"calculateDynamicMeasures", fsiCalcInputStruct.getCusip());
IFSIMBSResults[] ret = null;
try
{
// Bigegg -- Reset the path according to the running OS
resetPaths(fsiCalcInputStruct);
if (fsiCalcInputStruct.getType() == CFSIMBSTypes.FRM_CMO)
{
checkCMOPaths(fsiCalcInputStruct.getCMOProviderDataDirectoryPath());
}
if (fsiOptionalModelData.getForcedPrepayMethod().equals(
CFSIPrepaySpeedUnit.CALC_USE_ESPIEL_MODEL))
{
checkPrepayModelPath(fsiCalcInputStruct.getParamsDir());
}
ret = newMBSCalculator.calculateDynamicMeasures(nRandomSeed,
nSamplingPaths, dYieldCurveShiftInBps, fsiCalcInputStruct,
fsiUseCMTAsDiscountRate, fsiMortgageRateModel, fsiOptionalModelData,
fsiCMOCallOptionSpec, lInputOptions, lOutputOptions,
arrValues);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public IFSITotalReturnResults calculateTotalReturn (int nRandomSeed,
int nSamplingPaths,
double dYieldCurveShiftInBps,
IFSIMortgageBackedSecurity fsiCalcInputStruct,
IFSITotalReturnInput fsiInput,
CFSIDiscounting fsiUseCMTAsDiscountRate,
IFSIOptionalModelManipulationData fsiOptionalModelData,
IFSICMOCallOptionSpec fsiSpec,
CFSIMortgageRateType fsiMortgageRateModel,
IFSITotalReturnResults fsiResults,
long lOutputOptions)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY,
"calculateMBSTotalReturn", fsiCalcInputStruct.getCusip());
IFSITotalReturnResults ret;
try
{
resetPaths(fsiCalcInputStruct);
try
{
if (fsiCalcInputStruct.getDataSource().equals(
CFSIDataSource.INTEX))
{
checkCMOPaths(fsiCalcInputStruct.getCMOProviderDataDirectoryPath());
}
}
catch (Exception e)
{
// ignored
}
ret = newMBSCalculator.calculateTotalReturn(nRandomSeed,
nSamplingPaths, dYieldCurveShiftInBps,
fsiCalcInputStruct,
fsiInput, fsiUseCMTAsDiscountRate,
fsiOptionalModelData,
fsiSpec, fsiMortgageRateModel, fsiResults,
lOutputOptions);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public double[] calculatePartialDuration (int nRandomSeed,
int nSamplingPaths,
IFSIMortgageBackedSecurity fsiMBS,
CFSIDiscounting fsiUseCMTAsDiscountRate,
CFSIMortgageRateType fsiMortgageRateModel,
IFSIOptionalModelManipulationData fsiOptionalModelData,
IFSICMOCallOptionSpec fsiSpec,
double dOAS,
double[] arrShocks)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY,
"calculateMBSPartialDuration", fsiMBS.getCusip());
double[] ret = null;
try
{
resetPaths(fsiMBS);
try
{
if (fsiMBS.getDataSource().equals(CFSIDataSource.INTEX))
{
checkCMOPaths(fsiMBS.getCMOProviderDataDirectoryPath());
}
}
catch (Exception e)
{
// ignored
}
ret = newMBSCalculator.calculatePartialDuration(nRandomSeed,
nSamplingPaths, fsiMBS, fsiUseCMTAsDiscountRate,
fsiMortgageRateModel, fsiOptionalModelData, fsiSpec,
dOAS, arrShocks);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public double[] calculatePartialDurations (
GregorianCalendar gcSettlementDate,
IFSICorpBond fsiBond,
double dOAS,
double[] arrShockPoints,
CFSIDiscounting fsiTreasuryFlag,
int nNeedToFitYCCurve)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY,
"calculateCorpBondPartialDurations", fsiBond.getCusip());
double[] ret = null;
try
{
ret = bondCalculator.calculatePartialDruations(gcSettlementDate,
fsiBond, dOAS, arrShockPoints,
fsiTreasuryFlag, nNeedToFitYCCurve);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public IFSICorpBond loadBondIndicatives (String sDataPath,
String sCusip,
GregorianCalendar gcSettlementDate,
IFSICorpBond fsiCorpBond,
IFSIFixedIncomeSecurityDescription fsiDescription)
throws RemoteException, SecurityNotFoundException, InvalidDataPathException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "loadBondIndicatives", sCusip);
IFSICorpBond ret = null;
try
{
checkIDCPath(sDataPath);
m_oLogger.info("loadBondIndicatives with sDataPath = " + sDataPath + " sCusip = " + sCusip +
" settlement date = " + gcSettlementDate.getTime());
ret = bondCalculator.loadBondIndicatives(sDataPath, sCusip,
gcSettlementDate, fsiCorpBond, fsiDescription);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public IFSICorpBond loadBondIndicativesFromCacheOrBloomberg (
String sCusip,
GregorianCalendar gcSettlementDate)
throws RemoteException, SecurityNotFoundException, InvalidDataPathException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "loadBondIndicativesFromCacheOrBloomberg",
sCusip);
IFSICorpBond fsiCorpBond = null;
try
{
IFSIObjectManager om = new CFSICorpBond(
FSISingleton.getFSISession());
((CFSICorpBond) om).openFromBloomberg(sCusip,
gcSettlementDate, this);
om = SecurityUtils.transformCorpBond(om);
fsiCorpBond = (IFSICorpBond) om.getManagedObject();
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return fsiCorpBond;
}
public IFSICorpBond loadBondIndicativesFromBloomberg (
String sCusip,
GregorianCalendar gcSettlementDate,
IFSICorpBond fsiCorpBond,
IFSIFixedIncomeSecurityDescription fsiDescription)
throws RemoteException, SecurityNotFoundException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "loadBondIndicativesFromBloomberg", sCusip);
IFSICorpBond ret = null;
try
{
ret = bondCalculator.loadBondIndicativesFromBloomberg(sCusip,
gcSettlementDate, fsiCorpBond, fsiDescription);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public IFSICorpBond loadBABondIndicatives (String sDataPath,
String sCusip,
GregorianCalendar gcSettlementDate,
IFSICorpBond fsiBond)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "loadBABondIndicatives", sCusip);
IFSICorpBond ret = null;
try
{
checkIDCPath(sDataPath);
ret = bondCalculator.loadBABondIndicatives(sDataPath, sCusip,
gcSettlementDate, fsiBond);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public IFSICorpBond checkValidity (GregorianCalendar gcSettlementDate,
IFSICorpBond fsiCorpBond)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "checkValidity", fsiCorpBond.getCusip());
IFSICorpBond ret = null;
try
{
ret = bondCalculator.CheckValidity(gcSettlementDate, fsiCorpBond);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public IFSIYieldCurves getTreasuryCurvePoint (IFSIYieldCurves fsiCurves)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getTreasuryCurvePoint", "");
IFSIYieldCurves ret = null;
try
{
ret = bondCalculator.getTreasuryCurvePoint(fsiCurves);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public IFSIBondResults calculateDynamicMeasuresFromPrice (
GregorianCalendar gcSettlementDate,
IFSICorpBond pEspBond,
IFSICalculationOptions calculationOption,
IFSIBondResults pResults,
int need_fit_yc_flag,
CFSIDiscounting is_Treasury_flag)
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "CalculateDynamicMeasuresFromPrice", "");
IFSIBondResults ret = null;
try
{
ret = bondCalculator.CalculateDynamicMeasuresFromPrice(
gcSettlementDate, pEspBond, calculationOption,
pResults, need_fit_yc_flag, is_Treasury_flag);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public IFSIBondResults priceFromYield (GregorianCalendar gcSettlementDate,
CFSIBondYieldType fsiYieldType, IFSICorpBond oneBondptr,
IFSIBondResults calc_results)
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "priceFromYield", "");
IFSIBondResults ret = null;
try
{
ret = bondCalculator.PriceFromYield(gcSettlementDate,
fsiYieldType, oneBondptr, calc_results);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public IFSIBondResults priceFromSpreadToWAL (
GregorianCalendar gcSettlementDate,
CFSIDiscounting is_Treasury_flag,
double dSpreadToWAL,
IFSICorpBond oneBondptr, IFSIBondResults pResults)
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "priceFromSpreadToWAL", "");
IFSIBondResults ret = null;
try
{
ret = bondCalculator.PriceFromSpreadToWAL(gcSettlementDate,
is_Treasury_flag, dSpreadToWAL, oneBondptr,
pResults);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public IFSIBondResults priceFromOAS (GregorianCalendar gcSettlementDate,
IFSICorpBond pEspBond,
IFSIBondResults pResults,
int need_fit_yc_flag,
CFSIDiscounting is_Treasury_flag)
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "priceFromOAS", "");
IFSIBondResults ret = null;
try
{
ret = bondCalculator.PriceFromOAS(gcSettlementDate, pEspBond,
pResults, need_fit_yc_flag, is_Treasury_flag);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public IFSIBondResults priceFromZVOAS (GregorianCalendar gcSettlementDate,
IFSICorpBond EspBond,
IFSIBondResults Results,
CFSIDiscounting is_Treasury_flag)
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "priceFromZVOAS", "");
IFSIBondResults ret = null;
try
{
ret = bondCalculator.PriceFromZVOAS(gcSettlementDate, EspBond,
Results, is_Treasury_flag);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return ret;
}
public IFSITotalReturnResults calculateTotalReturn (
GregorianCalendar gcSettlementDate,
IFSICorpBond pEspBond,
IFSITotalReturnInput fsiInput,
IFSITotalReturnResults pResults,
CFSIDiscounting is_Treasury_flag,
long lOutputOptions)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "calculateTotalReturn", "");
IFSITotalReturnResults fsiReturned = null;
try
{
fsiReturned = bondCalculator.CalculateTotalReturn(
gcSettlementDate, pEspBond, fsiInput, pResults,
is_Treasury_flag, lOutputOptions);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return fsiReturned;
}
public IFSIBondResults calculate (IFSIDerivatives fsiDerivatives,
boolean bBlack,
boolean bStrikePriceAtMoney,
long lInputOptions,
long lOutputOptions,
CFSIDiscounting fsiDisountingMethod,
IFSIBondResults fsiResults)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "calculate", "");
IFSIBondResults fsiReturned = null;
try
{
fsiReturned = newMBSCalculator.calculate(fsiDerivatives, bBlack,
bStrikePriceAtMoney, lInputOptions,
lOutputOptions, fsiDisountingMethod, fsiResults);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return fsiReturned;
}
public IFSITotalReturnResults calculateTotalReturn (
IFSIDerivatives fsiDerivatives,
IFSITotalReturnInput fsiInput,
boolean bBlack,
boolean bStrikePriceAtMoney,
CFSIDiscounting fsiDiscounting,
IFSITotalReturnResults fsiResults,
long lOutputOptions)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "calculateTotalReturn", "");
IFSITotalReturnResults fsiReturned = null;
try
{
fsiReturned = newMBSCalculator.calculateTotalReturn(
fsiDerivatives, fsiInput, bBlack, bStrikePriceAtMoney,
fsiDiscounting, fsiResults, lOutputOptions);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return fsiReturned;
}
public double[] calculatePartialDruations (
GregorianCalendar gcSettlementDate,
IFSIDerivatives fsiDerivatives,
double dOAS,
double[] arrShockPoints,
CFSIDiscounting fsiTreasuryFlag,
int nNeedToFitYCCurve)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "calculatePartialDruations", "");
double[] arrPDs = null;
try
{
arrPDs = newMBSCalculator.calculatePartialDruations(
gcSettlementDate, fsiDerivatives, dOAS,
arrShockPoints, fsiTreasuryFlag, nNeedToFitYCCurve);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return arrPDs;
}
public Object[] getForwardRate (CFSIIndexType[] arrIndex,
double dTimeSpan,
CFSICouponFrequencyType fsiFrequency,
CFSIMortgageRateType fsiMortgageRateType,
String sParametersPath)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getForwardRate", "");
Object[] arrRates = null;
try
{
arrRates = newMBSCalculator.getForwardRate(arrIndex, dTimeSpan,
fsiFrequency, fsiMortgageRateType, sParametersPath);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return arrRates;
}
public Object[] getSampledRates (int nRandonSeed,
int nNumberOfPath,
GregorianCalendar gcSettleDate,
CFSIIndexType[] arrIndex,
int nTimeSpan,
boolean bTreasury)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getSampledRates", "");
Object[] arrRates = null;
try
{
arrRates = newMBSCalculator.getSampledRates(nRandonSeed,
nNumberOfPath, gcSettleDate, arrIndex,
nTimeSpan, bTreasury);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return arrRates;
}
public Object[] getIRPCorrelation (CFSIIndexType fsiIndex1,
CFSIIndexType fsiIndex2,
double dTimeSpan,
CFSICouponFrequencyType fsiFrequency)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getIRPCorrelation", "");
Object[] arrCorrelation = null;
try
{
arrCorrelation = newMBSCalculator.getIRPCorrelation(fsiIndex1,
fsiIndex2, dTimeSpan, fsiFrequency);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return arrCorrelation;
}
public Object[] getBlack (CFSIDerivativeType fsiType,
CFSIIndexType fsiIndex,
double dTimeSpan,
CFSICouponFrequencyType fsiFrequency)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getBlack", "");
Object[] arrBlack = null;
try
{
arrBlack = newMBSCalculator.getBlack(fsiType, fsiIndex,
dTimeSpan, fsiFrequency);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return arrBlack;
}
public Object[] getPrepaySpeed (GregorianCalendar gcSettleDate,
GregorianCalendar gcMRateDate,
IFSIMortgageCollateralDescription fsiDescription,
IFSIPrepayModelMatrix fsiMatrix,
double[] arrCommitRate30,
double[] arrCommitRate15,
double[] arrCommitRate07,
double[] arrCommitRate05,
CFSIPrepaySpeedUnit fsiUnit,
CFSIMortgageRateType fsiType,
IFSIMBSPrepaymentHistory fsiActualHistory)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getPrepaySpeed", "");
Object[] arrSpeeds = null;
try
{
String sPrepModelPath = "";
if (isWindows)
{
sPrepModelPath = fsiMatrix.getPrepayModelParameterPath();
}
else
{
sPrepModelPath = fsiMatrix.getPrepayModelParameterPathUnix();
}
arrSpeeds = getPrepaySpeed(gcSettleDate, gcMRateDate,
fsiDescription, sPrepModelPath, arrCommitRate30,
arrCommitRate15, arrCommitRate07, arrCommitRate05, fsiUnit,
fsiType, fsiActualHistory);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return arrSpeeds;
}
public Object[] getPrepaySpeed (GregorianCalendar gcSettleDate,
GregorianCalendar gcMRateDate,
IFSIMortgageCollateralDescription fsiDescription,
String sPrepayModelPath,
double[] arrCommitRate30,
double[] arrCommitRate15,
double[] arrCommitRate07,
double[] arrCommitRate05,
CFSIPrepaySpeedUnit fsiUnit,
CFSIMortgageRateType fsiType,
IFSIMBSPrepaymentHistory fsiActualHistory)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getPrepaySpeed", "");
Object[] arrSpeeds = null;
try
{
arrSpeeds = newMBSCalculator.getPrepaySpeed(gcSettleDate,
gcMRateDate, fsiDescription, sPrepayModelPath,
arrCommitRate30, arrCommitRate15, arrCommitRate07,
arrCommitRate05, fsiUnit, fsiType,
fsiActualHistory);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return arrSpeeds;
}
public IFSIPrepayModelMatrix getPrepayModelMatrixRemote (
IFSIPrepayModelMatrix fsiMatrix)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getPrepayModelMatrixRemote", "");
IFSIPrepayModelMatrix fsiResult = null;
try
{
String sWinPath = fsiMatrix.getPrepayModelParameterPath();
String sUnixPath = fsiMatrix.getPrepayModelParameterPathUnix();
if (!isWindows && null != sUnixPath)
{
m_oLogger.debug("Unix platform. Path = " + sUnixPath);
fsiMatrix.setPrepayModelParameterPath(sUnixPath);
}
else
{
m_oLogger.debug("Win32 platform. Path = " + sWinPath);
}
fsiResult = newMBSCalculator.getPrepayModelMatrix(fsiMatrix);
fsiResult.setPrepayModelParameterPath(sWinPath);
fsiResult.setPrepayModelParameterPathUnix(sUnixPath);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return fsiResult;
}
public IFSIEuroDollarFuture loadEuroDollarFutureFromBloomberg (
IFSIEuroDollarFuture fsiFuture)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "loadEuroDollarFutureFromBloomberg", "");
IFSIEuroDollarFuture fsiReturned = null;
try
{
fsiReturned = derivativeCalculator.loadEuroDollarFutureFromBloomberg(fsiFuture);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return fsiReturned;
}
public IFSIMBSResults calculate (GregorianCalendar gcSettleDate,
long lInputOption,
long lOutputOption,
IFSIFutureOption fsiOption,
IFSIMBSResults fsiResults,
CFSIDiscounting fsiDiscounting)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "calculate", "");
IFSIMBSResults fsiReturned = null;
try
{
fsiReturned = this.derivativeCalculator.calculate(gcSettleDate,
lInputOption, lOutputOption, fsiOption,
fsiResults, fsiDiscounting);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return fsiReturned;
}
public double[] calcPartialDurations (GregorianCalendar gcSettleDate,
IFSISecurity fsiSecurity,
double dOAS,
double[] arrShocks,
CFSIDiscounting fsiDiscounting)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "calcPartialDurations", "");
double[] arrPDs = null;
try
{
arrPDs = this.derivativeCalculator.calcPartialDurations(
gcSettleDate, fsiSecurity, dOAS,
arrShocks, fsiDiscounting);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return arrPDs;
}
public IFSITotalReturnResults calculateTotalReturn (
GregorianCalendar gcSettleDate,
IFSISecurity fsiSecurity,
IFSITotalReturnInput fsiInput,
IFSITotalReturnResults fsiResults,
long lOutputOptions,
IFSIBondResults fsiExtraResults,
CFSIDiscounting fsiDiscounting)
throws RemoteException, MBSCalculatorException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "calculateTotalReturn", "");
IFSITotalReturnResults fsiReturned = null;
try
{
fsiReturned = derivativeCalculator.calculateTotalReturn(
gcSettleDate, fsiSecurity, fsiInput, fsiResults,
lOutputOptions, fsiExtraResults, fsiDiscounting);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return fsiReturned;
}
public double getEuroDollarFuturePrice (String sCusip)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getEuroDollarFuturePrice", sCusip);
double dPrice = 0.0D;
try
{
dPrice = derivativeCalculator.getEuroDollarFuturePrice(sCusip);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return dPrice;
}
public double getEuroDollarFutureYield (String sCusip)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getEuroDollarFutureYield", sCusip);
double dYield = 0.0D;
try
{
dYield = derivativeCalculator.getEuroDollarFutureYield(sCusip);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return dYield;
}
/**
* for full instructions on how to use this, see NewMBSCalculator.
*/
public CFSICashFlowMatrix getMBSCashFlows (int iRandomSeed,
int iNumberOfSamplingPaths,
double dYieldCurveShiftInBps,
IFSIMortgageBackedSecurity fsiMBS,
IFSIOptionalModelManipulationData
fsiOptionalModelManipulationData,
CFSIMortgageRateType iMortgageRateModel,
CFSIDiscounting iYieldCurveToUseForDiscounting,
GregorianCalendar gcYieldCurveDate,
GregorianCalendar gcSettleDate,
IFSISynthetic fsiSynthetic, // if no modifiers are desired, pass in null.
IFSICMOCallOptionSpec fsiCallOptionSpec,
long lCashFlowType, // as defined in CFSICashFlowType. Can only represent one type.
int iPartialDurationYCShockIndex, // ignored if the cash flow type does not denote partial duration. This
// is not an index among all the yield curve points, but only among the shocked points. Thus, if there are
// two shocked points, then a value of 1 refers to the second shocked point, not necessarily the two-month maturity.
boolean bCalculateDollarRoll,
IFSITotalReturnInput fsiTotalReturnInput, // ignored if the cash flow type is not one of the total return
// types (set to null in this case).
long lCalculationOutputOptionsForTotalReturnOnly)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getMBSCashFlows", "");
CFSICashFlowMatrix fsiMatrix = null;
try
{
fsiMatrix = newMBSCalculator.getMBSCashFlows(
iRandomSeed, iNumberOfSamplingPaths, dYieldCurveShiftInBps,
fsiMBS, fsiOptionalModelManipulationData, iMortgageRateModel,
iYieldCurveToUseForDiscounting,
gcYieldCurveDate, gcSettleDate, fsiSynthetic, fsiCallOptionSpec, lCashFlowType,
iPartialDurationYCShockIndex, bCalculateDollarRoll, fsiTotalReturnInput,
lCalculationOutputOptionsForTotalReturnOnly);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return fsiMatrix;
}
public long getNecessaryCashFlowTypesForCalculations (
long lInputOptions, // as defined in IFSICalculationOptions
long lOutputOptions) // as defined in IFSICalculationOptions
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getNecessaryCashFlowTypesForCalculations", "");
long lType;
try
{
lType = SecurityCalculator.getNecessaryCashFlowTypesForCalculations(
lInputOptions, lOutputOptions);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return lType;
}
// see com.fsillc.natif.release5.SecurityCalculator.java for documentation.
public IFSIMBSResults[] calculateDynamicMeasuresGivenCashFlows (
long lInputOptions,
long lOutputOptions,
CFSIDynamicMeasuresCashFlowMatrixManager[] arrManagers,
IFSIMBSDollarRoll fsiMBSDollarRoll,
IFSIMBSResults[] arrMBSResults)
throws RemoteException
{
// the function signature here is different than the native method. This is to accomodate a weird bug
// in RMI where modifications to an object sent from the client are lost when the function returns. Thus,
// we actually return the MBSResults array in addition to modifying it.
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "calculateDynamicMeasuresGivenCashFlows", "");
try
{
SecurityCalculator.calculateDynamicMeasuresGivenCashFlows(
lInputOptions, lOutputOptions, arrManagers,
fsiMBSDollarRoll, arrMBSResults);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return arrMBSResults;
}
// This must be called before getting partial duration cash flows. The values in the maturities array
// should be in months.
public void applyPartialDurationYCShocksToIRTree (
double[] arrYCMaturitiesToShock,
double dShockMagnitude)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "applyPartialDurationYCShocksToIRTree", "");
try
{
if (arrYCMaturitiesToShock.length < 2)
{
throw new RuntimeException(
"The yield curve must have at least two shocks for partial duration calculation.");
}
SecurityCalculator.applyPartialDurationYCShocksToIRTree(
arrYCMaturitiesToShock, dShockMagnitude);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
}
// see com.fsillc.natif.release5.SecurityCalculator.java for documentation.
public double[] calculatePartialDurationGivenCashFlows (
double dPrice,
double dOAS,
CFSIPartialDurationCashFlowMatrixManager[] arrManagers)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "calculatePartialDurationGivenCashFlows", "");
double[] arrPD = null;
try
{
arrPD = SecurityCalculator.calculatePartialDurationGivenCashFlows(
dPrice, dOAS, arrManagers);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return arrPD;
}
public double calculateAverageLifeEquivPrepaymentSpeed (
double[] prepaySpeedsInSMM,
int nMonths,
double dWAC,
int nOrigTerm,
int nAge,
int iWAM,
CFSIPrepaySpeedUnit nOutputAvgPrepaySpeedTypeFlag)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "calculateAverageLifeEquivPrepaymentSpeed", "");
double dSpeed = 0.0D;
try
{
dSpeed = newMBSCalculator.calculateAverageLifeEquivPrepaymentSpeed(
prepaySpeedsInSMM, nMonths, dWAC, nOrigTerm, nAge,
iWAM, nOutputAvgPrepaySpeedTypeFlag.intValue());
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return dSpeed;
}
public IFSITotalReturnResults calculateTotalReturnGivenCashFlows (
IFSITotalReturnInput fsiTotalReturnInput,
IFSITotalReturnResults fsiTotalReturnResults,
long lOutputOptions,
CFSITotalReturnCashFlowMatrixManager[] arrManagers)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "calculateTotalReturnGivenCashFlows", "");
try
{
SecurityCalculator.calculateTotalReturnGivenCashFlows(
fsiTotalReturnInput, fsiTotalReturnResults,
lOutputOptions, arrManagers);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return fsiTotalReturnResults;
}
public IFSIPrepayLoanLevelDescription retrieveDefaultLoanLevelParameters (
IFSIPrepayLoanLevelDescription fsiLevel,
String strPrepayModelPath,
String strAgency,
int nOrigTerm,
int nIf0IsFixedIf1IsArm)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "retrieveDefaultLoanLevelParameters", strAgency);
IFSIPrepayLoanLevelDescription fsiDes = null;
try
{
fsiDes = newMBSCalculator.retrieveDefaultLoanLevelParameters(
fsiLevel, strPrepayModelPath,
strAgency, nOrigTerm, nIf0IsFixedIf1IsArm);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return fsiDes;
}
public double[] smmToCpr (double[] arrSMMs)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "smmToCpr", "");
double[] arrCPRs = null;
try
{
arrCPRs = newMBSCalculator.smmToCpr(arrSMMs);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return arrCPRs;
}
public long getTTRCashFlowTypes (IFSITotalReturnInput fsiInput,
long lFlagsAtHorizon)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "getTTRCashFlowTypes", "");
long lTypes = 0L;
try
{
lTypes = newMBSCalculator.getTTRCashFlowTypes(fsiInput,
lFlagsAtHorizon);
}
finally
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return lTypes;
}
public boolean detectManagerHeartBeat() throws RemoteException {
// Bigegg - This method will be called inside the JNDI server's cleanup
// thread. It tries to detect the manager heart beat and returns true
// if succeeds.
m_oLogger.debug("in Calculator.detectManagerHeartBeat()");
// We will give it three tries.
for (int i = 0; i < 3; i++) {
try {
if (getManagerHeartBeat().healthDetect())
return true;
}
catch (Exception e) {
m_oLogger.debug("Couldn't detect the manager heart beat, will retry", e);
}
// Sleep for 500 mili-seconds
try {
Thread.sleep(500);
}
catch (InterruptedException e) {
// ignored
}
}
m_oLogger.warn("Manager seems dead, this Calculator will be destroyed soon");
return false;
}
public void updateAvailability ()
throws RemoteException
{
// Bigegg - This method is only called inside the JNDI server, so we don't
// call the update JNDI status here.
m_oLogger.debug("in Calculator.updateAvailability()");
// Shane - If the GUI crashes, all the calculator it uses will not be set to
// be available. When the GUI retrieves a calculator, it sends a "heart beat"
// to the calculator which is cached in m_fsiFSIHeartBeat.
// When setAvailable() is called, m_fsiFSIHeartBeat is set to null.
// If the GUI crasehs, when the cleanup pool thread invokes this method,
// all the calculators will have their availability status updated correctly.
// Bigegg on 2005/06/11
// This method will only called by FSINamingServer cleanup thread
if (isLocked())
{
m_oLogger.debug("The Calculator is locked by GUI, going to detect the GUI's availability");
// We will detect the locking GUI still there
// We will give it more than one chances
for (int i = 0; i < 3; i++)
{
try
{
if (getGUIHeartBeat().healthDetect())
{
m_oLogger.debug("GUI's heart beat is responding");
return;
}
}
catch (Exception ex)
{
// ignored
m_oLogger.warn("GUI failed to respond");
}
try
{
Thread.sleep(3000);
}
catch (InterruptedException e)
{
// ignored
}
}
m_oLogger.debug("GUI heart beat doesn't respond, going to remove the lock on this Calculator");
setGUIHeartBeat(null);
}
}
public FSIHeartBeat getManagerHeartBeat ()
throws RemoteException
{
return m_fsiManagerHeartBeat;
}
public void setManagerHeartBeat (FSIHeartBeat fsiHeartBeat)
throws RemoteException
{
m_fsiManagerHeartBeat = fsiHeartBeat;
}
public void shutdown ()
throws RemoteException
{
System.exit( -1);
}
public void fakeCallForTest (long mills)
throws RemoteException
{
updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "fakeCallForTest", "");
try
{
Thread.sleep(mills);
}
catch (InterruptedException ex)
{
// ignored
}
updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
public boolean isLocked ()
{
return getGUIHeartBeat() != null;
}
public String getLockedBy ()
{
return getHostFromHeartBeat(getGUIHeartBeat());
}
//
// Private or protected helper methods
//
private void setGUIHeartBeat (FSIHeartBeat hb)
{
this.m_fsiGUIHeartBeat = hb;
}
private FSIHeartBeat getGUIHeartBeat ()
{
return m_fsiGUIHeartBeat;
}
/**
* Use the system property "os.name" to judge if the underlying
* platform is Windows or Unix
*/
private boolean isWindowsPlatform ()
{
String osName = System.getProperty("os.name");
m_oLogger.info("Constructing CalculatorImplementation for " + osName);
if (osName.indexOf("Windows") > -1)
{
return true;
}
else
{
return false;
}
}
/**
* Update the status of this Calculator to the JNDI server. This method also
* update the time of function calling, so we may possibly implementation
* a mechanism to detect those long running methods or those lost
* Calculators.
*
* @param status
* @param methodName
* @param cusip
*/
protected void updateStatusToJNDI (int status, String methodName, String cusip)
{
if (status == CalcStatus.CALC_STATUS_BUSY)
{
m_oLogger.debug("in Calculator." + methodName + "()");
}
else
{
m_oLogger.debug("About to return from the above method");
}
setTimeOfLastFunctionCall();
try
{
// Bigegg on 2005/6/8
// Now we just update the calc status to JNDI server
String lockedBy = getHostFromHeartBeat(getGUIHeartBeat());
m_oLogger.debug("updating Calc status to JNDI server: Calc Name=" + calcName +
", status=" + status + ", Method=" + methodName + ", lockedBy = " + lockedBy);
boolean isLocked = isLocked();
long lastUpdateTime = System.currentTimeMillis();
CalcStatus calcStatus = new CalcStatus(CalcStatus.NODE_TYPE_CALC,
calcName, status, methodName, cusip, lastUpdateTime,
isLocked, lockedBy, calcType);
FSINamingContext context = JNDIHelper.getFSIContext();
context.updateCalculatorStatus(calcName, this, calcStatus);
}
catch (Exception ex)
{
m_oLogger.warn("Error update this calculator status to the JNDI server", ex);
}
}
// Should be called at the beginning of every calculation function call.
// timeOfLastFunctionCall is used to determine if a calculator is no longer
// unavailable because it has expired.
private void setTimeOfLastFunctionCall ()
{
timeOfLastFunctionCall = System.currentTimeMillis();
}
protected void init ()
throws RemoteException, MBSCalculator.NoDLLException, MBSCalculatorException
{
// Bigegg - Initialize intenal calculators. These calculator implementation
// needs two path parameter in their constructors. This could probably also
// deprecated, but it involves some native methods. I will confirm with Shane
// to remove them from the constructors.
mbsCalculator = new MBSCalculator("", "");
newMBSCalculator = new NewMBSCalculator("", "");
bondCalculator = new BondCalculator("mbsc");
derivativeCalculator = new DerivativeCalculator();
try
{
getMarketData = new GetMarketData();
}
catch (Exception e)
{
getMarketData = null;
}
strScenarioInitializationId = "";
try
{
strHostName = InetAddress.getLocalHost().getHostName().toLowerCase();
}
catch (UnknownHostException e)
{
strHostName = "";
}
}
private String getHostFromHeartBeat (FSIHeartBeat hb)
{
if (hb == null)
{
return "";
}
try
{
return hb.getHostname();
}
catch (Exception ex)
{
m_oLogger.warn("Wrong heart beat", ex);
return "";
}
}
/**
* @param prepayModelPath
* @param cmoDataVendorPath
* @throws RemoteException
* @throws NoDLLException
* @throws MBSCalculatorException
*/
private void internalResetPaths (String prepayModelPath, String cmoDataVendorPath)
throws RemoteException, NoDLLException, MBSCalculatorException
{
checkCMOPaths(cmoDataVendorPath);
checkPrepayModelPath(prepayModelPath);
mbsCalculator.resetPaths(prepayModelPath, cmoDataVendorPath);
}
private void checkCMOPaths (String sCMOPaths)
throws RemoteException
{
String[] sPath = CalculatorUtils.extractCMOPaths(sCMOPaths);
String sCDIPath = sPath[0];
String sCDUPath = sPath[1];
m_oLogger.debug("Checking paths: " + sCDIPath + " and " + sCDUPath);
checkCMOPaths(sCDIPath, sCDUPath);
}
private void checkCMOPaths (String sCDIPath, String sCDUPath)
throws RemoteException
{
String sErrorMessage = "";
boolean blnCDIPathValid = true;
boolean blnCDUPathValid = true;
if (sCDIPath.trim().length() > 0)
{
blnCDIPathValid = isPathValid(sCDIPath);
}
if (sCDUPath.trim().length() > 0)
{
blnCDUPathValid = isPathValid(sCDUPath);
}
if (!blnCDIPathValid && !blnCDUPathValid)
{
sErrorMessage = "Invalid CDI and CDU paths: '" + sCDIPath + "' and '" + sCDUPath + "'";
}
else if (!blnCDIPathValid)
{
sErrorMessage = "The path '" + sCDIPath + "' is not valid.";
}
else if (!blnCDUPathValid)
{
sErrorMessage = "The path '" + sCDUPath + "' is not valid.";
}
if (sErrorMessage.length() > 0)
{
throw new RemoteException(sErrorMessage);
}
}
private void resetPaths (IFSIMortgageBackedSecurity fsiMBS)
{
IFSISecurityDataSource dataSource = fsiMBS.getSecurityDataSource();
IFSIPrepayModelMatrix fsiMatrix = fsiMBS.getPrepayModelMatrix();
// Shane - Reset the prepay model path here also
m_oLogger.debug("The data source of this MBS is " + dataSource);
if (isWindows)
{
if (fsiMBS.getType().equals(CFSIMBSTypes.FRM_CMO) && null != dataSource)
{
fsiMBS.setCMOProviderDataDirectoryPath(
dataSource.getPath() + " " + dataSource.getPath2());
}
if (null != fsiMatrix)
{
fsiMBS.setParamsDir(fsiMatrix.getPrepayModelParameterPath());
}
m_oLogger.debug("Windows Platform, using " + fsiMBS.getCMOProviderDataDirectoryPath() +
"/n and " + fsiMBS.getParamsDir() + " for " + fsiMBS.getCusip());
}
else
{
if (null != dataSource)
{
fsiMBS.setCMOProviderDataDirectoryPath(
dataSource.getPathUnix() + " " + dataSource.getPathUnix2());
}
if (null != fsiMatrix)
{
fsiMBS.setParamsDir(fsiMatrix.getPrepayModelParameterPathUnix());
}
m_oLogger.debug("Unix Platform, using " + fsiMBS.getCMOProviderDataDirectoryPath() +
"/n and " + fsiMBS.getParamsDir() + " for " + fsiMBS.getCusip());
}
}
private void checkPrepayModelPath (String sPrepayModelPathToUse)
throws RemoteException
{
boolean blnPrepayModelPathValid = isPathValid(sPrepayModelPathToUse);
if (!blnPrepayModelPathValid ||
sPrepayModelPathToUse.trim().length() == 0)
{
String sErrorMessage = "Prepay Model Path '" + sPrepayModelPathToUse + "' is not valid.";
throw new RemoteException(sErrorMessage);
}
}
private void checkIDCPath (String sIDCPath)
throws RemoteException
{
String sErrorMessage = "";
if (sIDCPath.trim().length() == 0)
{
sErrorMessage = "IDC Path is not specified.";
}
else if (!isPathValid(sIDCPath))
{
sErrorMessage = "IDC Path '" + sIDCPath + "' is not valid.";
}
if (sErrorMessage.length() > 0)
{
throw new RemoteException(sErrorMessage);
}
}
private boolean isPathValid (String sPath)
{
return!CalculatorUtils.pathInvalid(sPath);
}
}
在每个计算业务方法开始都有updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY, "setScenarioInitializationId", "");和结尾都有 updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
这样的代码。而且这个类中的计算业务方法非常多,我不清楚作者copy paste这些updateStatusToJNDI是否感觉到累。而且我们应该把业务方法和这些updateStatusToJNDI方法的关注点分离(aop的概念)。我决定把这个类进行refactor。
而且我觉得使用java的动态代理进行refactor比较好,不用引入其他第三方包。
下面是我的最终结果。Calculator是计算类的接口。
/*
* Created on 2005-7-5
*/
package com.fsillc.remote.server;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.fsillc.remote.interfaces.Calculator;
import com.fsillc.remote.util.CalcStatus;
/**
* This class is use for update the calculator's status.
*
*
* @author deng.yin(邓胤)
*/
public class CalculatorProxy implements InvocationHandler {
private Object calculator;
private CalculatorProxy(Object calculator){
this.calculator = calculator;
}
private static Calculator getProxyInstance(Object calculator){
return (Calculator) Proxy.newProxyInstance(calculator.getClass().getClassLoader(),calculator.getClass().getInterfaces(),new CalculatorProxy(calculator));
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object returnObject = null;
CalculatorImplementation calc = (CalculatorImplementation) calculator;
try{
// before calculation, change the calculator's status to busy
calc.updateStatusToJNDI(CalcStatus.CALC_STATUS_BUSY,method.getName(),"");
returnObject = method.invoke(calculator,args);
}finally{
//whenever the calculation successfully, change the calculator's status to idle
calc.updateStatusToJNDI(CalcStatus.CALC_STATUS_IDLE, "", "");
}
return returnObject;
}
}