CoolFace
Modelpublic

sammiset/finops-resolver

sourceHugging Faceapache-2.0updated 5mo agoView on Hugging Face
0likes10downloads
Model Card

finops-resolver

Fine-tuned Qwen3-8B model that recommends ordered resolution sequences for post-trade CNS settlement fails. Given a triage classification, inventory snapshot, and pending FTR list, the model produces a step-by-step resolution plan with mathematical coverage tracking and a plain-English narrative.

This is Stage 2 in a two-model pipeline:

StageModelTaskGGUF Size
1finops-triage (Qwen3.5-9B)Classify, score, and route fails~5.7 GB
2finops-resolver (Qwen3-8B)Recommend resolution sequence~5.0 GB

All training data is synthetic. All resolution logic is grounded in a curated knowledge base of post-trade settlement rules.

Architecture

Base model: unsloth/Qwen3-8B (text-only, no VL overhead)

Fine-tuning method: QLoRA via Unsloth + trl SFTTrainer

ParameterValue
LoRA rank (r)16
LoRA alpha32
Target modulesq_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj
LoRA dropout0
Quantization4-bit NF4 (double quant)
Gradient checkpointingUnsloth optimized
Max sequence length5,120 tokens
Effective batch size8 (2 per device x 4 accumulation)
Epochs3
Learning rate2e-4 (cosine schedule, 90 warmup steps)
Precisionbf16
PackingEnabled (SFTTrainer)

Training data: 8,000 train / 2,000 eval examples in ChatML format. Each example includes a structured <think>...</think> reasoning trace in the assistant turn, followed by the resolution JSON. The thinking trace walks through the full resolution logic: problem statement, inventory check, FTR ranking, chase walkthrough, fallback reasoning, Reg SHO timeline check, gridlock evaluation, and escalation decision.

Trainable parameters: 43.6M of 8.2B (0.53%)

Input Schema

The model expects a JSON object containing the triage output from Stage 1, the current inventory snapshot, pending FTRs, and any related fails.

json
{
  "triage": {
    "category": "CNS_FAIL",
    "cns_direction": "FTD",
    "lifecycle_state": "ESCALATED",
    "priority_score": 88.2,
    "priority_tier": "CRITICAL",
    "score_components": {
      "age": 18.0,
      "value": 12.5,
      "regulatory": 28.0,
      "counterparty": 3.0
    },
    "reason": "CNS FTD 32000 shs, threshold security, high priority",
    "action": "LOCATE_AND_DELIVER",
    "escalation_level": "L3",
    "deadline": "T+13",
    "flags": ["THRESHOLD_SECURITY", "HIGH_VALUE"]
  },
  "cusip": "594918104",
  "ftd_qty": 32000,
  "inventory": {
    "box_qty": 8000,
    "stock_loan_available": 3000,
    "recall_outstanding": 5000,
    "pending_receives": 2000
  },
  "ftrs": [
    {
      "dtc": "DTC-0161",
      "qty": 12000,
      "age_days": 3,
      "settlement_type": "RVP",
      "settlement_date": "T+1",
      "cp_fail_rate_pct": 2.1,
      "partial_delivery_history": true
    }
  ],
  "related_fails": [
    {
      "category": "DVP_FAIL",
      "dtc": "DTC-0352",
      "qty": 5000,
      "side": "Sell",
      "age_days": 2
    }
  ]
}

Input Field Reference

triage (from Stage 1 finops-triage model):

FieldTypeDescription
categorystringFail classification (CNS_FAIL)
cns_directionstringFTD (fail to deliver) or FTR (fail to receive)
lifecycle_statestringNEW, OPEN, ESCALATED, AGED
priority_scorefloat0-100, weighted composite of age/value/regulatory/CP factors
priority_tierstringLOW (0-25), MEDIUM (26-50), HIGH (51-75), CRITICAL (76-100)
score_componentsobjectBreakdown: age (30%), value (25%), regulatory (35%), counterparty (10%)
reasonstringHuman-readable triage summary
actionstringRecommended action class from triage
escalation_levelstringL1, L2, L3
deadlinestringReg SHO close-out deadline (e.g., T+13 standard, T+6 threshold)
flagsarrayRisk flags: THRESHOLD_SECURITY, HIGH_VALUE, REG_SHO_CLOSE_OUT, AGED_FAIL, LARGE_POSITION, ILLIQUID

inventory:

FieldTypeDescription
box_qtyintUnencumbered settled long positions (ex-SEG)
stock_loan_availableintExternal borrow available
recall_outstandingintStock lent that can be recalled
pending_receivesintExpected inbound (T+1 receives, pending recalls)

ftrs[]:

FieldTypeDescription
dtcstringDTC participant number of counterparty
qtyintFTR share quantity
age_daysintDays since original settlement date
settlement_typestringRVP (receive vs payment), DVP (deliver vs payment), FOP (free of payment)
settlement_datestringExpected settlement date
cp_fail_rate_pctfloatCounterparty 15-day rolling fail rate
partial_delivery_historyboolWhether this counterparty has delivered partials before

related_fails[]:

FieldTypeDescription
categorystringDVP_FAIL, CNS_FAIL, DEPOT_FAIL
dtcstringCounterparty DTC number
qtyintFail quantity
sidestringBuy or Sell
age_daysintFail age

Output Schema

json
{
  "resolution_steps": [
    {
      "step": 1,
      "action": "CHASE_FTR",
      "dtc": "DTC-0161",
      "qty": 12000,
      "settlement_type": "RVP",
      "settlement_date": "T+1",
      "rationale": "Age 3d 12000sh",
      "coverage_after_step_pct": 37.5,
      "remaining_short": 20000
    }
  ],
  "additional_ftrs_chased": 0,
  "fallback_strategy": "INITIATE_RECALL",
  "fallback_qty": 5000,
  "secondary_fallback": "SOURCE_BORROW",
  "secondary_fallback_qty": 3000,
  "total_coverable": 28000,
  "residual_short": 4000,
  "residual_action": "ESCALATE",
  "gridlock_detected": false,
  "gridlock_parties": [],
  "escalation_required": true,
  "escalation_reason": "Residual 4000 shs uncoverable",
  "narrative": "Chase DTC-0161 RVP T+1 for 12000 shs. INITIATE_RECALL 5000, SOURCE_BORROW 3000, escalate residual 4000 shs."
}

Output Field Reference

FieldTypeDescription
resolution_steps[]arrayOrdered sequence of resolution actions
resolution_steps[].stepint1-indexed step number
resolution_steps[].actionstringAction enum value (see below)
resolution_steps[].dtcstringTarget counterparty DTC number
resolution_steps[].qtyintShare quantity for this step
resolution_steps[].settlement_typestringRVP, DVP, or FOP
resolution_steps[].settlement_datestringExpected settlement date
resolution_steps[].rationalestringWhy this step was prioritized
resolution_steps[].coverage_after_step_pctfloatCumulative coverage percentage after this step
resolution_steps[].remaining_shortintShares still uncovered after this step
additional_ftrs_chasedintFTR chases beyond the first 10 (truncated for token efficiency)
fallback_strategystringPrimary fallback action after FTR chasing
fallback_qtyintShares covered by primary fallback
secondary_fallbackstringSecondary fallback action
secondary_fallback_qtyintShares covered by secondary fallback
total_coverableintSum of all sources (FTRs + fallbacks)
residual_shortintftd_qty - total_coverable (floor 0)
residual_actionstringESCALATE if residual > 0, else NONE
gridlock_detectedboolWhether gridlock signals triggered
gridlock_partiesarrayDTC numbers of parties in the gridlock chain
escalation_requiredboolTrue when residual_short > 0 after all steps
escalation_reasonstringHuman-readable escalation reason (empty if not required)
narrativestringPlain-English resolution summary

Mathematical Invariants

These hold for every valid output:

  • coverage_after_step_pct = (cumulative_qty_covered / ftd_qty) * 100 at each step
  • remaining_short decreases monotonically across steps
  • total_coverable = sum of all step quantities + fallbackqty + secondaryfallback_qty
  • residual_short = max(0, ftdqty - totalcoverable)
  • escalation_required = (residual_short > 0)

Action Enum

ActionDescription
CHASE_FTRContact counterparty to push FTR delivery
OFFSET_FTRApply FTR directly against FTD at CNS
APPLY_BOXUse free float inventory (unencumbered, ex-SEG)
INITIATE_RECALLRecall stock lent via executing broker relationship
SOURCE_BORROWObtain stock loan externally (last resort)
PARTIAL_DELIVERProactively deliver partial quantity to CNS
DEPOT_MOVEMENTMove shares from local market to DTC (ADR/cross-market)
NET_GRIDLOCKPropose bilateral or tri-party net settlement
BUY_IN_NOTICEFormal buy-in threat (B2B escalation)
SPO_SETTLEMENTCash settle free of payment (CA event)
ESCALATEResidual requires human intervention

Resolution Logic

All resolution logic is sourced from a curated knowledge base of post-trade settlement rules. The model does not invent rules.

CNS FTD Waterfall

The core resolution follows a strict priority waterfall — exhaust cheaper/faster options before escalating:

1. Chase all FTRs (oldest first, largest as tiebreaker)
   ↓ residual?
2. Apply free float box (unencumbered, ex-SEG only)
   ↓ residual?
3. Initiate recall (cheaper than borrow, always attempt first)
   ↓ residual?
4. Source stock loan (external borrow, last resort)
   ↓ residual?
5. Escalate

FTR Prioritization

FTRs are chased simultaneously, but ranked for allocation:

PriorityRule
Primary sortAge descending (oldest first)
TiebreakerQuantity descending (largest first)
Settlement typeDoes NOT affect priority
Broker relationshipDoes NOT affect priority

Partial Delivery Policy

Always apply partial deliveries immediately. Never hold for full delivery. A partial today that keeps you inside the Reg SHO window is always preferred over a full delivery that arrives too late.

This applies to both FTDs (delivering partials to CNS) and FTRs (accepting partials from counterparties).

Cross-Date Netting

T+5 FTRs can fulfill T+3 FTDs. The model evaluates next-day obligation chains before recommending external sourcing, avoiding unnecessary stock loan cost.

Reg SHO Parallel Sourcing

Default behavior is sequential: recall first, borrow only if recall is insufficient.

Exception: If the recall notice period (3 business days) would breach the Reg SHO close-out deadline, the model initiates recall AND stock loan simultaneously. This is triggered when deadline_days <= recall_notice_period.

Reg SHO Timelines:

Security TypeGrace PeriodClose-out Deadline
StandardT+4 through T+12Beginning of T+13
ThresholdT+2 through T+5Beginning of T+6

CA Event Resolution

Corporate action event fails cannot be resolved unilaterally. The model recommends one of three paths:

OptionMethodWhen
ADeliver pre-event sharesShares still valid post-event
BDeliver post-event equivalentNew CUSIP issued, old invalid
CSPO (cash settle free of payment)Share delivery impractical post-CA

All three require counterparty agreement.

Depot Movement

Triggered for ADR or cross-market securities where free float exists in a local market but not at DTC. The model factors movement timeline against the Reg SHO deadline before recommending.

B2B Escalation Path

For persistent street-side FTR failures:

1. Standard FTR chase (age + size priority)
2. Formal buy-in notice (threat creates legal/financial pressure)
3. Execute buy-in (if no delivery follows notice)

The buy-in threat alone typically resolves the fail.

Gridlock Detection

Gridlock is a circular dependency where multiple parties are each waiting on another to deliver the same CUSIP. Full visibility into counterparty positions is never available — detection relies on patterns in your own FTR/FTD data.

Four-Signal Decision Tree

The model evaluates four signals sequentially:

SignalTestIf No
S1Same CUSIP appears in both your FTD and FTR positions?Standard resolution (not mid-chain)
S23+ brokers involved in same CUSIP fails?Bilateral issue (not gridlock)
S3FTR age increasing despite repeated chase attempts?Continue chasing, monitor 1-2 days
S4Similar quantities across involved brokers?Partial gridlock (one party is bottleneck)

All four signals positive = full gridlock confirmed → initiate multi-party net settlement.

S1-S3 positive, S4 negative = partial gridlock → one party is likely the bottleneck, targeted escalation.

Gridlock Resolution

When gridlock is confirmed:

  1. 1.Identify circular dependency from available data
  2. 2.Simultaneous outreach to all parties in the chain
  3. 3.Understand each party's obligation for the CUSIP
  4. 4.Propose net settlement to break the dependency
  5. 5.Accept partial net if full resolution not possible

Gridlock vs Non-Gridlock

FactorGridlockNot Gridlock
Parties3+ brokers on same CUSIP2 parties (bilateral)
Chase response"Waiting on our source"Specific delivery timeline
FTR agingSteady increase despite chasingEpisodic delays
CUSIP concentrationSame CUSIP across multiple failsDifferent CUSIPs failing
Resolution progressNone despite multiple attemptsPartial deliveries arriving

Training Data

Generation

Training data is generated programmatically (scripts/gen_resolver.py + scripts/trace_generator.py). No LLM-generated examples. The generator:

  1. 1.Samples FTR count from the complexity distribution
  2. 2.Generates FTRs with realistic age/quantity/settlement distributions
  3. 3.Generates independent inventory snapshots
  4. 4.Walks the resolution waterfall deterministically (chase → box → recall → borrow)
  5. 5.Evaluates all four gridlock signals from the generated positions
  6. 6.Selects fallback strategies following KB waterfall order
  7. 7.Generates a deterministic <think> reasoning trace narrating each decision
  8. 8.Validates mathematical invariants before writing

Complexity Distribution

TierFTR Count% of Dataset
Simple1-3 FTRs30%
Medium5-10 FTRs40%
Complex11-28 FTRs across 10+ brokers30%

FTR Age Distribution

97% of FTRs are aged T+2 through T+5 (Gaussian centered at T+3), reflecting normal settlement. 3% tail extends to T+6 through T+10 for aged/escalated scenarios.

Scenario Coverage

The training data includes all of the following outcome types:

  • Full coverage via FTRs alone (no fallback needed)
  • Partial FTR coverage + box covers residual
  • Partial FTR + box + recall
  • Partial FTR + box + recall + borrow (full waterfall)
  • Gridlock detected with multi-party outreach
  • B2B escalation to buy-in notice
  • CA event SPO settlement
  • ADR depot movement required
  • Cross-date netting (T+5 FTR fulfilling T+3 FTD)
  • Parallel recall + loan (Reg SHO deadline conflict)
  • Problem counterparty with partial delivery history
  • Zero inventory (all external sourcing)
  • Full inventory (no external sourcing needed)

Thinking Trace Methodology

Each training example includes a structured <think>...</think> block in the assistant turn. The trace is generated deterministically from the input/output pair (no LLM calls) and follows a fixed 10-section structure:

  1. 1.Problem statement — CUSIP, FTD quantity, priority tier, deadline, flags
  2. 2.Inventory check — Box, recall, borrow, pending receives, coverage ratio
  3. 3.FTR ranking — Sorted by age desc then qty desc, top 10 shown with ranking notes
  4. 4.Chase walkthrough — Step-by-step coverage tracking (first 5 shown, rest summarized)
  5. 5.Fallback reasoning — Primary and secondary strategies with source quantities
  6. 6.Reg SHO check — Deadline vs recall notice period, sequential vs parallel decision
  7. 7.Gridlock evaluation — All 4 signals evaluated explicitly (S1-S4)
  8. 8.Escalation decision — Required/not required with reason
  9. 9.Conclusion — Final coverage percentage, residual action

This teaches the model to reason through the waterfall before producing the resolution JSON.

Scope and Limitations

v1 Training Scope

This model covers:

  • CNS FTD resolution waterfall (chase → box → recall → borrow → escalate)
  • Gridlock detection via 4-signal decision tree (S1-S4)
  • Reg SHO parallel sourcing (recall + borrow when deadline is tight)
  • CA event SPO settlement paths
  • Depot movement for ADR/cross-market securities
  • Cross-date netting (T+5 FTR vs T+3 FTD)
  • B2B buy-in notice escalation

Deferred to Future Training Iterations

  • B2B buy-in execute path — the model recommends buy-in notice (threat) but the full execute-buy-in workflow is not included in the current training run. The buy-in threat alone resolves the majority of cases; the execute path is planned for a future iteration.
  • Synthetic FTR cap at 28 — production environments can have unbounded FTR counts. The current training data caps at 28 FTRs across 10+ brokers. The architecture supports extension to higher counts in future runs.
  • Multi-CUSIP resolution — current scope is single-CUSIP per inference call. Cross-CUSIP optimization (e.g., portfolio-level netting) is planned.
  • Real-time inventory refresh — the model operates on a point-in-time inventory snapshot. Integration with streaming inventory updates is an inference-layer concern, not a model limitation.

The architecture supports extension across all of these dimensions. This is an actively developed model.

Usage

Ollama Setup

Create a Modelfile:

FROM ./finops-resolver-qwen3-8b-q4_k_m.gguf
PARAMETER temperature 0.1
PARAMETER top_p 0.9
PARAMETER num_ctx 5120

SYSTEM "You are a post-trade settlement resolution assistant. Given a triage output, inventory snapshot, and pending FTRs for a CUSIP, recommend an ordered resolution sequence following the KB resolution logic. Chase FTRs first (oldest then largest), apply free box, recall before borrow. Apply partials immediately. Detect and flag gridlock. Output JSON only — no explanation, no markdown, no preamble."
bash
ollama create finops-resolver -f Modelfile

Two-Model Pipeline

bash
# Stage 1 — triage
TRIAGE_OUTPUT=$(ollama run finops-triage "Triage this fail record: {fail_record_json}")

# Stage 2 — resolver
# Combine triage output with inventory + FTR data
ollama run finops-resolver "Resolve this fail:
{
  \"triage\": $TRIAGE_OUTPUT,
  \"cusip\": \"594918104\",
  \"ftd_qty\": 32000,
  \"inventory\": {
    \"box_qty\": 8000,
    \"stock_loan_available\": 3000,
    \"recall_outstanding\": 5000,
    \"pending_receives\": 2000
  },
  \"ftrs\": [...],
  \"related_fails\": [...]
}"

Direct Inference

bash
ollama run finops-resolver "Resolve this fail:
{\"triage\":{\"category\":\"CNS_FAIL\",\"cns_direction\":\"FTD\",\"lifecycle_state\":\"ESCALATED\",\"priority_score\":88.2,\"priority_tier\":\"CRITICAL\",\"score_components\":{\"age\":18.0,\"value\":12.5,\"regulatory\":28.0,\"counterparty\":3.0},\"reason\":\"CNS FTD 32000 shs, threshold security\",\"action\":\"LOCATE_AND_DELIVER\",\"escalation_level\":\"L3\",\"deadline\":\"T+13\",\"flags\":[\"THRESHOLD_SECURITY\"]},\"cusip\":\"594918104\",\"ftd_qty\":32000,\"inventory\":{\"box_qty\":8000,\"stock_loan_available\":3000,\"recall_outstanding\":5000,\"pending_receives\":2000},\"ftrs\":[{\"dtc\":\"DTC-0161\",\"qty\":12000,\"age_days\":3,\"settlement_type\":\"RVP\",\"settlement_date\":\"T+1\",\"cp_fail_rate_pct\":2.1,\"partial_delivery_history\":true}],\"related_fails\":[]}"

HuggingFace

Repository: sammiset/finops-resolver

GGUF download: finops-resolver-qwen3-8b-q4_k_m.gguf

Quantization: Q4KM (4-bit, k-quant mixed precision)

Base model: Qwen/Qwen3-8B

Training

bash
pip install unsloth
python scripts/train.py

Produces the LoRA adapter in adapters/checkpoint-final/ and exports models_gguf/finops-resolver-qwen3-8b-q4_k_m.gguf automatically.

Training Results

Trained on RunPod A100 80GB. 3 epochs, 1,758 steps, ~5.5 hours.

MetricValue
Final train loss (avg)0.1625
Final eval loss0.1424
Eval loss (epoch 2.56)0.1425
Train runtime20,020s (~5h 34m)
Train samples/sec0.702
Train steps/sec0.088
Eval samples/sec2.457
Total steps1,758
Final learning rate1.437e-08
Final gradient norm0.037

Convergence notes:

  • Train and eval loss converged closely (0.1625 avg vs 0.1424 eval) — no overfitting
  • Gradient norms stable at 0.03-0.04 throughout final epoch, indicating clean convergence
  • Cosine LR schedule decayed smoothly from 2e-4 to ~1.4e-08
  • Eval loss plateaued between epochs 2.56 and 3.0 (0.1425 → 0.1424), suggesting 3 epochs was the right stopping point

Validation

bash
python scripts/validate_resolver.py --input data/train.jsonl

Enforces: schema conformance, mathematical correctness of coverage percentages, monotonic remaining_short, valid action enum values, gridlock signal consistency, and escalation flag accuracy.

License and Credits

This project is licensed under the Apache License 2.0, consistent with the base model license.

Base model: Qwen/Qwen3-8B by the Qwen Team, Alibaba Group. Qwen3-8B is released under the Apache 2.0 license.

Fine-tuning framework: Unsloth for QLoRA training and GGUF export.

Training infrastructure: trl SFTTrainer on RunPod A100 80GB.