How do you convert dense account-level remediation inputs into a defensible time-value-of-money cost signal for Finance, Legal, Operations, and executive stakeholders?
This SAS project implements a high-scale time-value-of-money engine for remediation liability calculations. It computes TVM on each account’s financial impact amount from the account-specific impact start date through a defined impact end date, using daily 1-year CMT Treasury rates and annual compounding logic.
The objective is to make account-level financial remediation calculations scalable, explainable, and audit-ready.
This project demonstrates a practical remediation finance principle:
A remediation liability engine should not only calculate final dollars.
It should preserve the logic path from original financial impact, to daily rate exposure, to annual compounding, to final account-level cost signal.
The dashboard translates the SAS TVM engine into an executive view of individual account impact, Treasury-rate sensitivity, and program-level liability concentration.
The top-left panel shows how an original overcharge grows over time as annual compounding is applied. The step-function pattern reflects the anniversary-based compounding design: accumulated daily interest is added at annual boundaries, with final remainder interest added at the impact end date.
The lower-left panel shows the 1-year CMT Treasury rate path used to drive the daily interest calculation. This connects account-level remediation cost to a documented interest-rate environment rather than a static or arbitrary rate assumption.
The right-side panel aggregates individual account calculations into impact buckets. It separates original principal from accrued TVM so leadership can see where total remediation liability is concentrated.
The engine expects two primary SAS input tables.
work.starting_populationRequired conceptual fields:
| Field | Purpose |
|---|---|
account_id |
Account identifier |
impact_start_date |
Date when the financial impact begins |
financial_amount |
Original account-level impact amount |
work.treasury_1yr_cmt_ratesRequired conceptual fields:
| Field | Purpose |
|---|---|
treasury_dt |
Daily Treasury rate date |
treasury_rate |
1-year CMT Treasury rate |
The code expects holiday and weekend gaps to be backfilled to the closest prior available rate before the TVM process runs.
The script defines an impact end date as:
today + 90 days
and stores it in the macro variable:
&IMPACT_END_DATEThis can be adjusted depending on the remediation or analysis window.
Daily interest is calculated using:
daily_rate = treasury_rate / 365
daily_interest = current_financial_amount × daily_rate
The engine stores daily interest at the row level and uses it for annual and final-remainder compounding.
On each account’s annual anniversary from impact_start_date, the engine sums the prior 365 days of daily interest and adds that amount to the account balance.
Conceptual flow:
original financial amount
→ daily interest accumulation
→ annual anniversary sum
→ compounded balance update
At the final IMPACT_END_DATE, the engine sums daily interest from the most recent anniversary through the final impact date and adds that remainder interest to the account balance.
This produces:
financial_amount_plus_tvmwhich represents:
original financial amount + accrued TVM
Primary source file:
The script first creates the macro variable &IMPACT_END_DATE.
IMPACT_END_DATE = INTNX('DAY', TODAY(), +90);This establishes the ending point for all account-level TVM calculations.
Large account populations are split into manageable processing chunks.
Configurable controls:
%let split = 200000;
%let per_array_loop = 5000;| Macro Variable | Purpose |
|---|---|
split |
Number of accounts per split dataset |
per_array_loop |
Number of accounts processed in each FCMP loop iteration |
This design reduces memory pressure and gives the user control over batch size based on available SAS server resources.
The engine finds the earliest impact_start_date in the starting population and filters Treasury rates between:
earliest impact start date
and
IMPACT_END_DATE
This avoids unnecessary rate joins outside the needed calculation window.
For each account chunk, the engine joins account records to daily Treasury rates and builds an array-ready dataset.
The array input contains helper fields such as:
| Field | Purpose |
|---|---|
place_indicator |
Marks first, middle, and last rows for each account |
account_id_ct |
Running day count for the account |
anniversary |
Flags exact annual boundaries |
daily_rate |
Daily Treasury rate |
financial_amount |
Current balance basis |
daily_int |
Daily interest placeholder |
int_summed |
Annual / remainder interest placeholder |
last_days |
Number of days since the last anniversary |
The core calculation runs through PROC FCMP.
The FCMP routine reads each batch into a two-dimensional array, processes account-level interest logic in memory, and writes updated values back to the temporary dataset.
Conceptual array columns:
| Array Column | Meaning |
|---|---|
col1 |
daily rate |
col2 |
financial amount / compounded amount |
col3 |
place indicator |
col4 |
account day counter |
col5 |
account id |
col6 |
anniversary flag |
col7 |
daily interest |
col8 |
summed interest |
col9 |
last-days remainder count |
After FCMP processing, the engine keeps the last observation for each account and outputs:
financial_amount_plus_tvmThe provided implementation creates chunk-level completed outputs such as:
work.tvm_array_complete1If the chunk processing loop is expanded, additional chunk-complete outputs can be produced and combined.
Purpose:
Split the starting population into account chunks and create array-ready TVM input tables.
Key responsibilities:
- determine chunk boundaries
- join account records to Treasury rates
- calculate daily rate
- create account day counters
- flag annual anniversaries
- calculate
last_daysfor final remainder compounding
Nested within %split_dataset.
Purpose:
Build the detailed account × Treasury-rate input table for one chunk.
This macro creates work.tvm_array&b, the account-level daily-rate dataset used by the FCMP calculation.
Purpose:
Process one chunk through PROC FCMP in account batches.
Key responsibilities:
- select a batch of accounts
- load the batch into a two-dimensional FCMP array
- calculate daily interest
- apply annual compounding
- apply final remainder compounding
- extract the final row per account
Purpose:
Driver macro for running chunk-level TVM processing.
The current version processes the first chunk by default and can be extended to process additional chunks in sequence.
The engine applies TVM at annual boundaries rather than using a single flat interest uplift. This makes the result more explainable for long remediation windows where interest accrual timing matters.
By using daily 1-year CMT Treasury rates, the calculation connects remediation liability to an external rate path. This creates a stronger financial rationale than static-rate assumptions.
The chunking and FCMP array design is built for large account populations where naive row-by-row processing can become inefficient or memory constrained.
The final account-level result can be used as the basis for downstream liability summaries, executive dashboards, remediation cost forecasts, or payment calculation review.
The dashboard and code comments are designed to make the calculation path understandable to both technical owners and executive stakeholders.
This project is implemented in SAS and designed for high-volume remediation environments where account-level financial calculations, auditability, and batch execution matter.
The engine uses:
- SAS macro variables
- dataset chunking
PROC MEANSPROC SQLDATAstep processingBYgroup logicPROC SORTPROC DATASETSPROC FCMP- two-dimensional arrays
- in-memory account-level processing
- annual anniversary flags
- final remainder compounding
The architecture is designed to reduce memory pressure by:
- limiting each join to a chunk of accounts
- restricting Treasury dates to the needed window
- using array-ready datasets
- processing account batches through FCMP loops
- deleting intermediate datasets after each chunk
The code documents the purpose of each major step:
impact end-date setup
population chunking
Treasury-rate filtering
array input construction
anniversary logic
remainder-day logic
FCMP processing
final account-level extraction
This makes the calculation easier to explain, review, and validate.
financial-tvm-optimization/
│
├── README.md
│
├── docs/
│ └── executive_dashboard_preview.png
│
└── src/
└── high_scale_tvm_engine.sas
| Artifact | Purpose |
|---|---|
docs/executive_dashboard_preview.png |
Executive dashboard preview |
src/high_scale_tvm_engine.sas |
High-scale SAS TVM calculation engine |
Create or load:
work.treasury_1yr_cmt_ratesExpected conceptual fields:
treasury_dt
treasury_rateHoliday and weekend rate gaps should be backfilled to the closest prior available rate before running the TVM process.
Create or load:
work.starting_populationExpected conceptual fields:
account_id
impact_start_date
financial_amountAdjust the processing controls if needed:
%let split = 200000;
%let per_array_loop = 5000;These should be tuned based on account volume and available SAS server memory.
Run:
src/high_scale_tvm_engine.sas
For the provided default run path, review:
work.tvm_array_complete1Key field:
financial_amount_plus_tvmIf the chunk-processing driver is expanded, review and combine additional work.tvm_array_complete&b outputs as needed.
This project is a remediation finance demonstration engine, not a production disbursement system.
Important boundaries:
- The input Treasury rate table must be prepared before the engine runs.
- Holiday and weekend backfilling is expected to be handled upstream or during Treasury-rate preparation.
- The default
IMPACT_END_DATEistoday + 90 daysand should be adjusted to the governed remediation context. - The provided driver macro processes one chunk by default; it can be expanded for additional chunks.
- The final output is an account-level TVM-adjusted balance, not a full payment authorization workflow.
- Treasury-rate assumptions, compounding rules, and payout logic must be governed by the applicable business, legal, finance, and compliance stakeholders before production use.
All data and visual outputs in this repository are generated from synthetic or anonymized datasets to protect proprietary information.
This framework demonstrates methodology for high-stakes enterprise and regulatory environments, but it does not expose real customer data, proprietary remediation calculations, confidential financial rules, or regulated production pipelines.
Important interpretation boundaries:
- Dashboard values are demonstration values, not production remediation totals.
- The engine calculates account-level TVM-adjusted balances, not final customer communications or disbursement instructions.
- Treasury-rate inputs must be independently sourced, validated, and governed in any production setting.
- The calculation framework should be reviewed by Finance, Legal, Compliance, Operations, and Audit before any production use.
No Cold Handoffs — engineering zero-defect, audit-ready results so stakeholders internalize the underlying “why.”
This project is designed to ensure that time-value-of-money remediation logic is not treated as a black-box calculation. The goal is to make the full path from original financial amount, to daily rate exposure, to annual compounding, to final liability signal clear enough for technical, finance, legal, operations, and executive stakeholders to review and defend.
