public static void RunRisk()
        {
            dynamic xlApp;

            xlApp = ExcelDnaUtil.Application;

            // read loan data
            double Balance    = (double)(xlApp.Range["Balance"].Value2);
            double Rate       = (double)(xlApp.Range["Rate"].Value2);
            double Spread     = (double)(xlApp.Range["Spread"].Value2);
            int    Maturity   = (int)(xlApp.Range["Maturity"].Value2);
            int    Resetting  = (int)(xlApp.Range["ReSetting"].Value2);
            string FixedOrARM = (string)(xlApp.Range["LoanType"].Value2);
            string PIOrIO     = (string)(xlApp.Range["RepaymentType"].Value2);

            Debug.Assert(Maturity <= GlobalVar.GlobalMaxMortgageLoanMaturity, "Mortgage Loan Maturity should not be greater than " + GlobalVar.GlobalMaxMortgageLoanMaturity);

            // Libor Curve
            double[] Libor_Curve = ExcelCasting.myArray <double>(xlApp.Range["LiborCurve"].Value2);
            int      len         = Libor_Curve.Length;

            Debug.Assert(len <= GlobalVar.GlobalMaxMortgageLoanMaturity, "Libor Curve should be EXACTLY of 360 data points" + GlobalVar.GlobalMaxMortgageLoanMaturity);
            LiborRates libor_rates = new LiborRates(Libor_Curve);

            // Build the loan
            IRepayment    rmPI = RepaymentFactory.GetRep(PIOrIO);
            IMortgageLoan loan = MortgageLoanFactory.GetLoan(FixedOrARM, Balance, Maturity, Rate, Resetting, Spread, libor_rates, rmPI);

            loan.CashFlows();

            // Write into excel
            xlApp = ExcelDnaUtil.Application;
            try
            {
                dynamic range = xlApp.Range["BegBalanceOutput"];
                range.Value = ExcelCasting.toColumnVect(loan.Write(loan.ReturnBegBalance()));

                range       = xlApp.Range["InterestOutput"];
                range.Value = ExcelCasting.toColumnVect(loan.Write(loan.ReturnInterest()));

                range       = xlApp.Range["PrincipalOutput"];
                range.Value = ExcelCasting.toColumnVect(loan.Write(loan.ReturnPrincipal()));

                range       = xlApp.Range["CashCollectionsOutput"];
                range.Value = ExcelCasting.toColumnVect(loan.Write(loan.ReturnCashCollections()));

                range       = xlApp.Range["EndBalanceOutput"];
                range.Value = ExcelCasting.toColumnVect(loan.Write(loan.ReturnEndBalance()));
            }

            catch (Exception e)
            {
                MessageBox.Show("Error:  " + e.ToString());
            }
        }
        public static object[,] LoanAmortisation(
            [ExcelArgument(Description = @"Balance Notional")] double Balance,
            [ExcelArgument(Description = @"Loan Rate")] double Rate,
            [ExcelArgument(Description = @"Loan Spread, Zero if It is a Fixed Rate Loan")]   double Spread,
            [ExcelArgument(Description = @"Maturity Period")] int Maturity,
            [ExcelArgument(Description = @"Rate Resetting Period, the same as Maturity if it is a Fixed Rate Loan")] int Resetting,
            [ExcelArgument(Description = @"Fixed (Fixed) or ARM (ARM)")] string FixedOrARM,
            [ExcelArgument(Description = @"Principal and Interest (PI) or Interest Only (IO)")] string PIOrIO,
            [ExcelArgument(Description = @"Libor Curve as an array")] double[] Libor_Curve)
        {
            // check Loan Maturity
            Debug.Assert(Maturity <= GlobalVar.GlobalMaxMortgageLoanMaturity, "Mortgage Loan Maturity should not be greater than " + GlobalVar.GlobalMaxMortgageLoanMaturity);

            // Libor Curve
            LiborRates libor_rates = new LiborRates(Libor_Curve);
            int        len         = Libor_Curve.Length;

            Debug.Assert(len <= GlobalVar.GlobalMaxMortgageLoanMaturity, "Libor Curve should be EXACTLY of 360 data points" + GlobalVar.GlobalMaxMortgageLoanMaturity);

            // Build the loan
            IRepayment    rmPI = RepaymentFactory.GetRep(PIOrIO);
            IMortgageLoan loan = MortgageLoanFactory.GetLoan(FixedOrARM, Balance, Maturity, Rate, Resetting, Spread, libor_rates, rmPI);

            loan.CashFlows();

            double[] BegBal      = loan.Write(loan.ReturnBegBalance());
            double[] Interest    = loan.Write(loan.ReturnInterest());
            double[] Principal   = loan.Write(loan.ReturnPrincipal());
            double[] Collections = loan.Write(loan.ReturnCashCollections());
            double[] EndBal      = loan.Write(loan.ReturnEndBalance());

            object[,] a = new object[MBSExcelDNA.Global.GlobalVar.GlobalMaxMortgageLoanMaturity, 5];
            for (int i = 0; i < (int)MBSExcelDNA.Global.GlobalVar.GlobalMaxMortgageLoanMaturity; i++)
            {
                a[i, 0] = BegBal[i];
                a[i, 1] = Interest[i];
                a[i, 2] = Principal[i];
                a[i, 3] = Collections[i];
                a[i, 4] = EndBal[i];
            }
            return(a);
        }
        private static IMortgageLoan construct_loan(double Balance, double Rate, double Spread, int Maturity, int Resetting, string FixedOrARM, string PIOrIO, string Libor_Name)
        {
            LiborRates LiborRate;

            GlobalCache.TryGetObject <LiborRates>(Libor_Name, out LiborRate);

            IMortgageLoan loan = null;

            try
            {
                // Build the loan
                IRepayment rmPI = RepaymentFactory.GetRep(PIOrIO);
                loan = MortgageLoanFactory.GetLoan(FixedOrARM, Balance, Maturity, Rate, Resetting, Spread, LiborRate, rmPI);
            }
            catch (Exception ex)
            {
                lock (m_sync)
                {
                    LogDisplay.WriteLine("Error: " + ex.ToString());
                }
            }
            return(loan);
        }