Skip to main content

Executive Summary

This guide equips Technical Business Analysts with the frameworks, SQL patterns, and regulatory intelligence needed to conduct effective transaction monitoring remediation in Australian banking. Drawing from AUSTRAC’s 205 guidance documents across 10 industries, it provides actionable detection patterns for the most common money laundering typologies and compliance gaps. What You’ll Learn:
  • The Australian regulatory context and AUSTRAC enforcement priorities
  • 36+ production-ready SQL queries for detecting suspicious patterns
  • Industry-specific red flags across banking, digital currency, remittance, and more
  • Documentation standards for audit-ready remediation findings
  • Lessons from billion-dollar enforcement actions (CBA, Westpac, Crown)

Table of Contents

Part 1: Understanding Your Mission
  • The regulatory imperative
  • What remediation actually means
  • Your core responsibilities
Part 2: The SQL Toolkit
  • 12 fundamental AML detection patterns
  • 16 industry-specific queries
  • Advanced optimization techniques
  • Performance strategies for million-record populations
Part 3: Red Flag Taxonomy
  • AUSTRAC’s typology framework
  • Industry-specific indicators
  • Cross-industry network patterns
  • Enforcement lessons learned
Part 4: Industry Deep Dives
  • Banking (correspondent, trade finance, private banking)
  • Digital currency (crypto off-ramping, unregistered DCE)
  • Remittance (hawala, conflict zones, networks)
  • Casino (integration, third-party funding)
  • Professional services (lawyers, accountants, real estate)
  • Superannuation (early release fraud, SMSF abuse)
  • Bullion (precious metals laundering)
Part 5: Delivering Results
  • AUSTRAC reporting obligations (TTR, IFTI, SMR)
  • Documentation standards
  • Stakeholder communication
  • Quality assurance framework
Part 6: Practical Application
  • Common pitfalls to avoid
  • Your first 90 days
  • Career development
  • Continuous improvement

Part 1: Understanding Your Mission

The Challenge You’re Stepping Into

Picture this: hundreds of thousands of transactions flagged over years, each representing a potential regulatory breach. AUSTRAC’s expectations are clear—demonstrate you’ve looked back, looked hard, and taken action. But here’s the reality: legacy systems, incomplete data lineage, and the sheer volume of incidents mean this isn’t just about ticking boxes. It’s about building a machine that learns, adapts, and closes the gap between what happened and what you can prove. You’re not just analysing data. You’re reconstructing history under regulatory scrutiny, one SQL query at a time.

The Australian Context

Following high-profile AUSTRAC enforcement actions (CBA 700M,Westpac700M, Westpac 1.3B, Crown $450M), Australian banks face unprecedented scrutiny on Anti-Money Laundering and Counter-Terrorism Financing (AML/CTF) controls. Transaction monitoring remediation programs exist because:
  • Historical systems failed to detect or escalate suspicious activity
  • Rule configurations were inadequate or poorly calibrated
  • Data quality issues prevented effective monitoring
  • Process gaps meant alerts weren’t properly investigated
Your program isn’t optional—it’s often an enforceable undertaking, supervised by regulators and audited externally.

What “Remediation” Actually Means

Remediation = Look Back + Fix Forward Look Back: Retrospectively analyse historical transactions using improved rules, better data, and enhanced detection logic to identify what was missed. Fix Forward: Implement sustainable controls, updated procedures, and governance to prevent future failures. Your role focuses heavily on the “look back”—but always with an eye to building reusable, scalable approaches.

Your Core Responsibilities Decoded

1. Analyse remediation items and identify red flags This means:
  • Reviewing batches of flagged transactions (often 10,000+ per sprint)
  • Applying risk typologies (structuring, trade-based laundering, sanctions evasion)
  • Distinguishing between genuine suspicious activity and false positives
  • Documenting your reasoning with audit-ready evidence
2. Use SQL to extract, validate, and interpret data This means:
  • Writing complex queries across multiple data sources (core banking, payment rails, customer data)
  • Validating data quality and completeness before analysis
  • Creating repeatable analytical scripts that others can leverage
  • Translating business rules into SQL logic
3. Provide analytical insights to support triage and decision-making This means:
  • Creating dashboards and summary reports for risk teams
  • Identifying patterns that indicate systemic issues vs. isolated incidents
  • Recommending prioritization criteria (risk-weighted, customer impact, regulatory sensitivity)
  • Supporting decisioning on whether to file Suspicious Matter Reports (SMRs)

Part 2: The SQL Toolkit

Core Principle: Detection Over Volume

Effective remediation isn’t about analyzing every transaction independently—it’s about identifying patterns that indicate money laundering typologies recognized by AUSTRAC. These queries represent decades of regulatory intelligence distilled into actionable detection logic.

Section 2A: Fundamental AML Detection Patterns

These 12 patterns form your foundation. Master these before moving to industry-specific queries.

Pattern 1: Structuring Detection (Just-Below-Threshold)

The most common AML pattern - customers deliberately keeping transactions under $10,000 AUD to avoid TTR reporting.
-- Detect customers making multiple transactions just below $10,000 threshold
-- Classic "structuring" behavior to avoid AUSTRAC TTR reporting
WITH daily_activity AS (
  SELECT
    customer_id,
    CAST(transaction_timestamp AS DATE) as txn_date,
    COUNT(*) as daily_txn_count,
    SUM(amount) as daily_total,
    COUNT(CASE WHEN amount >= 9000 AND amount < 10000 THEN 1 END) as near_threshold_count,
    AVG(amount) as avg_txn_amount
  FROM transactions
  WHERE transaction_type IN ('CASH_DEPOSIT', 'TRANSFER')
    AND transaction_timestamp >= DATEADD(month, -6, GETDATE())
  GROUP BY customer_id, CAST(transaction_timestamp AS DATE)
)
SELECT
  da.customer_id,
  c.customer_name,
  c.customer_type,
  COUNT(DISTINCT da.txn_date) as flagged_days,
  SUM(da.daily_txn_count) as total_txns,
  SUM(da.daily_total) as total_amount,
  AVG(da.near_threshold_count) as avg_near_threshold_per_day
FROM daily_activity da
JOIN customers c ON da.customer_id = c.customer_id
WHERE da.daily_txn_count >= 3
  AND da.near_threshold_count >= 2
  AND da.daily_total >= 20000
GROUP BY da.customer_id, c.customer_name, c.customer_type
HAVING COUNT(DISTINCT da.txn_date) >= 3
ORDER BY total_amount DESC;

Pattern 2: Rapid Movement (Layering)

Money transferred through intermediate accounts quickly to obscure origin.
-- Detect rapid movement through intermediary accounts
WITH transaction_pairs AS (
  SELECT
    t1.account_id,
    t1.amount as inbound_amount,
    t1.transaction_timestamp as inbound_time,
    t2.amount as outbound_amount,
    t2.transaction_timestamp as outbound_time,
    DATEDIFF(minute, t1.transaction_timestamp, t2.transaction_timestamp) as time_diff_minutes
  FROM transactions t1
  JOIN transactions t2 ON t1.account_id = t2.account_id
  WHERE t1.transaction_type = 'CREDIT'
    AND t2.transaction_type = 'DEBIT'
    AND t2.transaction_timestamp > t1.transaction_timestamp
    AND t2.transaction_timestamp <= DATEADD(hour, 2, t1.transaction_timestamp)
    AND t1.amount >= 5000
    AND ABS(t1.amount - t2.amount) / t1.amount <= 0.05
)
SELECT
  account_id,
  a.customer_id,
  c.customer_name,
  COUNT(*) as layering_instances,
  SUM(inbound_amount) as total_inflows,
  AVG(time_diff_minutes) as avg_time_lag_minutes
FROM transaction_pairs tp
JOIN accounts a ON tp.account_id = a.account_id
JOIN customers c ON a.customer_id = c.customer_id
GROUP BY account_id, a.customer_id, c.customer_name
HAVING COUNT(*) >= 5
ORDER BY total_inflows DESC;

Pattern 3: Circular Money Flow

Using recursive CTE to detect funds returning to originator after multiple hops.
-- Detect circular money flows (funds return to origin)
WITH RECURSIVE money_flow AS (
  SELECT
    transaction_id,
    account_id as origin_account,
    counterparty_account as next_account,
    amount as original_amount,
    transaction_timestamp,
    1 as hop_count,
    CAST(account_id AS VARCHAR(1000)) as path,
    0 as is_circular
  FROM transactions
  WHERE transaction_type = 'TRANSFER'
    AND amount >= 5000
    AND transaction_timestamp >= DATEADD(month, -3, GETDATE())

  UNION ALL

  SELECT
    mf.transaction_id,
    mf.origin_account,
    t.counterparty_account,
    t.amount,
    t.transaction_timestamp,
    mf.hop_count + 1,
    mf.path + '|' + CAST(t.counterparty_account AS VARCHAR),
    CASE WHEN t.counterparty_account = mf.origin_account THEN 1 ELSE 0 END
  FROM money_flow mf
  JOIN transactions t ON mf.next_account = t.account_id
  WHERE mf.hop_count < 10
    AND mf.is_circular = 0
    AND t.transaction_timestamp > mf.transaction_timestamp
    AND t.amount >= mf.original_amount * 0.75
)
SELECT
  origin_account,
  COUNT(*) as circular_flows,
  AVG(hop_count) as avg_hops,
  SUM(original_amount) as total_amount
FROM money_flow
WHERE is_circular = 1
GROUP BY origin_account
ORDER BY total_amount DESC;

Pattern 4: Cross-Border High-Risk Jurisdiction

-- Transactions to AUSTRAC high-risk jurisdictions
SELECT
  t.customer_id,
  c.customer_name,
  t.beneficiary_country,
  COUNT(*) as txn_count,
  SUM(t.amount) as total_value,
  COUNT(DISTINCT t.beneficiary_name) as unique_beneficiaries
FROM transactions t
JOIN customers c ON t.customer_id = c.customer_id
JOIN risk_jurisdictions rj ON t.beneficiary_country = rj.country_code
WHERE rj.risk_rating IN ('High', 'Very High')
  AND t.transaction_type = 'INTL_TRANSFER'
  AND t.transaction_date >= DATEADD(year, -1, GETDATE())
GROUP BY t.customer_id, c.customer_name, t.beneficiary_country
HAVING COUNT(*) >= 3 OR SUM(t.amount) >= 50000
ORDER BY total_value DESC;

Pattern 5: Dormant Account Reactivation

-- Accounts inactive for 180+ days suddenly reactivating
SELECT
  account_id,
  customer_id,
  DATEDIFF(day, last_activity_before_dormancy, recent_activity_date) as dormancy_days,
  recent_txn_count,
  recent_amount,
  recent_amount / NULLIF(historical_avg_monthly, 0) as activity_spike_ratio
FROM (
  SELECT
    account_id,
    customer_id,
    MAX(CASE WHEN transaction_date < DATEADD(month, -6, GETDATE())
             THEN transaction_date END) as last_activity_before_dormancy,
    MIN(CASE WHEN transaction_date >= DATEADD(month, -1, GETDATE())
             THEN transaction_date END) as recent_activity_date,
    COUNT(CASE WHEN transaction_date >= DATEADD(month, -1, GETDATE())
               THEN 1 END) as recent_txn_count,
    SUM(CASE WHEN transaction_date >= DATEADD(month, -1, GETDATE())
             THEN amount ELSE 0 END) as recent_amount,
    AVG(CASE WHEN transaction_date < DATEADD(month, -6, GETDATE())
             THEN amount END) as historical_avg_monthly
  FROM transactions
  GROUP BY account_id, customer_id
) dormancy_analysis
WHERE dormancy_days >= 180
  AND recent_amount >= 10000
ORDER BY recent_amount DESC;

Pattern 6: Data Quality Assessment

-- Critical data quality checks before analysis
SELECT
  'Missing Customer ID' as issue,
  COUNT(*) as record_count,
  CAST(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM transactions) AS DECIMAL(5,2)) as pct
FROM transactions WHERE customer_id IS NULL
UNION ALL
SELECT 'Invalid Date', COUNT(*),
  CAST(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM transactions) AS DECIMAL(5,2))
FROM transactions WHERE transaction_date > GETDATE()
UNION ALL
SELECT 'Missing Amount', COUNT(*),
  CAST(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM transactions) AS DECIMAL(5,2))
FROM transactions WHERE amount IS NULL OR amount = 0
ORDER BY pct DESC;

Pattern 7: Beneficiary Network Analysis

-- Shared beneficiaries across multiple customers (coordination)
SELECT
  beneficiary_name,
  beneficiary_country,
  COUNT(DISTINCT customer_id) as unique_senders,
  COUNT(*) as total_transactions,
  SUM(amount) as total_value
FROM transactions
WHERE transaction_type = 'INTL_TRANSFER'
  AND transaction_date >= DATEADD(year, -1, GETDATE())
GROUP BY beneficiary_name, beneficiary_country
HAVING COUNT(DISTINCT customer_id) >= 3
  AND SUM(amount) >= 100000
ORDER BY unique_senders DESC;

Pattern 8: Time-Based Anomalies

-- Off-hours transaction patterns (automated/evasion)
SELECT
  customer_id,
  COUNT(CASE WHEN DATEPART(hour, transaction_timestamp) BETWEEN 0 AND 5
             THEN 1 END) as late_night_txns,
  COUNT(*) as total_txns,
  CAST(COUNT(CASE WHEN DATEPART(hour, transaction_timestamp) BETWEEN 0 AND 5
                  THEN 1 END) * 100.0 / COUNT(*) AS DECIMAL(5,2)) as pct_late_night
FROM transactions
WHERE transaction_date >= DATEADD(month, -6, GETDATE())
GROUP BY customer_id
HAVING COUNT(CASE WHEN DATEPART(hour, transaction_timestamp) BETWEEN 0 AND 5
                  THEN 1 END) >= 10
ORDER BY late_night_txns DESC;

Pattern 9: Just-In-Time Funding (Mule Accounts)

-- Accounts that receive and immediately disburse funds
SELECT
  account_id,
  AVG(running_balance) as avg_balance,
  SUM(CASE WHEN balance_impact > 0 THEN balance_impact ELSE 0 END) as total_inflows,
  SUM(CASE WHEN balance_impact < 0 THEN ABS(balance_impact) ELSE 0 END) as total_outflows,
  total_inflows / NULLIF(avg_balance, 0) as turnover_ratio
FROM (
  SELECT
    account_id,
    CASE WHEN transaction_type = 'CREDIT' THEN amount ELSE -amount END as balance_impact,
    SUM(CASE WHEN transaction_type = 'CREDIT' THEN amount ELSE -amount END)
      OVER (PARTITION BY account_id ORDER BY transaction_timestamp) as running_balance
  FROM transactions
  WHERE transaction_date >= DATEADD(month, -3, GETDATE())
) balance_analysis
GROUP BY account_id
HAVING AVG(running_balance) < 5000
  AND SUM(CASE WHEN balance_impact > 0 THEN balance_impact ELSE 0 END) > 100000
  AND total_inflows / NULLIF(avg_balance, 0) > 20
ORDER BY turnover_ratio DESC;

Pattern 10: Smurfing Detection

-- Coordinated structuring across multiple entities
SELECT
  beneficiary_name,
  CAST(transaction_timestamp AS DATE) as txn_date,
  COUNT(DISTINCT customer_id) as unique_senders,
  COUNT(*) as txn_count,
  SUM(amount) as daily_total
FROM transactions
WHERE transaction_type IN ('TRANSFER', 'INTL_TRANSFER')
  AND amount < 10000
  AND transaction_date >= DATEADD(month, -6, GETDATE())
GROUP BY beneficiary_name, CAST(transaction_timestamp AS DATE)
HAVING COUNT(DISTINCT customer_id) >= 3
  AND SUM(amount) >= 20000
ORDER BY daily_total DESC;

Pattern 11: Customer Deviation from Baseline

-- Compare recent vs historical behavior
WITH historical AS (
  SELECT customer_id, AVG(amount) as hist_avg, COUNT(*) as hist_count
  FROM transactions
  WHERE transaction_date BETWEEN DATEADD(month, -7, GETDATE())
                              AND DATEADD(month, -1, GETDATE())
  GROUP BY customer_id
),
recent AS (
  SELECT customer_id, AVG(amount) as recent_avg, COUNT(*) as recent_count
  FROM transactions
  WHERE transaction_date >= DATEADD(month, -1, GETDATE())
  GROUP BY customer_id
)
SELECT
  r.customer_id,
  h.hist_avg,
  r.recent_avg,
  (r.recent_avg - h.hist_avg) / h.hist_avg * 100 as avg_change_pct
FROM recent r
JOIN historical h ON r.customer_id = h.customer_id
WHERE r.recent_avg > h.hist_avg * 1.5
ORDER BY avg_change_pct DESC;

Pattern 12: Round-Amount Analysis

-- Excessive use of round numbers (artificial transactions)
SELECT
  customer_id,
  COUNT(*) as total_txns,
  COUNT(CASE WHEN amount % 1000 = 0 THEN 1 END) as round_txns,
  CAST(COUNT(CASE WHEN amount % 1000 = 0 THEN 1 END) * 100.0 / COUNT(*)
       AS DECIMAL(5,2)) as pct_round
FROM transactions
WHERE transaction_date >= DATEADD(month, -6, GETDATE())
  AND amount >= 1000
GROUP BY customer_id
HAVING COUNT(*) >= 10
  AND CAST(COUNT(CASE WHEN amount % 1000 = 0 THEN 1 END) * 100.0 / COUNT(*)
           AS DECIMAL(5,2)) >= 60
ORDER BY pct_round DESC;

Section 2B: Industry-Specific Detection Queries

Building on AUSTRAC’s 205 guidance documents, these queries target sector-specific risks.

Banking: Correspondent Banking Nested Transactions

-- Identify transactions with unclear ultimate originators (sanctions risk)
SELECT
  t.transaction_id,
  t.correspondent_bank,
  t.ordering_customer,
  t.amount,
  CASE WHEN t.ordering_customer IS NULL THEN 'CRITICAL - Missing originator'
       ELSE 'OK' END as risk_flag
FROM international_transactions t
WHERE t.transaction_type = 'CORRESPONDENT_BANKING'
  AND (t.ordering_customer IS NULL OR t.ordering_customer IN ('UNKNOWN', 'VARIOUS'))
ORDER BY t.amount DESC;

Banking: Trade Finance Documentation Mismatch

-- Detect over/under invoicing in trade finance
SELECT
  tf.customer_id,
  tf.lc_reference,
  tf.invoice_amount,
  tf.payment_amount,
  ABS(tf.invoice_amount - tf.payment_amount) / tf.invoice_amount * 100 as variance_pct,
  CASE WHEN sd.lc_reference IS NULL THEN 'Missing shipping docs' END as doc_status
FROM trade_finance_transactions tf
LEFT JOIN shipping_documents sd ON tf.lc_reference = sd.lc_reference
WHERE tf.invoice_amount >= 50000
  AND (ABS(tf.invoice_amount - tf.payment_amount) / tf.invoice_amount > 0.15
       OR sd.lc_reference IS NULL)
ORDER BY variance_pct DESC;

Banking: Cash-Intensive Business Revenue Check

-- Compare cash deposits to declared revenue
SELECT
  c.customer_id,
  c.business_type,
  c.declared_annual_revenue / 12 as expected_monthly,
  AVG(monthly_cash) as actual_monthly_cash,
  AVG(monthly_cash) / (c.declared_annual_revenue / 12) as ratio
FROM customers c
JOIN (
  SELECT customer_id, DATE_TRUNC('month', transaction_date) as month,
         SUM(amount) as monthly_cash
  FROM transactions
  WHERE transaction_type = 'CASH_DEPOSIT'
  GROUP BY customer_id, DATE_TRUNC('month', transaction_date)
) cash ON c.customer_id = cash.customer_id
WHERE c.customer_type = 'BUSINESS'
GROUP BY c.customer_id, c.business_type, c.declared_annual_revenue
HAVING AVG(monthly_cash) > c.declared_annual_revenue / 12 * 1.5
ORDER BY ratio DESC;

Digital Currency: Crypto Off-Ramping

-- Exchange deposits immediately transferred elsewhere
WITH crypto_deposits AS (
  SELECT
    customer_id,
    transaction_date,
    amount,
    LEAD(transaction_date) OVER (PARTITION BY customer_id
                                  ORDER BY transaction_date) as next_date,
    LEAD(transaction_type) OVER (PARTITION BY customer_id
                                  ORDER BY transaction_date) as next_type
  FROM transactions
  WHERE counterparty_name IN ('COINBASE', 'BINANCE', 'INDEPENDENT RESERVE')
)
SELECT
  customer_id,
  COUNT(*) as crypto_deposits,
  SUM(amount) as total_value,
  COUNT(CASE WHEN DATEDIFF(hour, transaction_date, next_date) <= 24
                  AND next_type = 'DEBIT' THEN 1 END) as rapid_exits
FROM crypto_deposits
GROUP BY customer_id
HAVING COUNT(CASE WHEN DATEDIFF(hour, transaction_date, next_date) <= 24
                      AND next_type = 'DEBIT' THEN 1 END) >= 10
ORDER BY total_value DESC;

Digital Currency: Unregistered DCE Provider

-- Customers potentially operating as unlicensed exchanges
SELECT
  c.customer_id,
  c.business_type,
  COUNT(DISTINCT t.counterparty_id) as unique_counterparties,
  COUNT(*) as crypto_txns,
  SUM(t.amount) as total_volume
FROM customers c
JOIN transactions t ON c.customer_id = t.customer_id
WHERE (c.business_type LIKE '%CRYPTO%' OR t.transaction_description LIKE '%bitcoin%')
  AND c.customer_id NOT IN (SELECT customer_id FROM austrac_registered_entities)
GROUP BY c.customer_id, c.business_type
HAVING COUNT(DISTINCT t.counterparty_id) >= 10 AND COUNT(*) >= 50
ORDER BY total_volume DESC;

Remittance: Hawala Same-Day Flow

-- Receive and send similar amounts same day (value transfer system)
SELECT
  customer_id,
  DATE(transaction_date) as txn_date,
  SUM(CASE WHEN transaction_type = 'CREDIT' THEN amount ELSE 0 END) as inflow,
  SUM(CASE WHEN transaction_type = 'DEBIT' THEN amount ELSE 0 END) as outflow,
  ABS(inflow - outflow) as net_difference
FROM transactions
WHERE transaction_date >= DATEADD(month, -6, GETDATE())
GROUP BY customer_id, DATE(transaction_date)
HAVING ABS(inflow - outflow) < GREATEST(inflow, outflow) * 0.10
  AND inflow >= 5000
ORDER BY inflow DESC;

Remittance: Shared Beneficiary Networks

-- Multiple remitters using same beneficiaries (coordination)
SELECT
  beneficiary_name,
  beneficiary_country,
  COUNT(DISTINCT customer_id) as unique_senders,
  SUM(amount) as total_value,
  STRING_AGG(DISTINCT customer_name, '; ') as senders
FROM transactions t
JOIN customers c ON t.customer_id = c.customer_id
WHERE c.business_type LIKE '%REMIT%'
  AND t.transaction_type = 'INTL_TRANSFER'
GROUP BY beneficiary_name, beneficiary_country
HAVING COUNT(DISTINCT customer_id) >= 3
ORDER BY unique_senders DESC;

Casino: Integration Pattern Detection

-- Cash withdrawal → casino → similar deposit (minimal loss)
WITH casino_cycles AS (
  SELECT
    t1.customer_id,
    t1.amount as withdrawal,
    t3.amount as deposit,
    t3.amount / t1.amount as return_ratio
  FROM transactions t1
  JOIN transactions t2 ON t1.customer_id = t2.customer_id
    AND t2.counterparty_name LIKE '%CASINO%'
    AND t2.transaction_date BETWEEN t1.transaction_date
                                AND DATEADD(day, 3, t1.transaction_date)
  JOIN transactions t3 ON t1.customer_id = t3.customer_id
    AND t3.transaction_type = 'CREDIT'
    AND t3.transaction_date BETWEEN t2.transaction_date
                                AND DATEADD(day, 7, t2.transaction_date)
  WHERE t1.transaction_type = 'DEBIT' AND t1.amount >= 5000
)
SELECT
  customer_id,
  COUNT(*) as cycles,
  AVG(return_ratio) as avg_return_ratio
FROM casino_cycles
GROUP BY customer_id
HAVING AVG(return_ratio) >= 0.90 AND COUNT(*) >= 5
ORDER BY cycles DESC;

Professional Services: Trust Account Velocity

-- Lawyer trust accounts with excessive activity
SELECT
  c.customer_id,
  c.customer_name,
  COUNT(*) as high_activity_days,
  AVG(daily_credits) as avg_daily_credits,
  AVG(daily_txn_count) as avg_txns_per_day
FROM customers c
JOIN accounts a ON c.customer_id = a.customer_id
JOIN (
  SELECT account_id, DATE(transaction_date) as txn_date,
         COUNT(*) as daily_txn_count,
         SUM(CASE WHEN transaction_type = 'CREDIT' THEN amount ELSE 0 END) as daily_credits
  FROM transactions
  WHERE transaction_date >= DATEADD(month, -6, GETDATE())
  GROUP BY account_id, DATE(transaction_date)
) daily ON a.account_id = daily.account_id
WHERE c.occupation LIKE '%LAWYER%' AND a.account_type = 'TRUST'
  AND (daily.daily_txn_count >= 5 OR daily.daily_credits >= 50000)
GROUP BY c.customer_id, c.customer_name
HAVING COUNT(*) >= 10
ORDER BY avg_txns_per_day DESC;

Superannuation: Early Release Fraud

-- Super access before preservation age
SELECT
  c.customer_id,
  DATEDIFF(year, c.date_of_birth, GETDATE()) as age,
  COUNT(sr.claim_id) as claims,
  SUM(sr.amount_released) as total_released
FROM customers c
JOIN super_releases sr ON c.customer_id = sr.customer_id
WHERE DATEDIFF(year, c.date_of_birth, sr.claim_date) < 60
GROUP BY c.customer_id, c.date_of_birth
HAVING COUNT(sr.claim_id) >= 2 OR SUM(sr.amount_released) >= 30000
ORDER BY total_released DESC;

Bullion: Round-Tripping Detection

-- Cash → gold purchase → quick resale
SELECT
  customer_id,
  COUNT(*) as bullion_txns,
  SUM(CASE WHEN transaction_type = 'DEBIT' THEN amount ELSE 0 END) as purchases,
  COUNT(CASE WHEN transaction_type = 'CREDIT'
                  AND prev_txn_type = 'DEBIT'
                  AND DATEDIFF(day, prev_date, transaction_date) <= 30
             THEN 1 END) as quick_turnarounds
FROM (
  SELECT
    customer_id,
    transaction_date,
    transaction_type,
    amount,
    LAG(transaction_date) OVER (PARTITION BY customer_id ORDER BY transaction_date) as prev_date,
    LAG(transaction_type) OVER (PARTITION BY customer_id ORDER BY transaction_date) as prev_txn_type
  FROM transactions
  WHERE counterparty_name LIKE '%BULLION%' OR counterparty_name LIKE '%GOLD%'
) bullion_activity
GROUP BY customer_id
HAVING SUM(CASE WHEN transaction_type = 'DEBIT' THEN amount ELSE 0 END) >= 50000
  AND quick_turnarounds >= 3
ORDER BY purchases DESC;

Cross-Industry: PEP Wealth Monitoring

-- Politically Exposed Persons with unexplained wealth
SELECT
  c.customer_id,
  p.position,
  p.estimated_salary,
  SUM(CASE WHEN t.transaction_type = 'CREDIT' THEN t.amount ELSE 0 END) as annual_inflows,
  annual_inflows / p.estimated_salary as wealth_ratio
FROM customers c
JOIN pep_screening p ON c.customer_id = p.customer_id
JOIN transactions t ON c.customer_id = t.customer_id
WHERE p.is_active_pep = 'Y'
  AND t.transaction_date >= DATEADD(year, -1, GETDATE())
GROUP BY c.customer_id, p.position, p.estimated_salary
HAVING annual_inflows > p.estimated_salary * 2
ORDER BY wealth_ratio DESC;

Section 2C: Advanced SQL Optimization

Window Functions for Efficiency

-- Running totals and moving averages without self-joins
SELECT
  customer_id,
  transaction_date,
  amount,
  SUM(amount) OVER (PARTITION BY customer_id
                    ORDER BY transaction_date) as cumulative_amount,
  AVG(amount) OVER (PARTITION BY customer_id
                    ORDER BY transaction_date
                    ROWS BETWEEN 29 PRECEDING AND CURRENT ROW) as moving_avg_30d,
  DENSE_RANK() OVER (PARTITION BY customer_id
                     ORDER BY amount DESC) as amount_rank
FROM transactions;

Indexing Strategy

-- Critical indexes for remediation queries
CREATE INDEX idx_txn_customer_date
  ON transactions(customer_id, transaction_date)
  INCLUDE (amount, transaction_type);

CREATE INDEX idx_txn_beneficiary
  ON transactions(beneficiary_name, beneficiary_country, transaction_date);

CREATE INDEX idx_txn_amount_type
  ON transactions(amount, transaction_type, transaction_date)
  WHERE amount >= 5000;

Batch Processing Template

-- Process large populations in manageable chunks
DECLARE @BatchSize INT = 10000;
DECLARE @Offset INT = 0;

WHILE @Offset < (SELECT COUNT(*) FROM remediation_incidents)
BEGIN
  INSERT INTO remediation_results (incident_id, risk_score)
  SELECT incident_id,
         CASE WHEN txn_count >= 5 THEN 'HIGH' ELSE 'LOW' END
  FROM remediation_incidents
  ORDER BY incident_id
  OFFSET @Offset ROWS FETCH NEXT @BatchSize ROWS ONLY;

  SET @Offset = @Offset + @BatchSize;
END;

Part 3: Red Flag Taxonomy

AUSTRAC’s Typology Framework

Based on 205 guidance documents across 10 industries, these are priority patterns: Structuring & Smurfing
  • Multiple transactions just below $10,000 AUD threshold
  • Coordinated deposits across accounts
  • Rapid cash deposits followed by transfers
Trade-Based Money Laundering
  • Over/under-invoicing vs industry benchmarks
  • Phantom shipments without trade documentation
  • Circular trading of same goods
Layering & Commingling
  • Complex transfer chains without business purpose
  • Mixing illicit with legitimate funds
  • Multiple intermediaries or shell companies
Sanctions Evasion
  • Transactions to sanctioned jurisdictions
  • Name variations matching sanctions lists
  • Front companies masking beneficial owners
Casino Integration
  • Large cash buy-ins with minimal gaming
  • Chip purchases at one venue, cash-out at another
  • Third-party chip redemptions
Digital Currency Schemes
  • Rapid fiat-to-crypto conversions
  • Mixing services or tumblers
  • P2P trading to avoid exchange reporting
  • Multiple wallet addresses
Professional Facilitators
  • Lawyers/accountants structuring transactions
  • Trust and company service providers
  • Real estate agents in cash settlements
  • Remittance dealers with unexplained volumes
Remittance & Hawala
  • High-volume, low-value to same jurisdictions
  • Same-day receive and send patterns
  • Beneficiaries in conflict zones
  • Transactions reversing normal flows
Superannuation Fraud
  • Early release on false grounds
  • SMSF non-arm’s length transactions
  • Identity fraud for super access
  • Illegal early access promoters
Bullion Laundering
  • Cash purchases of precious metals
  • Rapid buy-sell cycles
  • Purchases inconsistent with wealth profile

Industry-Specific Risk Concentrations

Banking (17 AUSTRAC guidance docs):
  • Correspondent banking nested transactions
  • Trade finance documentation mismatches
  • Private banking unclear source of wealth
  • Cash-intensive businesses exceeding declared revenue
Digital Currency (5 docs):
  • Crypto off-ramping patterns
  • Unregistered DCE providers
  • Privacy coin usage
  • Unhosted wallet transactions
Remittance (8 docs):
  • Hawala-style operations
  • Shared beneficiary networks
  • Conflict zone transfers
  • Unlicensed operators
Casino (4 docs):
  • Integration with minimal loss
  • Third-party funding
  • Chip-walking schemes
  • Junket participation
Professional Services (6 docs):
  • Trust account rapid turnover
  • Client fund commingling
  • Property settlement cash components
  • Nominee arrangements
Cross-Industry Critical:
  • PEPs with unexplained wealth
  • Complex beneficial ownership structures
  • Negative media during transaction periods
  • Related party networks

Part 4: AUSTRAC Reporting & Documentation

Reporting Obligations from Remediation

1. Threshold Transaction Reports (TTRs)

Trigger: Physical currency ≥ $10,000 AUD When Remediation Requires Late Filing:
  • Missed cash deposits/withdrawals ≥$10k
  • Multiple cash transactions that should have been aggregated
  • Structuring patterns identified retrospectively
Action: File late TTR immediately, document delay reason, consider SMR if deliberate structuring Example: “Customer made 3 cash deposits on same day: 4,500,4,500, 3,800, 2,200=2,200 = 10,500 total. No TTR filed. Action: File late TTR + SMR for structuring.”

2. International Funds Transfer Instructions (IFTIs)

Trigger: ALL international transfers (no minimum) When Remediation Requires Late Filing:
  • Any SWIFT transfer without IFTI
  • Missing correspondent banking reports
  • Incomplete IFTI data fields
Critical: CBA and Westpac penalties centered on missed IFTIs

3. Suspicious Matter Reports (SMRs)

Trigger: Reasonable grounds to suspect ML/TF When Required:
  • Structuring to avoid reporting
  • Transactions inconsistent with profile
  • Multiple red flags combining
  • Links to criminal activity
Timeframe: 3 business days (24 hours if terrorism financing) SMR Template Structure:
GROUNDS FOR SUSPICION:
[Specific pattern identified during remediation]

TIMELINE:
[Date range and key events]

CUSTOMER PROFILE:
[Occupation, income, relationship tenure]

TRANSACTIONS ANALYZED:
[Count, value, patterns observed]

RED FLAGS IDENTIFIED:
[Specific AUSTRAC typology matches]

ANALYSIS CONDUCTED:
[Queries run, comparisons made]

CONCLUSION:
[Why legitimate explanations insufficient]

Documentation Standards

Every incident requires:
  1. Incident Summary: ID, customer, alert date, analyst, risk score
  2. Transaction Analysis: Date range, count, value, patterns
  3. Customer Context: Occupation, income, products, history
  4. Due Diligence Review: What was available at transaction time
  5. External Checks: Media, sanctions, PEP, law enforcement
  6. Decision Rationale: Why suspicious or not, typology match
  7. Actions Taken: SMR filed, TTR filed, restrictions applied
  8. QA Sign-off: Peer review, compliance approval
Documentation Quality Standards: Poor: “Customer made several transactions to high-risk country” Good: “Customer made 8 transactions totaling 87,400tobeneficiariesinMalaysia(FATFIncreasedMonitoringjurisdiction)betweenJanMar2022,inconsistentwithstatedoccupationaslocalgovernmentemployeewithdeclaredincomeof87,400 to beneficiaries in Malaysia (FATF Increased Monitoring jurisdiction) between Jan-Mar 2022, inconsistent with stated occupation as local government employee with declared income of 62,000 annually.” Poor: “Looks suspicious” Good: “Pattern consistent with structuring typology per AUSTRAC guidance. Multiple transactions just below $10,000 threshold with no business explanation. Customer occupation and income profile inconsistent with transaction frequency and amounts.”

Part 5: Learning from Enforcement Actions

Case Study 1: CBA - Anonymous ATM Exploitation ($700M)

What Happened: Intelligent deposit machines allowed $20k deposits without real-time monitoring. Criminals exploited for years. Patterns Missed:
  • Multiple same-day deposits from different locations
  • Dormant accounts reactivated via cash deposits
  • Deposits followed by immediate international transfers
  • Geographic impossibility (deposits 500km apart within hours)
Lesson: Channel-specific monitoring critical. New accounts need stricter rules.

Case Study 2: Westpac - Correspondent Banking Gaps ($1.3B)

What Happened: Failed to monitor payment descriptions for child exploitation indicators, millions of missing IFTIs. Patterns Missed:
  • Payment descriptions with law enforcement code words
  • Multiple customers sending to same offshore beneficiary
  • Missing beneficial owner information
  • Correspondent banking weak-AML jurisdictions
Lesson: Payment free-text fields contain critical intelligence. IFTI completeness matters.

Case Study 3: Crown/Tabcorp - Casino Integration (450M/450M/45M)

What Happened: Gaming operators failed to file SMRs despite observing suspicious patterns. Patterns Missed:
  • Large chip purchases with minimal play
  • Third-party chip purchases
  • Multiple cage visits (structuring)
  • Chips bought at one venue, cashed at another
Lesson: Timing patterns matter. Correlate bank transactions with venue activity.

Common Remediation Pitfalls

Pitfall 1: “Clean Customer” Assumption
  • Long tenure doesn’t equal legitimacy
  • Dormancy followed by activation is a red flag
  • Accounts can be compromised or customers can turn to crime
Pitfall 2: Income ≠ Transaction Volume
  • High earners should show savings, bills, consumption
  • Pure flow-through = pass-through/mule behavior
  • Calculate account turnover ratio (transactions / avg balance)
Pitfall 3: Geographic Bias
  • Risk is context-dependent
  • Consider customer demographics and stated relationships
  • Geography alone insufficient
Pitfall 4: Single-Transaction Focus
  • Sophisticated ML involves patterns across time
  • Always analyze in aggregate
  • Use windowing (30-day, 90-day views)
Pitfall 5: Technology Over-Reliance
  • You’re doing remediation because systems failed
  • Apply human judgment
  • Ask “Does this make sense?”
Pitfall 6: Occupational Stereotyping
  • Professionals are often facilitators
  • Doctor/lawyer/accountant ≠ low risk
  • AUSTRAC has specific professional guidance for a reason
Pitfall 7: Documentation Shortcuts
  • Every finding needs clear articulation
  • What observed? Why suspicious? What typology? What alternatives ruled out?
Pitfall 8: Peer Comparison Absence
  • Always compare to peer group
  • “High” and “unusual” are relative terms
  • Variance from peers = risk indicator

Part 6: Practical Application

Your First 90 Days

Days 1-30: Foundation
  • Understand your bank’s AUSTRAC commitments
  • Map data landscape (systems, tables, data dictionaries)
  • Review existing methodology and case examples
  • Build relationships with Risk, Compliance, IT
  • Run first data quality assessment
Days 31-60: Execution
  • Complete first analytical sprint (intake to closure)
  • Develop 5 reusable SQL templates
  • Present findings and incorporate feedback
  • Identify process inefficiencies
  • Build personal knowledge base
Days 61-90: Optimization
  • Automate at least one manual process
  • Contribute to team knowledge sharing
  • Identify skill gaps and create development plan
  • Build cross-functional relationships
  • Reflect and refine approach

AUSTRAC Quick Reference

TTR Identification:
SELECT transaction_id, customer_id, amount, transaction_date,
  CASE
    WHEN reported_to_austrac = 'Y' THEN 'COMPLIANT'
    WHEN DATEDIFF(day, transaction_date, GETDATE()) > 10 THEN 'LATE - BREACH'
    ELSE 'PENDING'
  END as ttr_status
FROM transactions
WHERE amount >= 10000 AND transaction_type IN ('CASH_DEPOSIT', 'CASH_WITHDRAWAL');
Structuring for SMR:
SELECT customer_id, CAST(transaction_date AS DATE) as txn_date,
  COUNT(*) as txn_count, SUM(amount) as daily_total
FROM transactions
WHERE transaction_type IN ('CASH_DEPOSIT', 'CASH_WITHDRAWAL')
GROUP BY customer_id, CAST(transaction_date AS DATE)
HAVING COUNT(*) >= 3 AND SUM(amount) >= 15000 AND MAX(amount) < 10000;
Missing IFTI:
SELECT transaction_id, customer_id, beneficiary_country, amount
FROM transactions
WHERE transaction_type = 'INTL_TRANSFER'
  AND (reported_to_austrac IS NULL OR reported_to_austrac = 'N')
ORDER BY amount DESC;

Skills to Cultivate

Technical:
  • Advanced SQL (CTEs, window functions, optimization)
  • Python for automation
  • Data visualization and storytelling
  • Statistical analysis (sampling, hypothesis testing)
Domain:
  • AML/CTF regulations (AUSTRAC, FATF)
  • Risk typologies and emerging threats
  • Banking products and payment rails
  • Sanctions and PEP screening
Soft Skills:
  • Influencing without authority
  • Simplifying complexity for non-technical audiences
  • Managing ambiguity and incomplete information
  • Building trust with regulators and auditors

Career Development

Transaction monitoring remediation skills are transferable across:
  • Financial crime analytics
  • Regulatory reporting and compliance
  • Forensic investigation
  • Risk modeling and analytics
This work is intense, but meaningful. You’re helping protect the financial system from abuse while ensuring legitimate customers aren’t unfairly impacted. That balance—between vigilance and fairness—is what makes this role both challenging and rewarding.

Closing Reflection

Transaction monitoring remediation is archaeology meets analytics—you’re digging through historical data, piecing together narratives, and drawing conclusions that have real consequences. It’s meticulous, sometimes tedious, but never unimportant. The best Technical Business Analysts in this space do three things exceptionally well:
  1. They think like investigators: Curious, skeptical, pattern-seeking
  2. They communicate like storytellers: Data becomes narrative; numbers become insights
  3. They operate like engineers: Scalable, repeatable, documented
You’ve been hired because your bank believes you can do all three. This guide is your starting point—a map for the territory ahead. The rest is yours to write.

Appendix: AUSTRAC Intelligence Framework

Your remediation program operates within the context of 205 AUSTRAC guidance documents:
  • 159 general guidance (broad financial crime landscape)
  • 17 banking-specific (your primary focus)
  • 8 remittance (cross-border risk)
  • 5 digital currency (emerging threats)
  • 4 each: casino, superannuation, legal services
  • 2 bullion, 1 each: accounting, real estate
Key Resources: Regulatory: Industry Bodies:
  • ACAMS (Anti-Money Laundering Specialists)
  • ICA (International Compliance Association)
How to Use AUSTRAC Guidance: When analyzing an incident, ask:
  1. Is there industry-specific guidance? Apply sector-specific red flags
  2. What typology does this match? Reference relevant guidance document
  3. Has this led to enforcement? Learn from similar penalty cases
  4. What’s the regulatory expectation? Understand what AUSTRAC requires
Pro Tip: When writing SMRs, cite AUSTRAC guidance documents to demonstrate your analysis aligns with regulatory frameworks.

Key Takeaways

The Fundamentals:
  • 36+ SQL queries covering all major AML typologies
  • Industry-specific patterns for 10 AUSTRAC sectors
  • Documentation standards for audit-ready findings
  • Enforcement lessons from billion-dollar penalties
The Mindset:
  • Patterns over individual transactions
  • Context over absolute values
  • Peer comparison over isolated analysis
  • Regulatory intelligence over invention
The Impact: Every pattern you detect, every insight you deliver, every SMR you file contributes to protecting the financial system. AUSTRAC’s 205 guidance documents exist because regulators, banks, law enforcement, and analysts like you learned hard lessons about where risks hide.
Special thanks to AUSTRAC’s comprehensive guidance library, which forms the regulatory foundation for this guide’s detection patterns, typologies, and risk frameworks.