Debt Service Coverage Ratio (DSCR)
The debt_service_coverage_ratio
function calculates the Debt Service Coverage Ratio (DSCR), a key financial metric used to assess a borrower's ability to repay debt. This ratio is widely used in commercial real estate lending, corporate finance, and credit risk assessment.
Usage in Pypulate
from pypulate.credit import debt_service_coverage_ratio
# Calculate DSCR
result = debt_service_coverage_ratio(
net_operating_income=500000, # $500,000 net operating income
total_debt_service=300000 # $300,000 total debt service
)
# Access the results
dscr = result["dscr"]
assessment = result["assessment"]
rating = result["rating"]
Parameters
Parameter | Type | Description | Default |
---|---|---|---|
net_operating_income |
float | Net operating income of the borrower | Required |
total_debt_service |
float | Total debt service obligations (principal, interest, lease payments, etc.) | Required |
Return Value
The function returns a dictionary with the following keys:
Key | Type | Description |
---|---|---|
dscr |
float | The calculated Debt Service Coverage Ratio |
assessment |
str | Text description of the risk level |
rating |
str | Categorical rating ("Poor", "Fair", "Good", or "Excellent") |
Risk Level Classification
The DSCR is categorized into risk levels:
DSCR Range | Risk Level |
---|---|
< 1.0 | Poor |
1.0 - 1.25 | Fair |
1.25 - 1.5 | Good |
> 1.5 | Excellent |
Comprehensive Example
Here's a complete example demonstrating how to calculate and analyze DSCR for different borrowers:
from pypulate.credit import debt_service_coverage_ratio
import matplotlib.pyplot as plt
import numpy as np
# Example 1: Strong borrower with high income relative to debt
strong_borrower = debt_service_coverage_ratio(
net_operating_income=800000, # $800,000 net operating income
total_debt_service=400000 # $400,000 total debt service
)
# Example 2: Average borrower with moderate coverage
average_borrower = debt_service_coverage_ratio(
net_operating_income=450000, # $450,000 net operating income
total_debt_service=350000 # $350,000 total debt service
)
# Example 3: Weak borrower with insufficient coverage
weak_borrower = debt_service_coverage_ratio(
net_operating_income=280000, # $280,000 net operating income
total_debt_service=300000 # $300,000 total debt service
)
# Print the results
print("Debt Service Coverage Ratio Analysis")
print("===================================")
print("\nExample 1: Strong Borrower")
print(f"DSCR: {strong_borrower['dscr']:.2f}")
print(f"Assessment: {strong_borrower['assessment']}")
print(f"Rating: {strong_borrower['rating']}")
print("\nExample 2: Average Borrower")
print(f"DSCR: {average_borrower['dscr']:.2f}")
print(f"Assessment: {average_borrower['assessment']}")
print(f"Rating: {average_borrower['rating']}")
print("\nExample 3: Weak Borrower")
print(f"DSCR: {weak_borrower['dscr']:.2f}")
print(f"Assessment: {weak_borrower['assessment']}")
print(f"Rating: {weak_borrower['rating']}")
# Visualize the results
borrowers = ['Weak', 'Average', 'Strong']
dscr_values = [
weak_borrower['dscr'],
average_borrower['dscr'],
strong_borrower['dscr']
]
# Create a bar chart
plt.figure(figsize=(10, 6))
bars = plt.bar(borrowers, dscr_values, color=['red', 'orange', 'green'])
# Add horizontal lines for the DSCR thresholds
plt.axhline(y=1.0, color='r', linestyle='--', label='Poor/Fair Threshold (1.0)')
plt.axhline(y=1.25, color='orange', linestyle='--', label='Fair/Good Threshold (1.25)')
plt.axhline(y=1.5, color='g', linestyle='--', label='Good/Excellent Threshold (1.5)')
# Add labels and title
plt.ylabel('Debt Service Coverage Ratio')
plt.title('DSCR Comparison')
plt.ylim(bottom=0) # Start y-axis at 0
# Add the DSCR values on top of the bars
for bar in bars:
height = bar.get_height()
plt.text(bar.get_x() + bar.get_width()/2., height + 0.05,
f'{height:.2f}', ha='center', va='bottom')
plt.legend()
plt.tight_layout()
plt.show()
# Create a sensitivity analysis
income_values = np.linspace(200000, 1000000, 100) # Range of income values
debt_service = 400000 # Fixed debt service
dscr_values = [income / debt_service for income in income_values]
ratings = []
for dscr in dscr_values:
if dscr < 1.0:
ratings.append("Poor")
elif dscr < 1.25:
ratings.append("Fair")
elif dscr < 1.5:
ratings.append("Good")
else:
ratings.append("Excellent")
# Create a plot showing how DSCR changes with income
plt.figure(figsize=(12, 6))
# Plot DSCR curve
plt.plot(income_values, dscr_values, 'b-', linewidth=2)
# Add colored regions for different ratings
poor_indices = [i for i, r in enumerate(ratings) if r == "Poor"]
fair_indices = [i for i, r in enumerate(ratings) if r == "Fair"]
good_indices = [i for i, r in enumerate(ratings) if r == "Good"]
excellent_indices = [i for i, r in enumerate(ratings) if r == "Excellent"]
if poor_indices:
plt.fill_between(income_values[min(poor_indices):max(poor_indices)+1],
0, dscr_values[min(poor_indices):max(poor_indices)+1],
color='red', alpha=0.3, label='Poor')
if fair_indices:
plt.fill_between(income_values[min(fair_indices):max(fair_indices)+1],
0, dscr_values[min(fair_indices):max(fair_indices)+1],
color='orange', alpha=0.3, label='Fair')
if good_indices:
plt.fill_between(income_values[min(good_indices):max(good_indices)+1],
0, dscr_values[min(good_indices):max(good_indices)+1],
color='yellow', alpha=0.3, label='Good')
if excellent_indices:
plt.fill_between(income_values[min(excellent_indices):max(excellent_indices)+1],
0, dscr_values[min(excellent_indices):max(excellent_indices)+1],
color='green', alpha=0.3, label='Excellent')
# Add horizontal lines for the DSCR thresholds
plt.axhline(y=1.0, color='r', linestyle='--')
plt.axhline(y=1.25, color='orange', linestyle='--')
plt.axhline(y=1.5, color='g', linestyle='--')
# Add labels and title
plt.xlabel('Net Operating Income ($)')
plt.ylabel('Debt Service Coverage Ratio')
plt.title('DSCR Sensitivity to Income (Fixed Debt Service: $400,000)')
plt.grid(True, linestyle='--', alpha=0.7)
plt.legend()
plt.tight_layout()
plt.show()
Example Output
Debt Service Coverage Ratio Analysis
===================================
Example 1: Strong Borrower
DSCR: 2.00
Assessment: Strong coverage, low risk
Rating: Excellent
Example 2: Average Borrower
DSCR: 1.29
Assessment: Sufficient coverage, acceptable risk
Rating: Good
Example 3: Weak Borrower
DSCR: 0.93
Assessment: Negative cash flow, high risk
Rating: Poor
Visualizations
DSCR Comparison
This visualization shows the DSCR values for three example borrowers, with horizontal lines indicating the threshold values that separate the rating categories.
DSCR Sensitivity Analysis
This visualization demonstrates how the DSCR changes with varying levels of net operating income while keeping debt service constant, highlighting the income thresholds for different rating categories.
Practical Applications
The DSCR can be used for:
- Commercial Real Estate Lending: Evaluating property cash flow relative to debt obligations
- Corporate Credit Analysis: Assessing a company's ability to service its debt
- Project Finance: Determining the financial viability of infrastructure projects
- Small Business Lending: Evaluating loan applications from small businesses
- Risk-Based Pricing: Setting interest rates based on the borrower's repayment capacity
Industry Standards
Different lenders and industries may use slightly different DSCR thresholds:
-
Commercial Real Estate:
- Typically requires DSCR ≥ 1.25
- Premium properties may require DSCR ≥ 1.5
- Riskier properties may accept DSCR ≥ 1.15
-
Corporate Lending:
- Investment grade: DSCR ≥ 1.5
- Non-investment grade: DSCR ≥ 1.2
- Distressed: DSCR < 1.0
-
Small Business Administration (SBA):
- Generally requires DSCR ≥ 1.15
- May consider global DSCR including owner's personal income
Best Practices
- Historical Analysis: Calculate DSCR using historical data to establish trends
- Stress Testing: Test DSCR under adverse scenarios (e.g., reduced income, increased interest rates)
- Industry Comparison: Compare DSCR to industry benchmarks
- Global DSCR: Consider all sources of income and all debt obligations
- Forward-Looking: Project future DSCR based on expected changes in income and debt