Hanzo

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

AlertDescriptionSeverity
wash_tradingSame account trading against itself (same symbol, opposite sides, similar quantity/price)High
large_tradeSingle trade exceeds notional thresholdMedium-Critical
structuringMultiple trades between 80-99% of CTR threshold in 24h (smurfing)High
velocityTrade frequency exceeds max per window for an accountMedium
price_spikeAbnormal 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 8,500,8,500, 9,200, 8,800,8,800, 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 -> medium

Severity Levels

ConditionSeverity
Price move >= 2x thresholdcritical
Price move >= thresholdhigh
Acceleration detected with move >= threshold/2medium

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=open

Response:

[
  {
    "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.go
  • luxfi/cex/pkg/surveillance/surveillance_test.go

How is this guide?

Last updated on

On this page