Oracle3
Open-source trading engine and MCP server for prediction markets. Fee-aware no-arbitrage trading across related contracts, live on Kalshi, Polymarket and Solana or on paper.
The intelligence layer for structured finance
FinanceC# · DockerfileGitHub @GraamOrgOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Structured Finance Cashflow Engine
Translation pending
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
graam-flows is the open execution layer behind Graam.
It provides a deterministic, auditable engine for running structured credit deals — from collateral projections through waterfall execution to bond analytics.
The goal is to move structured credit away from encrypted CDI files and fragmented spreadsheet models toward a shared, executable representation of a deal.
Read more: From CDI Files to Executable DealsRead the full README ↗graam-flows is the open execution layer behind Graam.
It provides a deterministic, auditable engine for running structured credit deals — from collateral projections through waterfall execution to bond analytics.
The goal is to move structured credit away from encrypted CDI files and fragmented spreadsheet models toward a shared, executable representation of a deal.
Read more: From CDI Files to Executable Deals
Structured credit workflows today rely heavily on spreadsheets and fragmented models. Deals are often re-built independently by each party, introducing inconsistencies and operational risk.
graam-flows provides a single, executable representation of a deal that can be:
This is a step toward making structured credit programmable.
graam-flows is the execution layer. Graam builds on top of it with:
This repository focuses on the deterministic modeling layer.
graph LR
Input["User Query / Prospectus"] --> Agent["Graam Agent"]
Agent -->|Deal DSL| D
subgraph graam-flows
D["Collateral Engine"] -->|pool cashflows| E["Waterfall Engine"]
E -->|tranche cashflows| F["Pricing Engine"]
end
F --> Output["Price / Yield / Spread / WAL"]
graam-flows has three engines:
The engines can be used together or independently. Generate collateral projections, run them through a waterfall, then price the output tranches — or use any engine in isolation.
The engine supports the deal structures found in Auto ABS, RMBS, and credit risk transfer (CRT) securitizations: sequential and pro-rata payment priorities, shifting interest, enhancement caps, trigger-dependent structure switching, reserve accounts, OC turbo mechanisms, and more.
dotnet build
dotnet test
dotnet run --project src/GraamFlows.Api
The API starts on http://localhost:5200 with Swagger UI at /swagger.
docker build -t graam-flows .
docker run -p 5200:5200 graam-flows
Both commands take the deal model as a positional argument:
# project a deal and export the cashflows to Excel
dotnet run --project src/GraamFlows.Cli -- run path/to/deal.json
# validate the deal's WAL against its published decrement table
dotnet run --project src/GraamFlows.Cli -- wal-tests path/to/deal.json --verbose
wal-tests strikes the grid entirely from the deal model — nothing is taken from the clock, so
two runs of the same file on different days give the same answer. Three fields decide the basis:
| Field | Meaning |
|---|---|
firstPaymentDate (deal level) | First distribution date, when the tranches carry only a payDay. Per-tranche firstPayDate wins; closingDate is the last resort. A deal that states none of the three is rejected rather than anchored to today. |
walScenarios.assumptions.prepaymentType | CPR (% of current balance — the default, and what RMBS decrement tables are struck in) or ABS (% of original balance, the auto-ABS convention). |
walScenarios.assumptions.callTriggers | Names of the triggers the "to redemption date" column is struck to; the run stops at whichever fires first. Omitted, a dated DATE_TERMINATION redemption is used when the deal declares one, else the COLLATERAL_VALUE clean-up. |
POST /api/calccollateral projects loan pool cashflows from asset data and assumptions.
{
"projectionDate": "2024-01-25",
"assets": [
{
"assetName": "Pool",
"interestRateType": "FRM",
"originalDate": "2023-06-01",
"originalBalance": 100000000,
"originalInterestRate": 6.5,
"currentInterestRate": 6.5,
"originalAmortizationTerm": 72,
"currentBalance": 95000000,
"serviceFee": 1.0
}
],
"assumptions": {
"cpr": 6.0,
"cdr": 1.0,
"severity": 40.0,
"prepaymentType": "CPR"
}
}
Assumptions support constant scalars, per-period vectors (cprVector: [6.0, 7.0, 8.0, ...]), or ramp strings (cprVectorStr: "1.0R12,6.0"). Prepayment convention can be CPR (% of current balance, standard for RMBS) or ABS (% of original balance, standard for Auto ABS).
POST /api/pricing computes bond analytics from a cashflow stream.
{
"cashflows": [
{ "date": "2024-02-25", "interest": 333333, "principal": 1500000, "balance": 98500000 },
{ "date": "2024-03-25", "interest": 328333, "principal": 1500000, "balance": 97000000 }
],
"params": {
"inputType": "price",
"inputValue": 99.5,
"settleDate": "2024-01-25",
"balance": 100000000,
"dayCount": "30/360",
"compounding": "SemiAnnual"
},
"rates": [[0.5, 5.0], [1.0, 4.8], [2.0, 4.6], [5.0, 4.5], [10.0, 4.4]]
}
Input types: price (solve for yield/spread), yield (solve for price), spread (solve for price from Z-spread). Returns price, yield, Z-spread, discount margin, modified duration, WAL, and accrued interest. The rates array provides a term structure as [term_years, rate_percent] pairs for spread and duration calculations.
POST /api/waterfall distributes collateral cashflows across tranches and returns tranche-level cashflows.
{
"projectionDate": "2024-01-25",
"collateralCashflows": [
{
"cashflowDate": "2024-02-25",
"groupNum": "1",
"beginBalance": 100000000,
"scheduledPrincipal": 1000000,
"unscheduledPrincipal": 500000,
"interest": 666667,
"netInterest": 585417,
"serviceFee": 81250,
"defaultedPrincipal": 0,
"recoveryPrincipal": 0
}
],
"deal": {
"dealName": "EXAMPLE-2024-1",
"waterfallType": "ComposableStructure",
"interestTreatment": "Collateral",
"closingDate": "2024-01-25",
"tranches": [
{
"trancheName": "A",
"originalBalance": 80000000,
"couponType": "Fixed",
"fixedCoupon": 5.0,
"firstPayDate": "2024-02-25",
"legalMaturityDate": "2030-01-25",
"dayCount": "30/360",
"cashflowType": "PI",
"trancheType": "Offered",
"payDay": 25,
"payFrequency": 12
},
{
"trancheName": "B",
"originalBalance": 20000000,
"couponType": "Fixed",
"fixedCoupon": 6.0,
"firstPayDate": "2024-02-25",
"legalMaturityDate": "2030-01-25",
"dayCount": "30/360",
"cashflowType": "PI",
"trancheType": "Offered",
"payDay": 25,
"payFrequency": 12
}
],
"unifiedWaterfall": {
"executionOrder": [
"INTEREST",
"PRINCIPAL_SCHEDULED",
"PRINCIPAL_UNSCHEDULED",
"WRITEDOWN"
],
"steps": [
{
"type": "INTEREST",
"structure": { "type": "SEQ", "tranches": ["A", "B"] }
},
{
"type": "PRINCIPAL",
"source": "scheduled",
"default": { "type": "SEQ", "tranches": ["A", "B"] }
},
{
"type": "PRINCIPAL",
"source": "unscheduled",
"default": { "type": "SEQ", "tranches": ["A", "B"] }
},
{
"type": "WRITEDOWN",
"structure": { "type": "SEQ", "tranches": ["B", "A"] }
}
]
}
}
}
Required fields to note:
collateralCashflows[].groupNum must match the group emitted by the unified waterfall ("1" by default). The default on PeriodCashflowDto is "0", which will cause every PayRule to be skipped.collateralCashflows[].netInterest drives tranche interest distribution; interest alone is not used. When chaining from /api/calccollateral, both fields are populated automatically.deal.closingDate seeds FirstSettleDate on each tranche and anchors first-period accrual. Without it, accrual days collapse to zero for interestTreatment: "Collateral".tranche.payFrequency is payments per year (12 = monthly, 4 = quarterly, 2 = semi-annual, 1 = annual), not months between payments. It must match the cadence of collateralCashflows; /api/calccollateral emits monthly cashflows, so tranches should use 12. The default is 12.The API accepts both camelCase and snake_case JSON keys.
Deals can be defined using the unified waterfall format (recommended) or the lower-level PayRules DSL.
The unified waterfall is a steps-based format where each step defines how a specific cashflow type is distributed. Step types:
| Step | Description |
|---|---|
INTEREST | Interest distribution to tranches |
PRINCIPAL | Principal distribution (source: scheduled, unscheduled, recovery) |
WRITEDOWN | Loss allocation (reverse seniority) |
EXPENSE | Deal expense payments |
RESERVE_DEPOSIT | Reserve account deposits |
EXCESS_TURBO | OC turbo paydown from excess interest |
EXCESS_RELEASE | Remaining excess to certificateholders |
SUPPLEMENTAL_REDUCTION | Credit-support-capped subordinate reduction |
CAP_CARRYOVER | WAC cap shortfall payback |
Each step uses a payable structure tree to define distribution order:
| Structure | DSL | Description |
|---|---|---|
| Sequential | SEQ(A, B, C) | Pay A fully, then B, then C |
| Pro rata | PRORATA(A, B) | Split proportionally by balance |
| Shifting interest | SHIFTI(0.7, seniors, subs) | Split by percentage (70/30) |
| Enhancement cap | CSCAP(0.055, seniors, subs) | Redirect excess credit support to subs |
| Fixed amount | FIXED(var, primary, overflow) | Fixed dollar amount to primary, rest to overflow |
| Forced paydown | FORCE_PAYDOWN(forced, support) | Force one tranche to zero first |
| Proforma | PROFORMA(A, 0.6, B, 0.4) | Fixed percentage shares |
Structures can be nested: SEQ(PRORATA('A-1','A-2','A-3'), SINGLE('B'), SINGLE('C')).
Principal structures can switch based on trigger pass/fail state:
{
"type": "PRINCIPAL",
"source": "scheduled",
"rules": [
{
"when": { "pass": ["CE_Test"] },
"structure": { "type": "SHIFTI", "shiftVariable": "ShiftPct", ... }
},
{
"structure": { "type": "SEQ", "tranches": ["A", "B", "C"] }
}
]
}
Rules are evaluated in order; the first match wins. A rule with no when is the unconditional fallback.
The executionOrder array controls which steps run and in what sequence. The default order is:
EXPENSE -> INTEREST -> PRINCIPAL_SCHEDULED -> PRINCIPAL_UNSCHEDULED ->
PRINCIPAL_RECOVERY -> RESERVE -> WRITEDOWN -> EXCESS_TURBO -> EXCESS_RELEASE
The waterfallOrder field controls how interest and principal interact:
standard (default): all interest paid, then all principalinterestFirst: per seniority level, pay interest then principalprincipalFirst: per seniority level, pay principal then interestsrc/
GraamFlows.Api/ REST API (ASP.NET Core)
GraamFlows.Cli/ Command-line interface
GraamFlows.Core/ Waterfall engine, rules engine, triggers
GraamFlows.Domain/ Domain models (Deal, Tranche, PayRule, etc.)
GraamFlows.Objects/ Interfaces, enums, data contracts
GraamFlows.Util/ Pricing analytics, calendar, day counters, term structure, solvers
tests/
GraamFlows.Tests/ Unit and integration tests (xUnit)
Core/AssetCashflowEngine/Amortizer.cs) - High-performance collateral cashflow generator. Uses a struct-of-arrays asset layout (AssetDataArrays) and tight, allocation-free inner loops for cache locality — execution itself is single-threaded. Projects scheduled principal, prepayments, defaults, recoveries, and delinquencies for fixed-rate, ARM, step-rate, and IO loans.Core/Waterfall/Structures/ComposableStructure.cs) - The waterfall execution engine. Runs step-based waterfall periods, tracking available funds through each step.Core/Waterfall/Structures/PayableStructures/) - Composable payment distribution trees (Sequential, Prorata, ShiftingInterest, EnhancementCap, etc.).Core/RulesEngine/) - Compiles PayRule DSL formulas into executable C# at runtime using Roslyn. Supports trigger conditions, variable lookups, balance queries, and structure-building functions.Api/Transformers/UnifiedWaterfallBuilder.cs) - Transforms the steps-based JSON format into PayRule DSL for the engine.Util/Finance/Cashflow.cs) - Bond analytics calculator. Computes price, yield, Z-spread, discount margin, modified duration, WAL, and accrued interest from any cashflow stream against a term structure.Util/Solvers1D/) - Numerical root-finding (Brent, Newton-Raphson, bisection, etc.) used by the pricing engine to solve for yield and spread.The engine has been used to model:
Business Source License 1.1 — converts to Apache 2.0 on April 3, 2029. See LICENSE.