Skip to main content

Deep Dive: Desktop App Plugin Architecture

Plugin Architecture Overview

The PowerSeller Desktop App supports 32 plugins distributed as separate PBL (PowerBuilder Library) files. Plugins extend the application with investor-specific rate sheet parsing, bid management, pool fill optimization, and buy-up/buy-down grid conversion — all without modifying the core application.

Plugin Framework

Every plugin follows a standard structural pattern:

ComponentRole
NVO (n_cst_rate_sheet_<vendor>)Non-Visual Object containing all business logic — Excel parsing, HTTP calls, data transformation
Window (w_<vendor>)Sheet window opened inside the MDI frame
Menu (m_plugin)Dynamic menu item added to the Plug-ins menu at startup
DataWindows.srd objects for display grids and report output
Tab UOsUser Object tabs for multi-panel layouts within the window

The base framework lives in plugin/n_cst_rate_sheet_fn.sru, which provides shared pricing merge logic used by all 26 rate sheet plugins. Key shared functions:

FunctionPurpose
of_update_pricing()Normalizes vendor-specific staging data into pscat_inst_dde_links_multi
of_apply_adjustments()Applies post-merge price adjustments
of_apply_global_adjustment_value()Applies site-wide global adjustments

Plugin Registration and Licensing

Plugins register in pxcat_site_plugins with the following record structure:

ColumnPurpose
plugin_idUnique identifier
window_namePowerBuilder window class to open
menu_labelDisplay text in Plug-ins menu
menu_orderSort position
current_versionVersion string
expiration_dateLicense expiration date
data_mgr_associationAvailable when Data Manager is licensed
secondary_mgr_associationAvailable when Secondary Manager is licensed
risk_mgr_associationAvailable when Risk Manager is licensed
post_closing_associationAvailable when Post-Closing Manager is licensed
app_runner_associationAvailable when AppRunner is licensed

Plugins also participate in the macro automation system via pxcat_macro_modules and pxcat_macro_module_plugins, allowing scheduled batch execution of plugin operations.

Plugin Lifecycle


BidMgr (Bid Management) — The Key Discovery

BidMgr is the single most important plugin for understanding the PSX relationship. Analysis of the source code reveals that BidMgr and the core bid_pkg module serve fundamentally different purposes — a distinction that was invisible from the module dependency graph alone.

BidMgr vs. bid_pkg: Two Different Directions

AspectBidMgr (plugin)bid_pkg (core module)
DirectionInbound — seller loan tapes come IN to the platformOutbound — loans go OUT to investor bids
Business contextA correspondent lender or aggregator receives loan tapes from sellers and needs to price them competitivelyA lender packages pools of owned loans and solicits bids from investors
Tablespsbid_loans, psbid_loan_confirm, psbid_trackingrmcat_bidpkg_*, rmcat_bx_bidpkg_*
WorkflowImport tape → BestEx/inquiry analysis → payup adjustments → margin rules → accept to pipelinePackage pools → solicit bids → select winner → settle
WTPO production usageActive — 6,592 loans, 42,732 confirmationsEmpty tables — no production data
ComplexityFull ETL pipeline with map-driven field translation, Excel OLE parsing, pricing integrationSimpler pool-to-bid packaging flow

BidMgr Workflow

BidMgr Workflow Steps (Detailed)

StepActionDetails
1Import seller loan tapeExcel file parsed via OLE automation. Map-driven ETL translates seller-specific column layouts into psbid_loans
2Assign bid_idFormat: YYYYMMDD + sequence number. Recorded in psbid_tracking
3Seed confirmationspsbid_loan_confirm populated from imported loans — one confirmation row per loan
4Copy to loan_inquiryLoans staged for pricing engine consumption
5Run BestEx/inquiry analysisExecute pricing against configured investor profiles
6Apply payup adjustmentsPer-loan adjustments from psbid_payup_percent
7Apply margin rulesMargin calculations based on bid parameters
8Update confirmationspsbid_loan_confirm updated with proxy MBS price, base price, and investor-specific prices
9Accept to pipeline (optional)Loans inserted into the main loan table with company suffix rules governing the company field value
10Export resultsOutput in CSV, Excel, PDF, XML, or via email

BidMgr Data Model

TablePurposeWTPO Row Count
psbid_loansImported seller loan tape data6,592
psbid_loan_confirmPricing confirmations per loan42,732
psbid_trackingBid assignment tracking (bid_id → date → status)Active
psbid_payup_percentPayup adjustment percentagesConfigured
psbid_column_mapSeller-specific Excel column mapping definitionsConfigured
psbid_margin_rulesMargin calculation rulesConfigured
psbid_export_configExport format and destination settingsConfigured
psbid_company_suffixCompany field suffix rules for pipeline acceptanceConfigured

Why This Matters

BidMgr implements the exact workflow that PSX (Xarbi) replaces:

  1. A seller submits a loan tape
  2. The system normalizes the seller's field layout
  3. Pricing runs against available investors
  4. Results are returned as confirmations

The difference: BidMgr uses manual SQL conversion rules per seller and Excel OLE parsing with hardcoded column positions. PSX uses automatic field detection, a declarative stacking engine, and anonymous marketplace matching.


Rate Sheet Plugins (26 Investor-Specific Parsers)

Common Architecture

Every rate sheet plugin follows the same structural pattern:

Data flow:

  1. Per-investor NVO (n_cst_rate_sheet_<vendor>) loads the investor's rate sheet via Excel OLE automation or HTTPS/XML
  2. Parsed data goes to a per-investor staging table (psb2b_pricing_<vendor>)
  3. Shared n_cst_rate_sheet_fn.of_update_pricing() normalizes staging data into pscat_inst_dde_links_multi
  4. of_apply_adjustments() and of_apply_global_adjustment_value() apply post-processing

Complete Plugin Inventory

#Plugin PBLInvestorParse FormatStaging Table
1ahmratesheet.pblAmeriHome Mortgage (AHM)Excel OLE — CoverSheet + Base Prices with dynamic widthpsb2b_pricing_ahm
2amfratesheet.pblAmeriFirst Financial (AMF)Excel OLEpsb2b_pricing_amf
3caliberratesheet.pblCaliber Home LoansExcel OLEpsb2b_pricing_cal
4famcratesheet.pblFinance of America Mortgage (FAMC)Excel OLEpsb2b_pricing_famc
5fhlbratesheet.pblFederal Home Loan Bank (FHLB)Excel OLEpsb2b_pricing_fhlb
6fhlbcincinnati.pblFHLB CincinnatiExcel OLEpsb2b_pricing_fhlb_cin
7fhlbindianapolis.pblFHLB IndianapolisExcel OLEpsb2b_pricing_fhlb_ind
8flagstarratesheet.pblFlagstar BankExcel OLEpsb2b_pricing_flagstar
9fmcratesheet.pblFederal Mortgage Corp (FMC)Excel OLEpsb2b_pricing_fmc
10fnm_fre_b2b.pblFannie Mae / Freddie Mac B2BHTTPS/XML API (MBS pricing)psb2b_pricing_fnm, psb2b_pricing_fre
11jpmcbratesheet.pblJPMorgan Chase Bank (JPMCB)Excel OLEpsb2b_pricing_jpmcb
12masshousingratesheet.pblMassHousingExcel OLEpsb2b_pricing_mh
13mrcratesheet.pblMortgage Research Center (MRC)Excel OLEpsb2b_pricing_mrc
14nrzratesheet.pblNew Residential Investment (NRZ)Excel OLEpsb2b_pricing_nrz
15phmratesheet.pblPennyMac (PHM)Excel OLE — flat Price tabpsb2b_pricing_phm
16phhratesheet.pblPHH MortgageExcel OLEpsb2b_pricing_phh
17phlratesheet.pblPlaza Home Lending (PHL)Excel OLEpsb2b_pricing_phl
18pnmacratesheet.pblPennyMac (PNMAC)Excel OLEpsb2b_pricing_pnmac
19radianratesheet.pblRadian GroupExcel OLEpsb2b_pricing_radian
20rwtratesheet.pblRedwood Trust (RWT)Excel OLEpsb2b_pricing_rwt
21tmsratesheet.pblThe Money Source (TMS)Excel OLEpsb2b_pricing_tms
22truistratesheet.pblTruist FinancialExcel OLE — hierarchical labeled rowspsb2b_pricing_truist
23usbratesheet.pblU.S. Bank (USB)Excel OLEpsb2b_pricing_usb
24wfratesheet.pblWells FargoExcel OLEpsb2b_pricing_wf
25plugin.pblBase plugin frameworkN/A — shared functionsN/A
26powerfill.pblPowerFill pool optimizationN/A — optimization enginepfill_*
note

The fnm_fre_b2b.pbl plugin is unique: it uses HTTPS/XML API calls instead of Excel OLE automation. All other rate sheet plugins parse Excel files downloaded by users or received via email.

What Varies Per Investor

Every investor publishes rate sheets in a different Excel layout, requiring custom PowerScript parsing logic for each:

InvestorLayout Complexity
PennyMacFlat Price tab — single worksheet, columnar rates × prices
TruistHierarchical labeled rows — rate categories with nested sub-sections
AmeriHomeCoverSheet + Base Prices — multi-worksheet with dynamic column width based on product count
FHLMC (via fnm_fre_b2b)4 worksheets — separate tabs for 15yr, 20yr, 30yr fixed and ARM products
FlagstarMulti-tab with LLPA adjustments embedded in separate worksheets
JPMCBComplex grid format with product/coupon matrix and nested adjustment tables

This per-investor parsing complexity is the core problem: every new investor requires a new PBL, custom PowerScript parsing code, a new staging table, and QA testing against that investor's actual rate sheet format. Format changes by the investor require code updates.


PowerFill (Pool Fill Optimization)

Purpose

PowerFill optimizes loan-to-trade allocation under configurable constraint sets. Given a set of open trades with target amounts and a pool of eligible loans, PowerFill determines the optimal loan allocation that minimizes carry cost and maximizes fill rates while respecting securitization rules.

Architecture

The heavy optimization logic lives in SQL Server stored procedures — approximately 19,000 lines of T-SQL — with the PowerBuilder UI serving primarily as a configuration and execution front-end.

Data Model

TablePurpose
pfill_constraintsConstraint definitions (loan eligibility rules per trade/pool)
pfill_guidesFill priority guide rankings
pfill_trade_paramsTrade-level parameters (target amount, tolerance, priority)
pfill_carry_costCarry cost tables for optimization scoring
pfill_loan_orderingLoan sort/priority rules for allocation sequencing

Key Capabilities

  • Constraint-based allocation — loans must satisfy all applicable securitization rules for the target pool
  • Tolerance limits — trades can be overfilled or underfilled within configurable tolerance bands
  • Priority ordering — trades and loans are ranked to determine allocation sequence
  • Carry cost optimization — minimizes warehouse financing cost by accelerating delivery of high-carry loans
  • Multi-pass allocation — multiple passes with different strategies (exact fit, best fit, fill remaining)
Future PSSaaS

The PSSaaS Pooling module would port PowerFill's optimization logic from T-SQL to .NET, enabling modern constraint solvers and better integration with the pooling engine's 12-source eligibility framework.


BUBD Grid Converter (Buy-Up/Buy-Down)

Overview

The BUBD Grid Converter parses agency buy-up/buy-down grid files and converts them to normalized rows used by the BestEx servicing strategy optimization. Buy-up/buy-down grids define the price adjustments a lender receives (or pays) for choosing a higher or lower servicing fee than the standard rate.

Supported Agency Formats

AgencyFormatSource
FNMA (Fannie Mae)Excel workbookPublished monthly by FNMA
FHLMC (Freddie Mac)Excel workbook or XMLPublished monthly by FHLMC
GMACCustom formatInvestor-specific

Data Flow

How BUBD Feeds BestEx

The normalized guarantee fee ratios in pscat_master_guar_fee_ratios are consumed by the BestEx engine during Phase 3 (Rate Optimization):

  1. For each loan, BestEx evaluates multiple servicing spread scenarios
  2. Each scenario references the BUBD grid to determine the price adjustment for that spread
  3. The optimal buy-up or buy-down level is selected based on net execution (total price including the BUBD adjustment)
  4. This feeds into pass-through rate computation and ultimately the scenario ranking

Key Details

  • Supports multiple master commitments and grid months per import
  • Grid structure: coupon rate × servicing spread matrix, where each cell contains a price adjustment (positive = buy-down credit, negative = buy-up cost)
  • Imported monthly as agencies publish updated grids

Mapping to the PSSaaS + PSX Ecosystem

Plugin Replacement Strategy

PluginReplaced ByHowStatus
BidMgrPSX (Xarbi)Loan tape ingestion with automatic field detection, AI-driven pricing via stacking engine, anonymous marketplace matching, bid request generationPSX v6.0 — pricing validated
Rate sheet plugins (24)PSXAI-driven rate sheet extraction replaces 24 custom Excel parsers; schema profiles replace per-investor code; 8-phase deterministic stacking replaces imperative pricing logicPSX v6.0 — 90 ADRs
fnm_fre_b2bPSSaaS Price Ingestion (future)GSE API-based pricing feeds integrated directly into PSSaaSArchitecture phase
PowerFillPSSaaS Pooling module (future)Port 19K lines of T-SQL optimization logic to .NET with modern constraint solversArchitecture phase
BUBD Grid ConverterPSSaaS Price Ingestion (future)API-based agency fee grid import with automated monthly updatesArchitecture phase
bid_pkg (core)PSX (Xarbi) + PSSaaS Bid Manager (future)PSX marketplace replaces solicited bid process; PSSaaS manages trade-side bid trackingArchitecture phase

Desktop Plugin → PSX Capability Mapping

Desktop CapabilityPSX ReplacementKey Difference
Manual Excel column mapping per seller (psbid_column_map)field_registry.py — canonical field model with alias detectionAutomatic detection vs. manual SQL rules
24 hardcoded Excel OLE parsers (per-investor PowerScript)AI-driven rate sheet extraction agentsAI adapts to format changes; no code updates needed
Imperative per-investor pricing logic in PowerScriptstacking_engine.py — 8-phase deterministic LLPA evaluationDeclarative stacking layers vs. imperative code per investor
Per-investor staging tables (psb2b_pricing_*)Schema profiles — buyer-specific configuration as dataConfiguration vs. dedicated database tables
Manual BestEx run after importPSSaaS BestEx enrichment wiring (PSX ADR-042)Automated pricing feedback loop
SQL conversion rules for field normalization (pxcat_conversion_values)Recursive AI extraction with canonical field registryAI-powered vs. rule-table-driven
No CRA/affordable housing analysisCRA eligibility with e11tec integrationBuilt-in compliance layer

PSX Capabilities Referenced

PSX (v6.0, 90 ADRs) replaces the plugin architecture with:

PSX ComponentWhat It ReplacesDescription
field_registry.pypsbid_column_map, pxcat_conversion_valuesCanonical field model with automatic alias detection — no manual column mapping
AI rate sheet extraction24 Excel OLE parser PBLsRecursive AI agents parse any rate sheet format without hardcoded layout logic
stacking_engine.pyPer-investor pricing code in n_cst_rate_sheet_<vendor>8-phase deterministic LLPA evaluation with declarative layer composition
Schema profilesPer-investor PBL + staging tableBuyer-specific configuration stored as data, not compiled code
Bid request generationManual phone/email bid solicitationAutomated bid creation and distribution through the marketplace
CRA eligibility (e11tec)Not available in Desktop AppCommunity Reinvestment Act eligibility scoring
BestEx enrichment (ADR-042)Manual BestEx run in Desktop AppAutomated PSSaaS ↔ PSX pricing feedback loop
Anonymous matchingDirect investor relationships onlyMarketplace model with privacy-preserving loan attributes

Architectural Comparison


Summary Statistics

MetricValue
Total plugins32 PBLs
Rate sheet parsers24 investor-specific
Utility plugins2 (base framework, PowerFill)
Specialty plugins1 (BidMgr) + BUBD converter logic
Staging tables37 (psb2b_* prefix)
T-SQL in PowerFill~19,000 lines
Unique Excel layouts parsed24 (every investor different)
WTPO BidMgr loans processed6,592 loans, 42,732 confirmations
PSX ADRs replacing this architecture90