Surveillance (KYT)
Real-time market surveillance and Know Your Transaction monitoring with wash trading, structuring, velocity, and parabolic price spike detection.
Surveillance — KYT (Know Your Transaction)
The surveillance engine monitors all trading activity in real-time for market manipulation, transaction structuring, unusual velocity, and abnormal price movements.
Alert Types
| Alert | Description | Severity |
|---|---|---|
wash_trading | Same account trading against itself (same symbol, opposite sides, similar quantity/price) | High |
large_trade | Single trade exceeds notional threshold | Medium-Critical |
structuring | Multiple trades between 80-99% of CTR threshold in 24h (smurfing) | High |
velocity | Trade frequency exceeds max per window for an account | Medium |
price_spike | Abnormal price acceleration detected (parabolic/exponential movement) | Medium-Critical |
Wash Trading Detection
Detects when the same account trades against itself:
- Same symbol, opposite sides (buy vs sell)
- Quantity within 10% tolerance
- Price within 5% tolerance
- Within configurable time window (default: 5 minutes)
Structuring / Smurfing Detection
Detects transaction structuring to avoid Currency Transaction Report (CTR) thresholds:
- Monitors 24-hour rolling window per account
- Flags when 3+ trades fall between 80-99% of CTR threshold
- Default CTR threshold: $10,000
Example: An account making trades of 9,200, 9,100 in 24 hours triggers structuring alert.
Velocity Monitoring
Detects unusually high trading frequency:
- Configurable window (default: 1 minute)
- Configurable max trades per window (default: 10)
- Deduplicates alerts per account per window
Parabolic Price Spike Detection
Uses second-derivative (quadratic) analysis to detect parabolic/exponential price movements that indicate potential market manipulation or flash crashes.
Algorithm
1. Collect price history for symbol within window (default: 5 min)
2. Split window into two halves at midpoint
3. Compute rate of change for each half:
rate1 = (midPrice - firstPrice) / dt1 # first half
rate2 = (lastPrice - midPrice) / dt2 # second half
4. Compute acceleration (2nd derivative):
accel = rate2 - rate1
5. Alert conditions:
- |pctChange| >= threshold (default 10%) -> high/critical
- |accel%| >= accelThreshold AND |pctChange| >= threshold/2 -> mediumSeverity Levels
| Condition | Severity |
|---|---|
| Price move >= 2x threshold | critical |
| Price move >= threshold | high |
| Acceleration detected with move >= threshold/2 | medium |
This catches both sudden pumps (price doubling in minutes) and parabolic crashes where the rate of decline is itself accelerating.
Configuration
type KYTConfig struct {
CTRThreshold float64 // $10,000 default
LargeTradeThreshold float64 // $50,000 default
VelocityWindow time.Duration // 1 minute default
VelocityMaxTrades int // 10 default
StructuringWindow time.Duration // 24 hours default
StructuringMinTxns int // 3 default
PriceSpikeWindow time.Duration // 5 minutes default
PriceSpikeMaxPct float64 // 10% default
PriceSpikeAccelPct float64 // 5% default
}API
List Alerts
GET /api/v1/admin/surveillance/alerts?status=openResponse:
[
{
"id": "alert-uuid",
"type": "price_spike",
"severity": "critical",
"status": "open",
"symbol": "BTC-USD",
"account_id": "",
"details": "abnormal price acceleration: 25.3% move with 12.1% acceleration",
"created_at": "2026-03-07T10:30:00Z"
}
]Test Coverage
16 passing tests covering:
- Wash trading (same account, opposite sides, similar params)
- No false positives (different quantities, same side)
- Large trade alerts and threshold boundaries
- Structuring detection and threshold boundaries
- Velocity monitoring
- Price spike detection (pump)
- Stable price non-triggering
- Parabolic crash detection (accelerating decline)
Source
luxfi/cex/pkg/surveillance/surveillance.goluxfi/cex/pkg/surveillance/surveillance_test.go
How is this guide?
Last updated on