Skip to main content

AI in Finance: Fraud Detection with Isolation Forest and Algorithmic Trading with Backtrader

Published: December 14, 2025 Updated: May 24, 2026 Larry Qu 9 min read

Introduction

AI in finance spans two primary domains: fraud detection (identifying malicious transactions in real-time) and algorithmic trading (executing market strategies automatically). Both require processing high-velocity data streams with low latency, but their ML approaches differ sharply. Fraud detection uses unsupervised anomaly detection to catch novel attack patterns without labeled examples. Algorithmic trading uses historical backtesting with supervised or reinforcement learning to optimize execution strategies.

The scale is immense. High-frequency trading accounts for approximately 72-78% of all US equity trading volume in 2026. AI venture funding in healthcare and finance reached $13 billion annually. Modern AI trading systems process an average of 3.5 terabytes of market data daily and incorporate 7,000-9,000 data points per trading decision. Fraud detection systems must handle real-time payments where money moves instantly with no reversal window.

This guide covers an Isolation Forest + autoencoder pipeline for real-time fraud detection with SHAP explainability and streaming architecture, a Backtrader-based algorithmic trading strategy with reinforcement learning extensions and NLP sentiment integration, graph neural networks for collusion detection, and production deployment patterns with model risk management.

Fraud Detection Pipeline

Modern fraud detection systems combine supervised models (trained on known fraud patterns) with unsupervised anomaly detection (catching novel fraud types). The pipeline below processes transactions in real-time through a streaming architecture:

flowchart LR
    T[Transaction Event<br/>Kafka / API] --> FE[Feature Engineering<br/>velocity, deviation, time]
    FE --> M1[Supervised Model<br/>XGBoost / CatBoost]
    FE --> M2[Unsupervised Model<br/>Isolation Forest]
    FE --> M3[Autoencoder<br/>Reconstruction Error]
    FE --> M4[Graph Neural Net<br/>Collusion detection]

    M1 --> F[Fusion Layer<br/>Weighted ensemble]
    M2 --> F
    M3 --> F
    M4 --> F

    F --> Score[Fraud Score 0-100]
    Score -->|> 90| Block[Block Transaction]
    Score -->|60-90| Review[Manual Review Queue]
    Score -->|< 60| Allow[Approve]

Real-time payments fraud is the fastest-growing threat in 2026. Faster payment rails (FedNow, real-time ACH) shorten the detection window to milliseconds — once money moves, there is no reversal. Fraudsters target off-hours, use AI-generated synthetic identities and deepfake voice clones, and exploit authenticated sessions through “all-green” fraud where credentials are valid. The shift is from point-in-time checks to continuous behavioral profiling across channels.

Streaming Feature Engineering

Production fraud systems process transactions from Kafka streams with sub-100ms latency:

import numpy as np
import pandas as pd
from sklearn.ensemble import IsolationForest
from sklearn.preprocessing import StandardScaler
from datetime import timedelta

def engineer_features_streaming(transaction: dict, user_history: pd.DataFrame) -> pd.Series:
    """Compute features for a single transaction using historical user data.

    Feature engineering must complete in under 50ms for real-time payments.
    Rolling windows use pre-aggregated counters, not full history scans.
    """
    features = {}
    features['amount'] = transaction['amount']
    features['tx_1h_count'] = len(user_history[
        user_history['timestamp'] > transaction['timestamp'] - timedelta(hours=1)
    ])
    user_avg = user_history['amount'].mean()
    user_std = user_history['amount'].std()
    features['amount_zscore'] = (transaction['amount'] - user_avg) / (user_std + 1e-8)
    features['is_weekend'] = int(transaction['timestamp'].weekday() >= 5)
    features['is_night'] = int(transaction['timestamp'].hour < 6)
    return pd.Series(features)

def train_isolation_forest(historical_df: pd.DataFrame, feature_cols: list) -> tuple:
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(historical_df[feature_cols])

    model = IsolationForest(
        n_estimators=200,
        contamination=0.01,
        random_state=42,
        n_jobs=-1
    )
    model.fit(X_scaled)
    return model, scaler

def score_transaction(transaction: dict, model, scaler, user_history: pd.DataFrame) -> dict:
    features = engineer_features_streaming(transaction, user_history)
    X = scaler.transform([features])
    anomaly_score = model.decision_function(X)[0]
    is_fraud = model.predict(X)[0] == -1
    return {
        'fraud_score': float(1 - (anomaly_score + 0.5)),
        'is_suspicious': bool(is_fraud),
    }

Autoencoder for Reconstruction-Based Detection

Autoencoders learn to reconstruct normal transactions. Fraudulent transactions produce high reconstruction error because they don’t match learned patterns:

import torch
import torch.nn as nn

class FraudAutoencoder(nn.Module):
    def __init__(self, input_dim: int, encoding_dim: int = 16):
        super().__init__()
        self.encoder = nn.Sequential(
            nn.Linear(input_dim, 64),
            nn.ReLU(),
            nn.Linear(64, 32),
            nn.ReLU(),
            nn.Linear(32, encoding_dim),
        )
        self.decoder = nn.Sequential(
            nn.Linear(encoding_dim, 32),
            nn.ReLU(),
            nn.Linear(32, 64),
            nn.ReLU(),
            nn.Linear(64, input_dim),
        )

    def forward(self, x):
        return self.decoder(self.encoder(x))

    def reconstruction_error(self, x: torch.Tensor) -> float:
        with torch.no_grad():
            reconstructed = self.forward(x)
            return nn.MSELoss()(reconstructed, x).item()

model = FraudAutoencoder(input_dim=6)
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
criterion = nn.MSELoss()

for epoch in range(50):
    for batch in normal_transactions_loader:
        optimizer.zero_grad()
        output = model(batch)
        loss = criterion(output, batch)
        loss.backward()
        optimizer.step()

Graph Neural Networks for Collusion Detection

Isolation Forest and autoencoders catch individual anomalous transactions but miss coordinated fraud rings. Graph Neural Networks (GNNs) model relationships between accounts, devices, and transactions to detect sophisticated collusion:

import torch
import torch.nn.functional as F
from torch_geometric.nn import GCNConv

class FraudGNN(torch.nn.Module):
    """Graph neural network for detecting coordinated fraud rings.

    Nodes represent accounts or devices. Edges represent transactions
    or shared attributes (IP address, device fingerprint).
    Collusion rings appear as densely connected subgraphs.
    """
    def __init__(self, in_channels: int, hidden_channels: int = 64):
        super().__init__()
        self.conv1 = GCNConv(in_channels, hidden_channels)
        self.conv2 = GCNConv(hidden_channels, hidden_channels)
        self.classifier = torch.nn.Linear(hidden_channels, 2)

    def forward(self, x, edge_index):
        x = self.conv1(x, edge_index)
        x = F.relu(x)
        x = F.dropout(x, training=self.training)
        x = self.conv2(x, edge_index)
        return self.classifier(x)

# Usage: model = FraudGNN(in_channels=num_features)
# Train on transaction graph where edges connect accounts that share
# device fingerprints, IP addresses, or beneficiary relationships.

GNNs are particularly effective against synthetic identity fraud — where fraudsters create fake identities that behave normally in isolation but share structural patterns (phones, addresses, devices) with known fraud rings.

Explainability with SHAP

import shap

explainer = shap.TreeExplainer(xgb_model)
shap_values = explainer.shap_values(transaction_features)

shap.initjs()
shap.force_plot(
    explainer.expected_value,
    shap_values[0],
    transaction_features,
    matplotlib=True
)
# Output: "Transaction flagged due to: amount_zscore=3.2, is_night=1, tx_1h_count=15"

Algorithmic Trading

Algorithmic trading has progressed beyond basic rule-based systems. Modern AI trading systems use machine learning for signal generation, reinforcement learning for execution optimization, and NLP for sentiment analysis.

Moving Average Crossover (Backtrader)

import backtrader as bt

class MovingAverageCrossover(bt.Strategy):
    """Buy when fast MA crosses above slow MA (golden cross).
    Sell when fast MA crosses below slow MA (death cross).
    """
    params = (('fast', 20), ('slow', 50))

    def __init__(self):
        self.fast_ma = bt.indicators.SMA(self.data.close, period=self.params.fast)
        self.slow_ma = bt.indicators.SMA(self.data.close, period=self.params.slow)
        self.crossover = bt.indicators.CrossOver(self.fast_ma, self.slow_ma)

    def next(self):
        if not self.position:
            if self.crossover > 0:
                self.buy()
        elif self.crossover < 0:
            self.sell()

cerebro = bt.Cerebro()
cerebro.addstrategy(MovingAverageCrossover)
data = bt.feeds.PandasData(dataname=historical_prices)
cerebro.adddata(data)
cerebro.broker.setcash(100000.0)
cerebro.broker.setcommission(commission=0.001)

print(f'Starting Portfolio Value: {cerebro.broker.getvalue():.2f}')
cerebro.run()
print(f'Final Portfolio Value: {cerebro.broker.getvalue():.2f}')

ML-Based Signal Generation

Modern strategies replace fixed rules with ML models that predict next-day return direction. An XGBoost classifier trained on technical, volume, and volatility features achieves approximately 63% out-of-sample accuracy for next-day direction prediction:

import xgboost as xgb

def train_signal_model(features: pd.DataFrame, targets: pd.Series) -> xgb.XGBClassifier:
    """Train XGBoost to predict next-day return direction.

    Features: price ratios, volume changes, volatility, RSI, MACD, sector correlation.
    Target: 1 if next-day return > 0, 0 otherwise.
    """
    model = xgb.XGBClassifier(
        n_estimators=200,
        max_depth=6,
        learning_rate=0.05,
        random_state=42
    )
    model.fit(features, targets)
    return model

def generate_signals(model, latest_features: pd.DataFrame) -> float:
    """Return probability of positive next-day return."""
    prob = model.predict_proba(latest_features)[0, 1]
    return prob  # threshold at 0.6+ for buy signal

Reinforcement Learning for Execution

Reinforcement learning optimizes trade execution — deciding order size, timing, and venue to minimize slippage and market impact. The agent learns through trial and error in simulated market environments:

import gymnasium as gym
from gymnasium import spaces

class TradingEnv(gym.Env):
    """Reinforcement learning environment for trade execution.

    State: price history, position, order book imbalance, volatility.
    Action: BUY, SELL, HOLD (with position sizing).
    Reward: realized PnL minus slippage penalty.
    """
    def __init__(self, price_data: np.ndarray):
        super().__init__()
        self.price_data = price_data
        self.current_step = 0
        self.position = 0
        self.cash = 100000

        self.action_space = spaces.Discrete(3)  # BUY, SELL, HOLD
        self.observation_space = spaces.Box(
            low=-np.inf, high=np.inf,
            shape=(10,), dtype=np.float32
        )

    def step(self, action):
        price = self.price_data[self.current_step]
        if action == 0:  # BUY
            shares = self.cash // price
            self.position += shares
            self.cash -= shares * price
        elif action == 1:  # SELL
            self.cash += self.position * price
            self.position = 0

        self.current_step += 1
        portfolio_value = self.cash + self.position * price
        reward = portfolio_value - self.cash
        done = self.current_step >= len(self.price_data) - 1
        return self._get_obs(), reward, done, False, {}

    def _get_obs(self):
        return self.price_data[self.current_step:self.current_step + 10]

RL-based execution is used in production by major market makers. Firms like Two Sigma and Citadel deploy RL agents for adaptive order routing, dynamically adjusting to liquidity conditions and volatility regimes.

NLP Sentiment for Trading

Natural language processing extracts trading signals from news articles, earnings calls, and social media. A transformer-based model scores sentiment and feeds it into the trading strategy:

from transformers import pipeline

class SentimentSignal:
    def __init__(self):
        self.sentiment_pipeline = pipeline(
            "text-classification",
            model="finbert-sentiment-v2"
        )

    def score_news(self, headlines: list[str]) -> float:
        """Aggregate sentiment from news headlines. Returns -1 to 1."""
        scores = []
        for headline in headlines:
            result = self.sentiment_pipeline(headline)[0]
            label = result['label']
            score = result['score']
            if label == 'POSITIVE':
                scores.append(score)
            elif label == 'NEGATIVE':
                scores.append(-score)
            else:
                scores.append(0)
        return np.mean(scores) if scores else 0.0

# Integrated into strategy:
# signal = 0.7 * ml_signal + 0.3 * sentiment_score

Studies show AI systems identify actionable trading opportunities from earnings announcements an average of 3.7 minutes faster than human analysts. Incorporating NLP sentiment alongside technical signals improves Sharpe ratios and reduces drawdowns during volatile periods.

Multi-Agent Market Simulation

Reinforcement learning agents can simulate market interactions to test strategies against adaptive counterparties. Multi-agent simulations reveal emergent behaviors like flash crashes and liquidity spirals that single-agent backtests miss:

class MarketSimulation:
    """Multi-agent market simulation for strategy stress-testing.

    Each agent learns and adapts. Useful for detecting
    unstable strategy interactions before live deployment.
    """
    def __init__(self, n_agents: int = 10):
        self.agents = [TradingEnv(price_data) for _ in range(n_agents)]

    def run_episode(self):
        for agent in self.agents:
            obs = agent.reset()
            done = False
            while not done:
                action = agent.action_space.sample()
                obs, reward, done, _, _ = agent.step(action)
        # Analyze emergent behaviors across all agents

Production Deployment Patterns

Fraud Detection Architecture

┌─────────────┐    ┌──────────────┐    ┌──────────────┐
│  Transaction │───▶│  Kafka       │───▶│  Feature      │
│  Gateway     │    │  Stream      │    │  Store        │
└─────────────┘    └──────────────┘    │  (Redis)      │
                                       └──────┬───────┘
                                       ┌──────▼───────┐
                                       │  Model        │
                                       │  Ensemble     │
                                       │  (GPU/CPU)    │
                                       └──────┬───────┘
                                       ┌──────▼───────┐
                                       │  Decision     │
                                       │  Engine       │
                                       └──────┬───────┘
                              ┌───────────────┼───────────────┐
                              │               │               │
                       ┌──────▼──────┐ ┌─────▼──────┐ ┌─────▼──────┐
                       │  Block      │ │  Review    │ │  Approve   │
                       │  (API call) │ │  Queue     │ │  (pass)    │
                       └─────────────┘ └────────────┘ └────────────┘

Model Risk Management

Financial regulators are developing AI-specific frameworks. Key production requirements:

  • Kill switches: Automatic circuit breakers when model confidence drops or market volatility exceeds thresholds
  • Shadow deployment: Run new models in parallel with production models for 30+ days before cutover
  • Explainability: Every trading decision must be attributable to features — regulators require it
  • Adversarial testing: Test fraud models against AI-generated attacks (deepfakes, synthetic identities)
  • Periodic retraining: Fraud patterns shift; models require weekly or daily retraining cycles
  • Regulatory compliance: Evolving rules around automated trading and AI disclosure

Performance Benchmarks

Component Latency Target Technology
Feature engineering < 50ms Redis cache, pre-aggregated counters
Fraud scoring (ensemble) < 100ms GPU batch inference, model distillation
Trade signal generation < 10ms ONNX Runtime, TensorRT
Order execution < 1ms FPGA, colocated servers
Model retraining < 1 hour Distributed GPU training (PyTorch DDP)

Resources

Comments

👍 Was this article helpful?