The FinWatch Watch Script DSL: A Comprehensive Reference
Welcome to the definitive guide for the FinWatch Watch Script (.ws) Domain Specific Language. This document is the single source of truth for any developer writing fraud detection rules. It provides an exhaustive, deeply technical exploration of every component of the language, grounded entirely in the actual implementation of the FinWatch parser and interpreter.
The Future is a Fluent Conversation About Risk
The philosophy behind the Watch Script DSL is “Rules as Code.” Fraud logic shouldn’t live in a black box. It should be versioned in Git, reviewed in Pull Requests, and deployed with the same rigor as your application’s source code. This language is designed to be expressive enough for complex fraud patterns, yet readable enough for compliance and risk analysts to audit.
The Old Way: A System Held Together by Regex and Hope
Traditional rule engines force you to think in isolated, stateless events. This leads to critical limitations:
They Lack Context: A simple rule can’t easily answer questions like, “How many times has this user tried to do this in the last hour?” or “Is this transaction unusual for this specific user?”
They Are Brittle: A rule like description regex "(?i)crypto" is easily bypassed. What if the user writes c-r-y-p-t-o? Or uses a different term? You’re stuck in a never-ending game of cat-and-mouse, adding ever-more-complex regex patterns that are a nightmare to maintain.
They Are Slow to Change: Because the logic is often buried in application code or managed through clunky UIs, deploying a new rule is a slow, developer-dependent process. By the time the rule is live, the fraudsters have moved on.
Consider a classic fraud pattern: structuring (or “smurfing”), where a user makes multiple small deposits to stay under a reporting threshold. How would you detect this with a traditional system? It’s nearly impossible. You can’t do it with a single regex, and it requires keeping state—something most basic rule engines aren’t built for.
A DSL like FinFlows allows you to describe the behavior of fraud, not just the superficial attributes of a single transaction. It provides the vocabulary to express complex, time-based patterns in a way that is both powerful and readable.Two features, in particular, are game-changers:
1. Time-Window Aggregates: The End of Stateless Rules
Instead of looking at one transaction, FinFlows allows you to analyze a stream of activity over a defined period. This is how you defeat patterns like structuring.Look how elegantly this rule describes the problem:
rule StructuringDetection { description "Detect multiple small deposits intended to evade limits" when amount < 10000 and count(where source == $current.source, "PT24H") >= 3 and sum(amount where source == $current.source, "PT24H") > 25000 then review score 0.8 reason "Possible structuring"}
In plain English, this says: “If a transaction is under 10,000,butthesameuserhasmadeatleast3transactionsinthelast24hoursthattotalmorethan25,000, flag it for review.”This is impossible with regex alone. With FinFlows, it’s a few lines of clear, declarative logic.
Static rules treat all users the same. current.source`, let you create rules that are relative to the actor’s own behaviour.Consider a velocity check:
rule HighVelocitySpending { description "Detect rapid spending from a single account" when sum(amount where source == $current.source, "PT1H") > 5000 then review score 0.7 reason "Spending velocity exceeded"}
This rule isn’t checking a single transaction. It’s asking, “Has the total amount from this specific source account exceeded $5,000 in the last hour?” It automatically personalizes the monitoring to each user, dramatically increasing accuracy and reducing false positives.