I'm pitching the owner of Takoma Towers (6733 New Hampshire Ave, Takoma Park, MD) on refinancing with Walker & Dunlop. They bought it in January 2020, so their acquisition debt is approaching maturity. Build a financing pitch I can send them. Include: a one-page summary of the property and why it's financeable; how it performs against its submarket on occupancy, retention, days on market and in-place rent by bedroom; who the residents are (income and credit, and how both are trending); a sized agency refinance comparing Fannie Mae and Freddie Mac 7- and 10-year fixed executions at current quotes, showing proceeds, rate, DSCR, debt yield and the binding constraint for each; and the questions a Fannie or Freddie underwriter will raise, with how we'd answer each. Use RealAI's modeled P&L as the operating basis and say so. Confirm whether the property falls under Takoma Park or Prince George's County rent stabilization, and reflect that in the rent growth assumption.
cd scratch/inputs/agents/01a087be-a40c-70fb-88a9-40a61b0703c2/ && wc -c *.md && cat RealAI_Credit_Underwriting_Template_manifest_v5.md
mkdir -p extracts subagents/workbooks && cat > extracts/takoma_inputs.json <<'EOF'
{
"property": {"id":"8630100d6e84aeb75924e0d64d3bf290","name":"Takoma Towers","address":"6733 New Hampshire Ave","city_state_zip":"Takoma Park, MD 20912","units":468,"rentable_sf":369252,"year_built":1969,"year_renovated":2014,"stories":13,"buildings":3,"acres":9.66,"occupancy_latest":0.9829,"last_sale_date":"2020-01-27","last_sale_price":85000000,"fee_owner":"TAKOMA TOWERS APTS LLC","county":"Prince George's County (24033)","census_place":"Chillum CDP","submarket":"Chillum/Queens Chapel"},
"realai_modeled_pnl_annual": {"gross_potential_rent":9947570.33,"vacancy_loss":184702.52,"net_rent":9762867.82,"other_income":1542258,"effective_gross_income":11305125.81,"advertising_marketing":41224.82,"general_administrative":821662.98,"insurance":314932.55,"management_fees":351572.51,"payroll_benefits":934350.17,"repairs_maintenance":432462.1,"utilities":1661564.85,"real_estate_tax":686276.73,"total_operating_expenses":5244046.73,"net_operating_income":6061079.08,"capital_expenditures_reserve":159346.96},
"submarket": {"occupancy":0.9684,"vacancy":0.0316,"in_place_rent_avg":1777.59,"retention":0.764,"dom_median":64},
"pg_county_benchmarks": {"total_opex_pct_egi":0.5147,"capex_pct_egi":0.017,"other_income_pct_net_rent":0.0851,"sample":196},
"market_cap_rate_mf_dc_2Q26":0.0573,
"ten_year_treasury_2026_09_24":0.0518,
"quotes_2026_09_23": {
"fannie_7yr":{"80_125":0.0641,"65_135":0.0616,"55_155":0.0601},
"fannie_10yr":{"80_125":0.0638,"65_135":0.0618,"55_155":0.0603},
"freddie_7yr":{"80_125":0.0631,"65_135":0.0611,"55_155":0.0591},
"freddie_10yr":{"80_125":0.0618,"65_135":0.0606,"55_155":0.0590}
},
"rent_regulation": {"regime":"Prince George's County PRSA","cap_formula":"lesser of CPI-U+3% or 6%","allowance_2026_07_to_2027_06":0.057,"takoma_park_city_rsl_applies":false}
}
EOF
echo okGoal: size an agency refinance for Takoma Towers (468-unit, 1969 high-rise at 6733 New Hampshire Ave, Takoma Park MD 20912, Prince George's County), across FOUR fixed-rate executions: Fannie Mae 7-yr, Fannie Mae 10-yr, Freddie Mac CME 7-yr, Freddie Mac CME 10-yr. This feeds a Walker & Dunlop financing pitch to the owner. You produce four populated, recalculated workbooks plus a JSON read-back. You do NOT write the pitch.
INPUTS
xlsx skill (sandbox_skills) before touching workbooks and use its recalc.py and integrity scan.WORKBOOK RULES (MUST)
COMMON INPUTS (all four)
SCENARIOS (note rate = agency quote, full-leverage 80% LTV / 1.25x tier, as of 2026-09-23)
OUTPUT (directory subagents/workbooks/)
All four workbooks were populated, sized and recalculated with zero Excel errors and no CHECK tokens. Files, JSON and scripts are in subagents/workbooks/ (details below). The integrity scan still exits non-zero on all four, with 20 high findings each. All 20 are blank-input references, listed under Integrity scan below, which I left in place. Every figure below was read back from the recalculated workbooks (readback.json has each cell address and value).
SIZING RESULTS (identical across scenarios: lender EGI Pro Forma!G11 10,838,224; OpEx G25 5,737,779; NOI G28 5,100,445; T12 NOI E28 5,901,732; haircut G30 13.58% / $801,287; OpEx uplift G26 348,891; lender value C44 89,013,010; vacancy floor Assumptions!F31 5.0%; OpEx ratio F34 51.47%)
| Fannie 7 (6.41%) | Fannie 10 (6.38%) | Freddie 7 (6.31%) | Freddie 10 (6.18%) | |
|---|---|---|---|---|
| Supportable proceeds (Loan Sizing!C29) | 54,303,892 | 54,474,745 | 54,876,710 | 55,635,702 |
| Requested (Assumptions!F8, rounded down to $10k) | 54,300,000 | 54,470,000 | 54,870,000 | 55,630,000 |
| Binding constraint (C30) | DSCR Amortizing | DSCR Amortizing | DSCR Amortizing | DSCR Amortizing |
| Test max loans E24 DSCR amortizing / E25 DSCR IO / E26 debt yield / E27 LTV | 54.30M / 66.31M / 60.01M / 71.21M | 54.47M / 66.62M / 60.01M / 71.21M | 54.88M / 67.36M / 60.01M / 71.21M | 55.64M / 68.78M / 60.01M / 71.21M |
| DSCR (C17) / debt yield (C18) / LTV (C19) at request | 1.2501 / 9.39% / 61.0% | 1.2501 / 9.36% / 61.2% | 1.2502 / 9.30% / 61.6% | 1.2501 / 9.17% / 62.5% |
| Annual debt service (Stress & Break-Even!C17) | 4,080,064 | 4,080,001 | 4,079,857 | 4,079,938 |
| Balance at maturity (Amortization!N4) | 49,021,938 | 46,037,706 | 49,452,398 | 46,776,222 |
| Stressed refi proceeds / gap (Refi Analysis!C28 / C30) | 58.92M / +9.90M | 62.51M / +16.47M | 59.52M / +10.07M | 63.80M / +17.03M |
| Prepayment cost at month 60 (Prepayment!C70, % of balance C71) | 1,051,624 (2.07%) | 1,970,247 (3.87%) | 965,671 (1.88%) | 1,571,532 (3.03%) |
| Defeasance cost (Defeasance!C39, total including $100k costs) | 52,166,328 | 53,841,405 | 52,698,315 | 54,555,325 |
| Cheaper route (Defeasance!C47) | Prepayment - defeasance unavailable (C8: "No - no defeasance clause per note", set by instruction) | same | Prepayment (saves 481,997, C48) | Prepayment (saves 1,103,833) |
| Exit cost above par (Defeasance!C51) | 2.07% | 3.87% | 1.88% | 3.03% |
| NOI break-even (Stress & Break-Even!C18) | 4,080,064 | 4,080,001 | 4,079,857 | 4,079,938 |
| NOI cushion (C21) | 20.0% | 20.0% | 20.0% | 20.0% |
| Break-even occupancy (C23) | 84.74% | 84.74% | 84.74% | 84.74% |
| Rate × NOI grid DSCR at +100 bps / −10% NOI | 1.0165 (E10) | 1.0163 | 1.0159 | 1.0151 |
| Recovery % of par at −10 / −20 / −30% (Recovery!D14 / E14 / F14) | 96.36% at all three | 96.34% at all three | 96.29% at all three | 96.21% at all three |
| Verdict cap (Assumptions!C21) | APPROVE WITH STRUCTURE (pending guarantor review) | same | same | same |
The remaining read-back items are in readback.json for each scenario:
CHECK / FLAG tokens (Assumptions!I23:I47, I50:I53; full status list in readback.json)
Treasury curve (Assumptions/Prepayment!D27:D35, curve date C36 = 2026-09-24)
Inputs I could not set as instructed, or set beyond the brief
Integrity scan
Conflicts and oddities
Files are in subagents/workbooks/:
python3 subagents/workbooks/scripts/populate.py <Fannie7|Fannie10|Freddie7|Freddie10>)The populate script reads the template from scratch/t.xlsx, a copy of the v5 clean template. It was run per scenario with the placeholder request, recalc, C29 read, and a rounded request set before a second recalc.
mkdir -p scripts && cat > scripts/pitch_calcs.py <<'EOF'
import json
d=json.load(open('extracts/takoma_inputs.json'))
# Bedroom in-place rents: property vs submarket (datamart, as of 2026-09-26)
prop={'1BR':1516.88,'2BR':1684.38,'3BR':1960.45,'All':1771.53}
sub={'1BR':1625.62,'2BR':1890.06,'3BR':2198.76,'All':1777.59}
print("In-place rent gap vs submarket:")
for k in prop: print(f" {k}: {prop[k]:.0f} vs {sub[k]:.0f} -> {prop[k]/sub[k]-1:+.1%}")
# Lender NOI & proceeds from workbooks
noi=5100445; sized={'Fannie7':54300000,'Fannie10':54470000,'Freddie7':54870000,'Freddie10':55630000}
# Implied cap rate at which the 80% LTV test would bind for the largest loan
for k,v in sized.items():
print(f"{k}: value where 80% LTV binds = {v/0.8:,.0f}; implied cap = {noi/(v/0.8):.2%}")
for cap in (0.0573,0.0625,0.065):
val=noi/cap; print(f"cap {cap:.2%}: value {val:,.0f}; LTV on Freddie10 {sized['Freddie10']/val:.1%}; per unit {val/468:,.0f}")
# Existing acquisition debt hypotheses (price $85M, Jan-2020) - balance unknown
for ltv in (0.60,0.65,0.70,0.75):
bal=85e6*ltv
print(f"acq LTV {ltv:.0%}: loan {bal/1e6:.1f}M -> vs Freddie10 {(sized['Freddie10']-bal)/1e6:+.1f}M, vs Fannie7 {(sized['Fannie7']-bal)/1e6:+.1f}M")
# Modeled vs lender: other income share and elapsed hold
print("other income % net rent modeled", 1542258/9762867.82, "county", 0.0851)
from datetime import date
print("years since acquisition", (date(2026,9,30)-date(2020,1,27)).days/365.25)
print("7yr maturity approx", "2027-01/02")
EOF
python3 scripts/pitch_calcs.pygrep -n -i -A3 "chart\|palette\|#[0-9A-F]\{6\}" skills/docx/references/realai-formatting.md | head -80Now the pitch document.
"""Build the Takoma Towers agency refinance pitch (plain draft). Figures embedded from
datamart pulls (extracts/takoma_inputs.json) and the four recalculated sizing workbooks
(subagents/workbooks/readback.json)."""
import os
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from docx import Document
from docx.shared import Inches
from docx.enum.style import WD_STYLE_TYPE
os.makedirs("scratch", exist_ok=True)
# ---------- chart: in-place rent by bedroom ----------
beds = ["1 BR", "2 BR", "3 BR"]
prop = [1517, 1684, 1960]
sub = [1626, 1890, 2199]
fig, ax = plt.subplots(figsize=(6.25, 2.9), dpi=220)
x = range(len(beds)); w = 0.36
b1 = ax.bar([i - w/2 for i in x], prop, w, color="#F4633A", label="Takoma Towers")
b2 = ax.bar([i + w/2 for i in x], sub, w, color="#517787", label="Chillum/Queens Chapel submarket")
for bars in (b1, b2):
for r in bars:
ax.text(r.get_x() + r.get_width()/2, r.get_height() + 25, f"${r.get_height():,.0f}",
ha="center", fontsize=8, color="#151513")
ax.set_xticks(list(x)); ax.set_xticklabels(beds, color="#565249")
ax.set_ylim(0, 2500); ax.yaxis.grid(True, color="#CBCAC6", linewidth=0.6); ax.set_axisbelow(True)
ax.tick_params(colors="#565249", labelsize=8)
for s in ("top", "right", "left"): ax.spines[s].set_visible(False)
ax.spines["bottom"].set_color("#CBCAC6")
ax.set_title("In-place rents run 7–11% below the submarket at every bedroom count",
fontsize=9.5, color="#151513", loc="left")
ax.legend(fontsize=8, frameon=False, loc="upper left")
plt.tight_layout()
chart = "scratch/takoma_rent_chart.png"
plt.savefig(chart); plt.close()
# ---------- document ----------
doc = Document()
for sec in doc.sections:
sec.page_width, sec.page_height = Inches(8.5), Inches(11)
sec.top_margin = sec.bottom_margin = Inches(1)
sec.left_margin = sec.right_margin = Inches(1.125)
for name in ("Eyebrow", "Eyebrow Secondary", "Stat", "Body Small", "Disclaimer"):
doc.styles.add_style(name, WD_STYLE_TYPE.PARAGRAPH)
def P(text, style=None):
return doc.add_paragraph(text, style=style)
def B(text):
return doc.add_paragraph(text, style="List Bullet")
def table(header, rows, widths=None):
t = doc.add_table(rows=1, cols=len(header))
t.style = "Table Grid"
for i, h in enumerate(header):
t.rows[0].cells[i].text = h
for r in rows:
cells = t.add_row().cells
for i, v in enumerate(r):
cells[i].text = str(v)
if widths:
for row in t.rows:
for i, wd in enumerate(widths):
row.cells[i].width = Inches(wd)
return t
P("Walker & Dunlop financing proposal", "Eyebrow")
doc.add_paragraph("Takoma Towers: agency refinance proposal", style="Title")
P("6733 New Hampshire Ave, Takoma Park, MD 20912 · 468 units · Prepared September 30, 2026", "Body Small")
# ---------------- page 1 summary ----------------
doc.add_heading("Summary", level=1)
P("Your January 2020 acquisition loan is approaching maturity. Our sizing shows Takoma Towers "
"supports roughly $54–56 million of fixed-rate, non-recourse agency debt on a lender "
"underwriting basis. Every execution is constrained by the 1.25x DSCR test, not by value. "
"We would lead with Freddie Mac CME 10-year fixed at $55.6 million and 6.18%.")
P("$55.6M · 6.18% fixed · 10-yr term / 30-yr amortization · 1.25x DSCR · 62.5% LTV", "Stat")
table(["Property snapshot", ""], [
["Units / rentable SF", "468 units / 369,252 SF (avg 789 SF)"],
["Vintage / format", "1969, renovated 2014; three 13-story high-rise buildings on 9.66 acres"],
["Ownership", "Takoma Towers Apts LLC; acquired Jan 27, 2020 for $85.0M ($181,624/unit)"],
["Jurisdiction", "Unincorporated Prince George's County (Chillum), Takoma Park mailing address"],
["Occupancy / retention", "98.3% occupied; 84.2% trailing-12-month retention"],
["Operating basis", "RealAI modeled P&L: EGI $11.31M, NOI $6.06M before reserves"],
["Lender-case NOI", "$5.10M after 5% vacancy floor, 10% other-income haircut, county OpEx floor and $340/unit reserves"],
["Lender value", "$89.0M at 5.73% cap (DC metro multifamily, 2Q26)"],
], widths=[1.9, 4.35])
doc.add_heading("Why it's financeable", level=3)
B("Stabilized and full. Occupancy of 98.3% beats the submarket's 96.8%. Leased units rent in 33 days against the submarket's 64.")
B("Sticky residents. Retention is 84% against 76% for the submarket, so renewals rather than new leasing carry the rent roll.")
B("Rents sit below market. In-place rents are 7–11% under the submarket at each bedroom count, so there is room within the county rent cap.")
B("Coverage survives the lender haircuts. Underwritten NOI is 13.6% below the modeled figure, yet the loan still sizes at 61–62% LTV. NOI can fall 20% before debt service goes uncovered.")
B("The exit at maturity is clear. Even at stressed takeout terms, every execution repays at maturity with $10–17M of headroom.")
doc.add_heading("Operating basis and rent regulation", level=3)
P("No owner T12 or rent roll was available. This proposal uses RealAI's modeled P&L as the operating "
"basis and applies agency-style lender haircuts to it. Proceeds will be re-sized on your actual T12 "
"and rent roll. Takoma Towers sits in Prince George's County, and the City of Takoma Park has lain "
"entirely in Montgomery County since 1997. The property is therefore outside the city's rent "
"stabilization law. It falls under the County's Permanent Rent Stabilization and Protection Act "
"(PRSA): built in 1969, it predates the exemption for units completed on or after Jan 1, 2000. "
"PRSA caps annual increases at the lesser of CPI-U + 3% or 6%, and the allowance for July 2026 "
"through June 2027 is 5.7%. We underwrite 2.5% annual rent growth, below the cap, because "
"in-place rents have been flat for a year.")
# ---------------- performance ----------------
doc.add_heading("Performance against the submarket", level=1)
P("Benchmark: Chillum/Queens Chapel submarket, RealAI Rent Index, as of September 26, 2026.")
table(["Metric", "Takoma Towers", "Submarket", "Read"], [
["Occupancy", "98.3%", "96.8%", "+1.5 pts"],
["Occupancy, 12 months ago", "98.7%", "97.0%", "Consistently above"],
["Retention (T12)", "84.2%", "76.4%", "+7.8 pts"],
["Days on market (median)", "33", "64", "Leases in half the time"],
["In-place rent, 1 BR", "$1,517", "$1,626", "−6.7%"],
["In-place rent, 2 BR", "$1,684", "$1,890", "−10.9%"],
["In-place rent, 3 BR", "$1,960", "$2,199", "−10.8%"],
["In-place rent, all units", "$1,772", "$1,778", "Mix skews to 3 BR"],
["In-place rent, 12-mo change (median)", "0.0%", "−0.6%", "Flat"],
], widths=[2.0, 1.3, 1.2, 1.75])
doc.add_picture(chart, width=Inches(6.25))
P("The discount at each bedroom count, combined with 98% occupancy, points to below-market pricing "
"rather than weak demand. The watch item is new-lease pricing. New-lease tradeouts are running "
"−1.1%, and current listings advertise up to two months free. Underwriters will read that as "
"concession pressure on new leases while renewals hold.", "Body Small")
# ---------------- residents ----------------
doc.add_heading("Who the residents are", level=1)
table(["Metric", "Takoma Towers", "Submarket", "Trend at property"], [
["Median household income", "$60,777", "$100,831", "−6.2% over 6 months"],
["Rent-to-income", "34.5%", "n/a", "Moderately cost-burdened"],
["Average FICO", "626", "660", "−11.8 pts over 12 months"],
["Accounts past due", "12.3%", "11.3%", "+1.3 pts over 12 months"],
["Credit cards ≥75% utilized", "40%", "33%", "+5.5 pts over 12 months"],
["Non-mortgage debt (avg)", "$7,053", "$12,705", "−21% over 12 months"],
["Median net worth", "Under $25K", "—", "Low wealth cushion"],
["Head-of-household age / single", "55 / 78%", "—", "Older, stable households"],
], widths=[2.0, 1.3, 1.2, 1.75])
P("The resident base is workforce: moderate incomes, thin savings and subprime-to-fair credit. Two "
"trends need to be addressed up front. Median income is down 6% in six months, and average FICO is "
"down 12 points in a year while card utilization rises. Total non-mortgage debt fell, so this looks "
"like strain rather than leverage-building. The operating evidence cuts the other way: 98% "
"occupancy and 84% retention show residents are paying and staying. An underwriter will ask for "
"the aged-receivables report to confirm it. Sample basis: 95 households and 76 credit files, rated "
"acceptable confidence.", "Body Small")
# ---------------- sizing ----------------
doc.add_heading("Sized agency refinance", level=1)
P("Quotes are all-in fixed rates at the full-leverage tier (80% LTV / 1.25x) as of September 23, "
"2026. The 10-year Treasury was 5.18% on September 24. Loans are sized on the lender case, with "
"30-year amortization, no interest-only period and a January 2027 closing. All figures come from "
"the four attached underwriting workbooks.")
doc.add_heading("Lender case", level=3)
table(["Line", "RealAI modeled P&L", "Lender case"], [
["Vacancy", "1.9% of GPR", "5.0% floor"],
["Other income", "$1.54M", "Less 10% haircut"],
["Operating expenses", "$5.24M (46.4% of EGI)", "$5.74M incl. reserves (county 51.5% floor)"],
["Effective gross income", "$11.31M", "$10.84M"],
["NOI after reserves", "$5.90M", "$5.10M (−13.6%)"],
], widths=[1.9, 2.0, 2.35])
doc.add_heading("Execution comparison", level=3)
table(["", "Fannie 7-yr", "Fannie 10-yr", "Freddie 7-yr", "Freddie 10-yr"], [
["Proceeds", "$54.30M", "$54.47M", "$54.87M", "$55.63M"],
["Rate (fixed)", "6.41%", "6.38%", "6.31%", "6.18%"],
["DSCR", "1.25x", "1.25x", "1.25x", "1.25x"],
["Debt yield", "9.39%", "9.36%", "9.30%", "9.17%"],
["LTV", "61.0%", "61.2%", "61.6%", "62.5%"],
["Binding constraint", "DSCR", "DSCR", "DSCR", "DSCR"],
["Balance at maturity", "$49.0M", "$46.0M", "$49.5M", "$46.8M"],
["Exit cost at year 5", "2.1% (YM)", "3.9% (YM)", "1.9% (YM)", "3.0% (YM)"],
], widths=[1.45, 1.2, 1.2, 1.2, 1.2])
P("Annual debt service is about $4.08M in every case. The DSCR test is the ceiling on all four: "
"each would allow $60–71M on debt yield or LTV. Freddie 10-year delivers the most proceeds at the "
"lowest rate. The trade is a heavier prepayment cost if you sell or refinance early: an estimated "
"3.0% of balance at year 5, against 1.9% on Freddie 7-year. If you expect to exit inside seven "
"years, Freddie 7-year gives up about $0.8M of proceeds and 13 bps of rate for the cheaper exit. "
"Fannie trails Freddie on both proceeds and rate at today's quotes. The lower-leverage 65% / 1.35x "
"tier prices 12–25 bps tighter, but its higher DSCR hurdle yields less proceeds for this asset.",
"Body Small")
doc.add_heading("Resilience", level=3)
B("NOI can fall 20% before the loan stops covering debt service. That break-even equals 84.7% occupancy.")
B("The maturity refinance clears at stressed terms (rate +50 bps, cap +50 bps). Headroom is $9.9M on Fannie 7 and $17.0M on Freddie 10.")
B("Value does not bind until cap rates reach about 7.3–7.5%. At a 6.25% cap, value is $81.6M and Freddie 10 LTV is 68%.")
doc.add_heading("Your existing loan: the number we need", level=3)
P("We do not have your current payoff. If the 2020 loan was sized at 60–65% of the $85M price, a "
"$54–56M refinance roughly retires it. If it was 70–75%, the refinance falls $4–9M short and "
"would be a cash-in. Your payoff statement and the prepayment terms on the current note will "
"settle this first.")
# ---------------- underwriter Q&A ----------------
doc.add_heading("What a Fannie or Freddie underwriter will ask", level=1)
qa = [
["Show us the actual T12 and rent roll. How does it compare with the modeled P&L?",
"We will size on your trailing-12 and a current rent roll. The model already assumes 5% vacancy, a 10% cut to other income and a county expense floor, so actuals near the modeled figures leave the sizing unchanged."],
["Other income is 15.8% of net rent against 8.5% for the county. What is in it?",
"Provide a line-item breakdown (utility reimbursements, parking, laundry, storage, fees) with 12 months of history. Recurring, documented items are underwritten; one-time fees are excluded."],
["Listings advertise up to two months free and new-lease tradeouts are negative. What is economic occupancy?",
"Physical occupancy is 98.3% and retention 84%, so concessions touch a minority of units. Provide a concession log by lease; the lender will net concessions from GPR, which the 5% vacancy floor partly absorbs."],
["Resident FICO fell 12 points and income 6% recently. What are collections and bad debt?",
"Provide aged receivables and 12-month bad-debt write-offs. Low non-mortgage debt, 84% retention and tenures typical of older households support collectability."],
["The asset is under Prince George's County rent stabilization. How is it underwritten?",
"Confirm PRSA registration and compliance, and disclose any banked increases, capital-improvement surcharges or fair-return petitions. Underwriting uses 2.5% growth, below the 5.7% cap, so the cap does not drive sizing."],
["It is a 1969 high-rise. What do the elevators, façade, roofs, mechanical systems and utilities look like?",
"The 2014 renovation and capital records should go to the property condition assessment. Expect replacement reserves at or above $340 per unit and possible repair escrows. Owner-paid utilities are 14.7% of EGI, and Maryland's large-building energy standards apply at this size, so energy data belongs in the package."],
["Who is the sponsor? What are its net worth, liquidity and track record?",
"Provide a personal financial statement, schedule of real estate owned and org chart for the key principal. The loan is non-recourse with standard carve-outs, but agency approval requires sponsor review."],
["What value supports the loan at this vintage?",
"Proceeds are DSCR-bound at about 62% LTV. Value would have to fall to about $69M (a cap rate near 7.3%) before LTV binds, so appraisal risk mainly affects pricing tier, not proceeds."],
["Debt yield is 9.2–9.4%. Is that thin?",
"It is typical for a stabilized, DSCR-sized agency loan in the DC metro. Agencies size on DSCR and LTV, not debt yield, and a strict 9.5% floor would cut proceeds to about $53.7M."],
]
table(["Underwriter question", "How we answer"], qa, widths=[2.4, 3.85])
# ---------------- next steps ----------------
doc.add_heading("What we need from you", level=1)
for t in ["Trailing-12 operating statement (monthly) and the prior two calendar years",
"Current rent roll with lease dates, concessions and any subsidy (e.g., voucher) tenancy",
"Payoff statement and prepayment terms on the existing loan",
"Aged receivables and bad-debt history",
"Capital expenditure history since 2014 and any recent third-party reports",
"PRSA registration and rent-increase notices",
"Sponsor financial statement and schedule of real estate owned"]:
B(t)
P("With these, we can re-size on actuals, take the loan to Fannie Mae and Freddie Mac for competing "
"quotes, and lock ahead of your maturity.")
P("Indicative only; not a commitment to lend. Figures come from RealAI's modeled P&L and market "
"data, not the owner's financial statements. Rates are market quotes as of September 23, 2026 and "
"will change. Prepayment costs are model estimates; actual yield maintenance or defeasance follows "
"the loan documents. Final terms depend on agency approval, third-party reports and sponsor review.",
"Disclaimer")
out = "scratch/takoma_pitch_plain.docx"
doc.save(out)
print(out)
cd /vercel/sandbox && sed -i 's/"Older, stable households"/"Older, mostly single-person households"/; s/Low non-mortgage debt, 84% retention and tenures typical of older households support collectability./Low non-mortgage balances and 84% retention support collectability./' scripts/build_takoma_pitch.py && grep -n "mostly single\|support collectability" scripts/build_takoma_pitch.py && rm -f scratch/takoma_pitch_*formatted* scratch/qa/* && python3 scripts/build_takoma_pitch.py && python3 skills/docx/scripts/apply_realai_format.py scratch/takoma_pitch_plain.docx --output scratch/takoma_pitch_formatted.docx
cd /vercel/sandbox && sed -i 's/"Head-of-household age \/ single", "55 \/ 78%", "—", "Older, mostly single-person households"/"Head-of-household age \/ unmarried", "55 \/ 78%", "—", "Older, mostly unmarried heads"/' scripts/build_takoma_pitch.py && rm -f scratch/takoma_pitch_formatted*.docx && python3 scripts/build_takoma_pitch.py >/dev/null && python3 skills/docx/scripts/apply_realai_format.py scratch/takoma_pitch_plain.docx --output scratch/takoma_pitch_formatted.docx | head -3 && mkdir -p scratch/qa && libreoffice --headless --convert-to pdf scratch/takoma_pitch_formatted.docx --outdir scratch/qa >/dev/null 2>&1 && pdftoppm -png -r 200 scratch/qa/takoma_pitch_formatted.pdf scratch/qa/page && ls scratch/qa
cd /vercel/sandbox && python3 skills/docx/scripts/finalize_metadata.py scratch/takoma_pitch_formatted.docx --title "Takoma Towers agency refinance proposal" --subject "Walker & Dunlop financing pitch: Fannie Mae and Freddie Mac 7- and 10-year fixed refinance sizing for Takoma Towers, Prince George's County MD" --keywords "Takoma Towers; agency refinance; Freddie Mac; Fannie Mae; rent stabilization; loan sizing" --output scratch/takoma_pitch_final.docx
The pitch is written and ready to send. It covers all five sections you asked for, and the four sizing workbooks behind the loan numbers are attached.
Rent stabilization: Prince George's County's rule applies, not Takoma Park's. The property sits in unincorporated Chillum, in Prince George's County . The whole City of Takoma Park has been in Montgomery County since 1997 , so the city's rent law doesn't reach this building. The county's Permanent Rent Stabilization and Protection Act does. It exempts only units completed in 2000 or later, and this building dates from 1969. The county caps increases at the lesser of CPI-U + 3% or 6%, which is 5.7% for July 2026 through June 2027 . I underwrote 2.5% rent growth, below the cap, because in-place rents have been flat for a year .
Sizing
Submarket performance: occupancy is 98.3% against the submarket's 96.8%. Retention is 84% against 76%, and median days on market is 33 against 64 . In-place rents are 7–11% below the submarket at each bedroom count .
Residents: this is where the pitch is weakest, and the Q&A section addresses it head-on.
Before you send it, check these:
Files are in the library:
Brand it for Walker & Dunlop. Their logo is attached.
cd /vercel/sandbox; f=scratch/inputs/library/01a0f407-d5a8-70d2-9867-f8b7cb3258ac/walkerdunlop.svg; wc -c $f; head -c 1500 $f; echo; grep -o 'fill="[^"]*"\|fill:[^;"]*\|#[0-9a-fA-F]\{6\}' $f | sort | uniq -c; ls scripts extracts subagents/workbooks 2>/dev/nullcd /vercel/sandbox; mkdir -p assets; python3 -c "import cairosvg" 2>&1; python3 -c " import cairosvg cairosvg.svg2png(url='scratch/inputs/library/01a0f407-d5a8-70d2-9867-f8b7cb3258ac/walkerdunlop.svg', write_to='assets/wd_logo.png', output_width=2400) " 2>&1 || convert -density 1200 -background none scratch/inputs/library/01a0f407-d5a8-70d2-9867-f8b7cb3258ac/walkerdunlop.svg -resize 2400x assets/wd_logo.png; identify assets/wd_logo.png; python3 skills/docx/scripts/finalize_metadata.py --help | head -30
cd /vercel/sandbox; sed -i 's/color="#F4633A", label="Takoma Towers"/color="#0F2B4D", label="Takoma Towers"/; s/color="#517787", label="Chillum/color="#18BEF0", label="Chillum/' scripts/build_takoma_pitch.py; grep -n '#0F2B4D\|#18BEF0' scripts/build_takoma_pitch.py
cat > scripts/brand_wd.py <<'EOF'
"""Apply Walker & Dunlop branding to the plain pitch draft (presentation only).
Palette from the supplied W&D logo: navy #0F2B4D, cyan #18BEF0."""
import sys
from docx import Document
from docx.shared import Pt, RGBColor, Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
NAVY, CYAN, INK, MUTED, RULE, PAPER = "0F2B4D", "18BEF0", "222222", "5B6770", "C9D3DC", "EEF3F7"
src, out, logo = sys.argv[1], sys.argv[2], sys.argv[3]
doc = Document(src)
def rgb(h): return RGBColor.from_string(h)
def style_font(st, size=None, bold=None, color=None, caps=False, italic=None):
f = st.font; f.name = "Arial"
st.element.get_or_add_rPr()
rf = st.element.rPr.find(qn("w:rFonts"))
if rf is None:
rf = OxmlElement("w:rFonts"); st.element.rPr.append(rf)
for a in ("w:ascii", "w:hAnsi", "w:cs", "w:eastAsia"): rf.set(qn(a), "Arial")
for a in ("w:asciiTheme", "w:hAnsiTheme", "w:cstheme", "w:eastAsiaTheme"):
if rf.get(qn(a)) is not None: del rf.attrib[qn(a)]
if size: f.size = Pt(size)
if bold is not None: f.bold = bold
if italic is not None: f.italic = italic
if color: f.color.rgb = rgb(color)
f.all_caps = caps
def bottom_rule(p_or_style_pPr, color, sz=8, space=4):
pPr = p_or_style_pPr
bdr = OxmlElement("w:pBdr"); b = OxmlElement("w:bottom")
for k, v in (("val", "single"), ("sz", str(sz)), ("space", str(space)), ("color", color)): b.set(qn("w:" + k), v)
bdr.append(b); pPr.append(bdr)
S = doc.styles
style_font(S["Normal"], 10, color=INK)
S["Normal"].paragraph_format.space_after = Pt(6); S["Normal"].paragraph_format.line_spacing = 1.15
style_font(S["Title"], 24, True, NAVY)
tp = S["Title"].element.get_or_add_pPr()
for e in tp.findall(qn("w:pBdr")): tp.remove(e)
bottom_rule(tp, CYAN, 12, 6)
S["Title"].paragraph_format.space_after = Pt(6)
style_font(S["Heading 1"], 15, True, NAVY)
bottom_rule(S["Heading 1"].element.get_or_add_pPr(), CYAN, 8, 3)
S["Heading 1"].paragraph_format.space_before = Pt(16); S["Heading 1"].paragraph_format.space_after = Pt(6)
S["Heading 1"].paragraph_format.keep_with_next = True
style_font(S["Heading 3"], 10.5, True, NAVY)
S["Heading 3"].paragraph_format.space_before = Pt(10); S["Heading 3"].paragraph_format.space_after = Pt(3)
S["Heading 3"].paragraph_format.keep_with_next = True
style_font(S["Eyebrow"], 8.5, True, CYAN, caps=True)
style_font(S["Stat"], 13, True, NAVY)
S["Stat"].paragraph_format.space_before = Pt(4); S["Stat"].paragraph_format.space_after = Pt(10)
style_font(S["Body Small"], 9, color=MUTED)
style_font(S["Disclaimer"], 7.5, color=MUTED, italic=True)
S["Disclaimer"].paragraph_format.space_before = Pt(14)
style_font(S["List Bullet"], 10, color=INK)
S["List Bullet"].paragraph_format.space_after = Pt(3)
# Tables: hairline borders, navy header with white bold text, zebra rows, 8.5pt
def set_borders(tbl):
tblPr = tbl._tbl.tblPr
for e in tblPr.findall(qn("w:tblBorders")): tblPr.remove(e)
b = OxmlElement("w:tblBorders")
for edge in ("top", "left", "bottom", "right", "insideH", "insideV"):
el = OxmlElement("w:" + edge)
v = "nil" if edge in ("left", "right", "insideV") else "single"
el.set(qn("w:val"), v); el.set(qn("w:sz"), "4"); el.set(qn("w:color"), RULE)
b.append(el)
tblPr.append(b)
def shade(cell, fill):
tcPr = cell._tc.get_or_add_tcPr()
sh = OxmlElement("w:shd"); sh.set(qn("w:val"), "clear"); sh.set(qn("w:color"), "auto"); sh.set(qn("w:fill"), fill)
tcPr.append(sh)
for t in doc.tables:
set_borders(t)
# sync grid widths from cell widths so LibreOffice honours them
grid = t._tbl.tblGrid
if t.rows:
ws = [c.width for c in t.rows[0].cells]
for gc, w in zip(grid.findall(qn("w:gridCol")), ws):
if w: gc.set(qn("w:w"), str(int(w.twips if hasattr(w, 'twips') else w / 635)))
for ri, row in enumerate(t.rows):
trPr = row._tr.get_or_add_trPr(); cs = OxmlElement("w:cantSplit"); trPr.append(cs)
if ri == 0:
th = OxmlElement("w:tblHeader"); trPr.append(th)
for ci, cell in enumerate(row.cells):
if ri == 0: shade(cell, NAVY)
elif ri % 2 == 0: shade(cell, PAPER)
for p in cell.paragraphs:
p.paragraph_format.space_after = Pt(1); p.paragraph_format.space_before = Pt(1)
for r in p.runs:
r.font.name = "Arial"; r.font.size = Pt(8.5)
if ri == 0: r.font.bold = True; r.font.color.rgb = rgb("FFFFFF")
elif ci == 0: r.font.bold = True; r.font.color.rgb = rgb(NAVY)
else: r.font.color.rgb = rgb(INK)
# Header: W&D logo right-aligned; footer: brand line
sec = doc.sections[0]
sec.header_distance = Inches(0.45); sec.footer_distance = Inches(0.45)
hp = sec.header.paragraphs[0]; hp.alignment = WD_ALIGN_PARAGRAPH.RIGHT
hp.add_run().add_picture(logo, width=Inches(2.4))
bottom_rule(hp._p.get_or_add_pPr(), CYAN, 6, 6)
fp = sec.footer.paragraphs[0]; fp.alignment = WD_ALIGN_PARAGRAPH.LEFT
r = fp.add_run("Walker & Dunlop | Takoma Towers agency refinance proposal | Page ")
r.font.name = "Arial"; r.font.size = Pt(7.5); r.font.color.rgb = rgb(MUTED)
r2 = fp.add_run()
for kind, text in (("begin", None), (None, "PAGE"), ("end", None)):
if kind:
fc = OxmlElement("w:fldChar"); fc.set(qn("w:fldCharType"), kind); r2._r.append(fc)
else:
it = OxmlElement("w:instrText"); it.set(qn("xml:space"), "preserve"); it.text = text; r2._r.append(it)
r2.font.name = "Arial"; r2.font.size = Pt(7.5); r2.font.color.rgb = rgb(MUTED)
doc.save(out); print(out)
EOF
rm -f scratch/takoma_pitch_* scratch/qa/*; python3 scripts/build_takoma_pitch.py && python3 scripts/brand_wd.py scratch/takoma_pitch_plain.docx scratch/takoma_pitch_wd.docx assets/wd_logo.png && python3 skills/docx/scripts/verify_text_unchanged.py scratch/takoma_pitch_plain.docx scratch/takoma_pitch_wd.docx; libreoffice --headless --convert-to pdf scratch/takoma_pitch_wd.docx --outdir scratch/qa >/dev/null 2>&1; pdftoppm -png -r 200 scratch/qa/takoma_pitch_wd.pdf scratch/qa/p; ls scratch/qacd /vercel/sandbox; python3 -c "
from docx import Document
a,b=Document('scratch/takoma_pitch_plain.docx'),Document('scratch/takoma_pitch_wd.docx')
t=lambda d:[p.text for p in d.paragraphs]+[c.text for tb in d.tables for r in tb.rows for c in r.cells]
print('body identical:',t(a)==t(b))"cd /vercel/sandbox; python3 - <<'EOF'
p='scripts/brand_wd.py'; s=open(p).read()
s=s.replace('style_font(S["Body Small"], 9, color=MUTED)','style_font(S["Body Small"], 9, color=MUTED)\nS["Body Small"].paragraph_format.space_before = Pt(6)')
s=s.replace('fp = sec.footer.paragraphs[0];','style_font(S["Footer"], 7.5, color=MUTED)\nfp = sec.footer.paragraphs[0];')
open(p,'w').write(s)
EOF
rm -f scratch/takoma_pitch_* scratch/qa/*; python3 scripts/build_takoma_pitch.py >/dev/null && python3 scripts/brand_wd.py scratch/takoma_pitch_plain.docx scratch/takoma_pitch_wd.docx assets/wd_logo.png && libreoffice --headless --convert-to pdf scratch/takoma_pitch_wd.docx --outdir scratch/qa >/dev/null 2>&1; pdftoppm -png -r 200 scratch/qa/takoma_pitch_wd.pdf scratch/qa/p; ls scratch/qacd /vercel/sandbox; python3 - <<'EOF'
p='scripts/brand_wd.py'; s=open(p).read()
start=s.index('r2 = fp.add_run()'); end=s.index('doc.save(out)')
new='''def _run():
rr = fp.add_run(); rr.font.name = "Arial"; rr.font.size = Pt(7.5); rr.font.color.rgb = rgb(MUTED); return rr
for kind in ("begin", "instr", "separate", "result", "end"):
rr = _run()
if kind == "instr":
it = OxmlElement("w:instrText"); it.set(qn("xml:space"), "preserve"); it.text = " PAGE "; rr._r.append(it)
elif kind == "result":
rr.text = "1"
else:
fc = OxmlElement("w:fldChar"); fc.set(qn("w:fldCharType"), kind); rr._r.append(fc)
'''
s=s[:start]+new+s[end:]; open(p,'w').write(s)
EOF
rm -f scratch/takoma_pitch_* scratch/qa/*; python3 scripts/build_takoma_pitch.py >/dev/null && python3 scripts/brand_wd.py scratch/takoma_pitch_plain.docx scratch/takoma_pitch_wd.docx assets/wd_logo.png && libreoffice --headless --convert-to pdf scratch/takoma_pitch_wd.docx --outdir scratch/qa >/dev/null 2>&1; pdftoppm -png -r 200 -f 3 -l 3 scratch/qa/takoma_pitch_wd.pdf scratch/qa/p; convert scratch/qa/p-3.png -crop 1700x200+0+2000 scratch/qa/foot.pngcd /vercel/sandbox; ls scratch/qa; f=$(ls scratch/qa/p-*.png | head -1); convert $f -crop 1700x200+0+2000 +repage scratch/qa/foot.png; ls scratch/qa
Fixed. Finalizing metadata under the Walker & Dunlop name and saving as a new version.
cd /vercel/sandbox; rm -f scratch/takoma_pitch_final*.docx; python3 skills/docx/scripts/finalize_metadata.py scratch/takoma_pitch_wd.docx --title "Takoma Towers agency refinance proposal" --subject "Walker & Dunlop financing pitch: Fannie Mae and Freddie Mac 7- and 10-year fixed refinance sizing for Takoma Towers, Prince George's County MD" --keywords "Takoma Towers; agency refinance; Freddie Mac; Fannie Mae; rent stabilization; loan sizing" --company "Walker & Dunlop" --output scratch/takoma_pitch_final.docx
I've rebranded the pitch for Walker & Dunlop and saved it as a new version of the same file. The text and numbers didn't change, and I checked that the body text matches the earlier version exactly.
The document's file properties now list Walker & Dunlop as the company, but the author field still says RealAI. If you'd like it to show you or your team, tell me the name to put there.
The four sizing workbooks are not branded; they're backup, not something the owner sees. I can brand them if you plan to send them too.
Files are in the library:
This is a read-only snapshot of a RealAI analysis.