Quote of the Day

more Quotes

Categories

Buy me a coffee

  • Home>
  • C#>

Analyzing a rental property through automation

Published December 31, 2022 in .NET , C# - 0 Comments

In this post, I write about building an API to help me analyze real estate properties.

One of the best ways to build passive incomes is through investing in real estate. I have read a few books on real estate investing and bought my first rental property back in 2020. Before buying a property, a prudent investor may want to analyze the property by figuring out the rental income, expenses, cash flow, cash on cash return, net operating income, cap rate etc. If you are not familiar with these concepts and want to learn more, I suggest reading The Book On Rental Property Investing.

Knowing the metrics give the investor an idea of how the property performs when compared to another property. The more properties an investor analyze, the higher chance the investor can land on a good deal. For instance, with the cash flow metric, you can have an idea of whether a property can produce positive income, or it will cost money as you have to pay additional to cover all the expenses. To calculate cash flow, you need to have an idea of the expenses and incomes. While it’s not possible to know the exact costs of the expenses, you can make an educated guess by estimating the common expenses such as insurance, mortgage, tax as well as costs for repairs, vacancy, and capital expenditures. For the incomes, you can estimate how much rent the property can produce. One way is to use Zillow Rent Estimator website, which automatically looks at the rental prices of properties similar to the targeted property and let you know the range of rental prices for the property. Other metrics require just simple calculations, nothing much beyond algebra, as shown in the code snippets below.

   public static double CalculateNetOperatingIncome(IDictionary<string, double> incomes, IDictionary<string, double> expenses)
        {
            // NOI = The profit you’ve received in a year, excluding your mortgage payment. 
            var totalMonthlyExpenseExcludingMortgage =
                expenses.Where(keyValuePair => keyValuePair.Key != Enum.GetName(CommonExpenseType.Mortgage)).Sum(keyValuePair => keyValuePair.Value);
            var totalMonthlyIncome = incomes.Sum(keyValuePair => keyValuePair.Value);
            return (totalMonthlyIncome * 12) - (totalMonthlyExpenseExcludingMortgage * 12);
        }

        /// <summary>
        /// Calculate the cap rate of an investment, given the property cash 
        /// price and monthly incomes. 
        /// Cap Rate: The percentage, or the return in investment you would 
        /// get if you pay all cash and have no mortgage. 
        /// Notes from the Multifamily Millionaire book: 
        /// "Cap rate is the rate of return an investor would buy the property 
        /// at, not considering the mortgage payment”.
        /// Ex: Let's say you purchase property at 4500000 (4.5 millions). 
        /// Let’s say we pay 4.5 millions in cash. And we make 450,000 profit 
        /// annually, then cap rate = 450,000/4500000 *100 = 10%

        /// </summary>
        /// <param name="propertyPrice">The cash price at which we purchase the property</param>
        /// <param name="monthlyIncomes">The incomes we receive monthly from the property</param>
        /// <returns></returns>
        public static double CalculateCapRate(double propertyPrice, IDictionary<string, double> monthlyIncomes)
        {
            double totalYearlyIncome = monthlyIncomes.Sum(keyValuePair => keyValuePair.Value) * 12;
            return totalYearlyIncome / propertyPrice * 100;
        }

        /// <summary>
        /// Calculate the Debt Service Coverage Ratio (DBCR) of an investment. 
        /// Notes from the Multifamily Millionaire book: 
        /// DBCR: Total debt payment includes mortgage and interest. 
        /// Banks want the DSCR to be at least 1.2. 
        /// Ex: Property brings $1 MIL in income, expenses total 400,000.
        /// Then, NOI = $600k. If total annual debt payment is $500k, then
        /// DSCR = NOI / Annual debt payment = 600k / 500k = 1.2 

        /// </summary>
        /// <param name="monthlyIncomes"></param>
        /// <param name="monthlyExpenses"></param>
        /// <returns></returns>
        public static double CalculateDebtServiceCoverageRatio(IDictionary<string, double> monthlyIncomes, IDictionary<string, double> monthlyExpenses)
        {
            double annualDebtPayment = monthlyExpenses.Where(keyValuePair => keyValuePair.Key == nameof(CommonExpenseType.Mortgage)).FirstOrDefault().Value * 12;

            return CalculateNetOperatingIncome(monthlyIncomes, monthlyExpenses) / annualDebtPayment;
        }

        /// <summary>
        /// Calculate the monthly amount of cash remaining after all expenses.
        /// Notes from the Multifamily Millionaire book: 
        /// Income is the monthly income you receive every month. Typically, 
        /// this will be rental income. But it can be also other incomes.For 
        /// example, you may have laundry machines that operates by coin and 
        /// receive income from it.
        /// Expense includes cost of repair, maintenance, management fee, 
        /// insurance, mortage etc...
        /// Cash flow = Incomes - Expenses
        /// </summary>
        /// <param name="incomes"></param>
        /// <param name="expenses"></param>
        /// <returns></returns>
        public static double CalculateCashFlow(IDictionary<string, double> incomes,
            IDictionary<string, double> expenses)
        {
            return incomes.Sum(keyValue => keyValue.Value) - expenses.Sum(keyValue => keyValue.Value);
        }

        /// <summary>
        /// Notes from the Multifamily Millionaire book: 
        /// The cash-on-cash return on investment (often abbreviated as CoCROI)
        /// is a simple metric that tells us what kind of yield our money is
        /// making us based only on the cash flow(ignoring appreciation, tax
        /// benefits, and the loan pay down). The CoCROI is nice because it 
        /// allows us to compare this investment against other investments, 
        /// like the stock market or mutual funds."
        /// "CoCROI is simply the ratio between how much cash flow we received 
        /// over a one-year period and how much money we invested."
        /// Annual Cash Flow = Total income - Total expenses
        /// Total investment is the total money you put out of pocket to 
        /// purchase the deal. 

        /// </summary>
        /// <param name="monthlyIncomes"></param>
        /// <param name="monthlyExpenses"></param>
        /// <param name="totalInvestment"></param>
        /// <returns></returns>
        public static double CalculateCashOnCashReturn(
            IDictionary<string, double> monthlyIncomes, IDictionary<string, double> monthlyExpenses, double totalInvestment)
        {
            return CalculateCashFlow(monthlyIncomes, monthlyExpenses) * 12 / totalInvestment * 100;
        }

For the calculations, I make a few estimations based on the type of property and where I want to invest. For example, in California, I estimate tax to be 1.25% of the purchase price and insurance to be about 0.25% of the purchase price. Similarly, I set predefined costs for repairs, capital expenditures, vacancies based on other characteristics of the property such as the number of beds, number of baths, year built, property condition etc. and personal preferences. Below snippets show the values I preset in the app for the calculations.

  "App": {
    "DefaultDownPaymentPercent": 25,
    "DefaultClosingCostOnBuy": 15000,
    "DefaultClosingCostOnSell": 15000,
    "DefaultAgentFeesPercentageOfSellingPrice": 6,
    "DefaultTaxPercentageOnSell": 15,
    "DefaultRepairCostOnSell": 5000,
    "DefaultYearlyPercentageIncreaseInPropertyValue": 4,
    "BaseMiscExpenseMonthlyAmount": 100,
    "BaseRepairMonthlyAmount": 110,
    "BaseCapExPercentOfPropertyValue": 0.20,
    "BaseHomeOwnerInsurancePercentageOfPropertyValue": 0.25,
    "BasePropertyManagementCostAsPercentageOfMonthlyRent": 5.00
  }

One hurdle I face is retrieving info about an active listing as I could not find a public API that exposes such information. Zillow does provide such API. However, using the API requires certain criteria, which I don’t meet. Fortunately, it’s not too hard to scrape the info from Zillow website using HTML Agility Pack library and some regular expressions. For more info on how to use the tool for web scraping, checkout my previous post.

For interest rate, I leverage the API from consumer finance, as shown in the below code snippet:

 public async Task<RateCheckerResponse?> CheckRate(RateCheckerRequestInfo request)
        {
            var queryParameters = new Dictionary<string, string?>()
            {
                ["loan_amount"] = request.LoanAmount.ToString(),
                ["state"] = request.State.ToString(),
                ["loan_type"] = request.LoanType,
                ["minfico"] = request.MinFico.ToString(),
                ["maxfico"] = request.MaxFico.ToString(),
                ["rate_structure"] = request.RateStructure,
                ["loan_term"] = request.LoanTerm.ToString(),
                ["price"] = request.Price.ToString()
            };
            var uri = QueryHelpers.AddQueryString("https://www.consumerfinance.gov/oah-api/rates/rate-checker", queryParameters);
            var response = await _httpClient.GetFromJsonAsync<RateCheckerResponse>(uri);
            return response;
        }

Below shows an example of sending a request to the API to analyze a property, given the address on Zillow.

curl -X 'GET' \
  'https://localhost:44386/PropertiesAnalyzer/address?address=402-redacted' \
  -H 'accept: text/plain'

Below shows the response from the API:

{
  "incomes": {
    "Rental": "3200.00"
  },
  "expenses": {
    "Mortgage": "3609.75",
    "PropertyTax": "708.33",
    "HomeOwnerInsurance": "141.67",
    "CapitalExpenditures": "210.33",
    "Repairs": "207.00",
    "PropertyManagement": "160.00",
    "Misc": "100.00"
  },
  "totalExpense": "5137.08",
  "totalIncome": "3200.00",
  "interestRate": "7.63",
  "listingDetail": {
    "listingPrice": "680000.00",
    "numOfBedrooms": 3,
    "numOfBathrooms": 1,
    "numOfStories": 1,
    "numOfLevels": "One",
    "numOfParkingSpaces": 1,
    "lotSize": "6,250 sqft",
    "numOfGarageSpaces": 1,
    "homeType": "SingleFamily",
    "propertyCondition": null,
    "yearBuilt": 1925,
    "hasHOA": false,
    "hoaFee": "0.00",
    "propertyAge": 97
  },
  "netOperatingIncome": "20072.00",
  "capRate": "5.65",
  "debtServiceCoverageRatio": "0.46",
  "cashOnCashReturn": "-12.56",
  "cashFlow": "-1937.08",
  "assumedDownPaymentPercent": "25.00",
  "assumedClosingCost": "15000.00",
  "assumedOutOfPocketCosts": {
    "DownPayment": "170000.00",
    "ClosingCost": "15000.00"
  }
}

One thing I want to know is how much money I can make or loss if I hold the property for a number of years and then sell. For instance, in expensive neighborhoods, it’s pretty much not possible to get positive cash flow because the rental income is not enough to cover all the expenses. Therefore, I may lose money in the short term. However, the value of a property tends to appreciate over time. Therefore, I may still make money if I hold the property long enough. I can figure out how much money I make or loss by calculating the value of the property, assuming the property appreciates a certain percentage every year, and the amount of equity I would have had at the time of selling. Knowing the info aids in the decision of whether to buy the property for long term investment, even if I don’t make anything in the short term.

curl -X 'GET' \
  'https://localhost:44386/FuturePropertyAnalyzer?address=402-redacted&numOfYearsHold=10' \
  -H 'accept: text/plain'

Below shows the response from the API:

{
  "totalAmountAfterHoldWithoutCashFlow": "275381.40",
  "totalAmountAfterHoldWithCashFlow": "42931.62",
  "estimatedMonthlyCashflow": "-1937.08",
  "analyzerInputs": {
    "estimatedMonthlyCashflow": "-1937.08",
    "downPaymentAmount": "170000.00",
    "originalLoanAmount": "510000.00",
    "originalPurchaseAmount": "680000.00",
    "holdingPeriodInYears": 10,
    "interestRate": "7.63",
    "loanProgram": 0
  },
  "analyzerConfigs": {
    "estimatedClosingCostOnSell": "15000.00",
    "estimatedRepairCostOnSell": "5000.00",
    "estimatedAgentFeesPercentageOfSellingPrice": "6.00",
    "downPaymentPercentage": "25.00",
    "estimatedYearlyIncreaseInPropertyValue": "4.00"
  },
  "amountPerMonthWithoutCashFlow": "2294.84",
  "amountPerMonthWithCashFlow": "357.76"
}

As you can see, the math involved in the calculation is straightforward, but doing the analysis manually can take time because you have to look up info about the property, interest rate and do the calculation for each of the metrics you are interested. The more properties you look at, the more time it takes. With the API, I can analyze properties more efficiently. Right now, I only design the API for my own uses. Depending on time and priorities, I may make the API more generic so that it can help other investors as well. For instance, I can have users create accounts which allow them to set predefined values such that the calculations would be personalized based on their preferences.

If you are interested in learning more, or have other feedback, please let me know.

References

Html Agility Pack (html-agility-pack.net)

The Book On Rental Property Investing

Zillow Rent Estimate Calculator | Zillow Rental Manager

Rate Checker API

No comments yet