← Voltar aos artigos
August 5, 2026
5 min read

Operador Neural de Fourier para Modelagem Financeira Baseada em PDE

Operador Neural de Fourier para Modelagem Financeira Baseada em PDE
#deep-learning
#FNO
#PDE
#operator-learning
#options

Cada rede neural neste blog até agora se aproximou de uma função: entrada de recursos, saída de número. O Operador Neural de Fourier aproxima um operador — um mapa entre espaços funcionais de dimensão infinita, onde a entrada é toda uma superfície de volatilidade e a saída é toda uma superfície de preço. Esse é um objeto diferente, precisa de maquinários diferentes, e o maquinário é o objetivo deste artigo: um kernel de valor complexo que pode ser aprendido aplicado aos modos de Fourier mais baixos, avaliado por meio de uma viagem de ida e volta FFT em O(nlogn)O(n \log n).

O preço das opções é onde isso chega às finanças. Black-Scholes, Heston, volatilidade local – todos EDPs, todos resolvidos hoje, um parâmetro definido por vez. Um operador aprende toda a família de parâmetros de uma só vez, e a passagem direta resultante é um único kernel de GPU em lote, em vez de um loop de marcha no tempo.

Essa é a promessa. A versão honesta deste artigo separa a mecânica, que é sólida e reproduzível do código abaixo, das reivindicações de desempenho, que na literatura FNO são relatadas em relação às linhas de base que ninguém nesta série aceitaria sem ser examinadas. A mecânica vem primeiro; a agenda de medição vem no final, marcada como não executada.

Da aproximação da função ao aprendizado do operador

Funções aproximadas de redes neurais clássicas: dada uma entrada xRnx \in \mathbb{R}^n, eles produzem uma saída yRmy \in \mathbb{R}^m. Isto é poderoso, mas fundamentalmente limitado quando os próprios objetos de interesse são funções. Na resolução financeira de PDE, a entrada não é um número único — é uma função que descreve condições iniciais/limites, uma superfície de volatilidade ou uma estrutura a termo. O resultado é outra função: a superfície do preço acima (S,t)(S, t) espaço.

Aprendizado de operadores eleva o problema para espaços de dimensão infinita. Em vez de aprender f:RnRmf: \mathbb{R}^n \to \mathbb{R}^m, aprendemos um operador:

G:AU\mathcal{G}: \mathcal{A} \to \mathcal{U}

onde A\mathcal{A} e U\mathcal{U} são espaços de funções de Banach. Para preços de opções, A\mathcal{A} pode ser o espaço das superfícies de volatilidade σ(S,t)\sigma(S,t) e U\mathcal{U} o espaço das superfícies de preços correspondentes V(S,t)V(S,t).

Duas arquiteturas dominam o cenário de aprendizagem do operador:

  1. DeepONet (Lu et al., 2021): Usa uma rede ramificada para codificar a função de entrada e uma rede tronco para codificar o local da consulta. A saída é seu produto interno. Fundamentado no teorema da aproximação universal para operadores de Chen e Chen (1995).

  2. Operador Neural de Fourier (Li et al., 2021): Parametriza o kernel integral no espaço de Fourier, usando a FFT para convolução global eficiente. Invariante à resolução por construção.

Ambos são aproximadores universais para operadores contínuos, mas o FNO tem uma vantagem estrutural para problemas de PDE: seu viés espectral captura naturalmente a estrutura global e suave das soluções de PDE. Também tem uma desvantagem estrutural especificamente para os pagamentos de opções, à qual voltaremos — uma base de Fourier truncada e uma falha na greve não são aliados naturais.

Arquitetura FNO em detalhes

O Operador Neural de Fourier, introduzido por Li et al. no ICLR 2021, baseia-se em uma observação simples, mas poderosa: a função de Green (kernel integral) de muitos PDEs tem uma representação compacta no espaço de Fourier. Em vez de aprender um kernel no espaço físico – o que requer O(n2)O(n^2) parâmetros para nn pontos da grade - o FNO aprende no espaço de frequência com apenas os pontos mais baixos kmaxk_{\max} modos, reduzindo a complexidade para O(nlogn)O(n \log n) através da FFT.

A Arquitetura Iterativa

Um FNO consiste em:

  1. Camada de elevação PP: Um mapa linear pontual que projeta a entrada de sua dimensão de canal original para uma representação latente de dimensão superior: v0(x)=P(a(x))v_0(x) = P(a(x)).

  2. Camadas de Fourier (repetidas LL vezes): Cada camada se aplica:

vl+1(x)=σ(Wlvl(x)+Kl(vl)(x))v_{l+1}(x) = \sigma\left(W_l \, v_l(x) + \mathcal{K}_l(v_l)(x)\right)

onde WlW_l é uma transformação linear local (pontualmente 1×11 \times 1 convolução) e Kl\mathcal{K}_l é um operador integral global implementado via FFT:

Kl(vl)(x)=F1(RlF(vl))(x)\mathcal{K}_l(v_l)(x) = \mathcal{F}^{-1}\left(R_l \cdot \mathcal{F}(v_l)\right)(x)

Aqui F\mathcal{F} denota a FFT, RlR_l é um tensor de peso de valor complexo que pode ser aprendido aplicado ao menor kmaxk_{\max} Modos de Fourier e σ\sigma é uma ativação não linear pontual (normalmente GELU).

  1. Camada de projeção QQ: Mapeia a representação latente de volta para a dimensão de saída: u(x)=Q(vL(x))u(x) = Q(v_L(x)).

Por que o Espaço Fourier?

A convolução espectral RlF(vl)R_l \cdot \mathcal{F}(v_l) é uma multiplicação no domínio da frequência, que é equivalente a uma convolução global no espaço físico - mas calculada em O(nlogn)O(n \log n) em vez de O(n2)O(n^2). Este não é apenas um truque de eficiência. As soluções PDE são normalmente suaves e dominadas por componentes de baixa frequência. Ao truncar para kmaxk_{\max} modos, o FNO atua como um filtro passa-baixa que pode ser aprendido que regulariza naturalmente a solução e evita artefatos de alta frequência.

Crucialmente, o FNO é considerado invariante à discretização: uma vez treinado em uma grade de tamanho nn, pode ser avaliado em qualquer resolução mnm \neq n simplesmente ajustando o tamanho da FFT e preenchendo zero ou truncando os pesos espectrais. Essa propriedade de super-resolução zero-shot é única entre os solucionadores neurais de PDE – e é a primeira afirmação neste artigo que merece uma medição em vez de uma citação. Veja a agenda de medição abaixo.

O PDE para o qual estamos aprendendo o operador

O EDP Black-Scholes — derivado, dissecado termo por termo e fornecido com sua solução de compra/venda de formato fechado na Fórmula Black-Scholes — é o alvo do operador:

Vt+12σ2S22VS2+rSVSrV=0\frac{\partial V}{\partial t} + \frac{1}{2}\sigma^2 S^2 \frac{\partial^2 V}{\partial S^2} + rS\frac{\partial V}{\partial S} - rV = 0

Tudo o que se segue trata-o como uma caixa preta com uma resposta conhecida. Essa resposta conhecida é exatamente a razão pela qual é o caso de teste certo: um operador treinado em resultados de diferenças finitas pode ser pontuado em relação a norm.cdf preços exatos, o que quase nenhum benchmark FNO na literatura pode fazer.

Formulação FNO

Reformulamos o problema como aprendizado de operador. Definir:

  • Função de entrada a(S,t)a(S, t): codifica os parâmetros PDE. Isso pode incluir a superfície de volatilidade σ(S,t)\sigma(S, t), a função de retorno e a taxa livre de risco como canais empilhados no (S,t)(S, t) grade.
  • Função de saída u(S,t)=V(S,t)u(S, t) = V(S, t): a superfície do preço da opção.

O FNO aprende Gθ:au\mathcal{G}_\theta: a \mapsto u de um conjunto de dados de (a(i),u(i))(a^{(i)}, u^{(i)}) pares gerados por um solucionador tradicional. Após o treinamento, a inferência para qualquer nova configuração de parâmetro é uma única passagem direta.

Geração de dados de treinamento

import numpy as np
from scipy.stats import norm

def black_scholes_fd(sigma, r, K, T, S_max=300, N_S=256, N_t=256):
    """Solve Black-Scholes PDE via explicit finite differences.

    NOTE: this is an interpreted double loop — the *worst* CPU baseline,
    exactly the kind called out in /en/blog/post/when-gpu-pays-off-sweep-roofline.
    It is fine for generating training data offline. It is NOT the baseline
    any speedup claim should be measured against; vectorize the inner loop
    over i (or use scipy sparse + implicit stepping) before timing anything.
    """
    dS = S_max / N_S
    dt = T / N_t
    S = np.linspace(0, S_max, N_S + 1)

    V = np.maximum(S - K, 0).astype(np.float64)

    for j in range(N_t):
        V_new = V.copy()
        for i in range(1, N_S):
            delta = (V[i+1] - V[i-1]) / (2 * dS)
            gamma = (V[i+1] - 2*V[i] + V[i-1]) / (dS**2)
            V_new[i] = V[i] + dt * (
                0.5 * sigma**2 * S[i]**2 * gamma
                + r * S[i] * delta
                - r * V[i]
            )
        V_new[0] = 0
        V_new[N_S] = S_max - K * np.exp(-r * (T - (j+1)*dt))
        V = V_new

    return S, V

Para treinamento, amostramos milhares de configurações de parâmetros – variando σ[0.05,0.80]\sigma \in [0.05, 0.80], r[0.01,0.10]r \in [0.01, 0.10], K[50,150]K \in [50, 150], T[0.1,2.0]T \in [0.1, 2.0] - e resolva cada um com o método das diferenças finitas. O conjunto de dados resultante de pares de entrada-saída é o que o FNO aprende.

Ampliando: O Modelo de Volatilidade Estocástica de Heston

A volatilidade constante é uma suposição sabidamente falsa, e o motivo pelo qual ela falha - o sorriso, as caudas gordas - é o assunto da seção "Realidade Dura" da Fórmula Black-Scholes. Heston corrige isso tornando a variância uma segunda variável de estado:

dS=rSdt+vSdW1dS = rS\,dt + \sqrt{v}\,S\,dW_1 dv=κ(θv)dt+ξvdW2dv = \kappa(\theta - v)\,dt + \xi\sqrt{v}\,dW_2

com Corr(dW1,dW2)=ρ\text{Corr}(dW_1, dW_2) = \rho. O PDE correspondente ao preço da opção V(S,v,t)V(S, v, t) é bidimensional no espaço:

Vt+12vS22VS2+ρξvS2VSv+12ξ2v2Vv2+rSVS+κ(θv)VvrV=0\frac{\partial V}{\partial t} + \frac{1}{2}vS^2\frac{\partial^2 V}{\partial S^2} + \rho\xi vS\frac{\partial^2 V}{\partial S \partial v} + \frac{1}{2}\xi^2 v\frac{\partial^2 V}{\partial v^2} + rS\frac{\partial V}{\partial S} + \kappa(\theta - v)\frac{\partial V}{\partial v} - rV = 0

É aqui que a aprendizagem do operador ganha o seu sustento, e o argumento é estrutural e não empírico. Esquemas de diferenças finitas em um (S,v,t)(S, v, t) escala de grade como O(NS×Nv×Nt)O(N_S \times N_v \times N_t), o termo derivado cruzado 2V/Sv\partial^2 V / \partial S \partial v complica a discretização, e cada novo conjunto de parâmetros (κ,θ,ξ,ρ,r)(\kappa, \theta, \xi, \rho, r) paga o custo total novamente. Um operador paga uma vez na hora do treinamento. A estrutura espacial 2D do Heston PDE também mapeia diretamente na FFT 2D nas camadas de Fourier, de modo que a arquitetura abaixo generaliza com uma mudança de dimensão em vez de um redesenho.

FNO para preços de opções: implementação PyTorch

Abaixo está uma implementação FNO completa e independente para aprender o operador Black-Scholes. A arquitetura segue Li et al. (2021) com adaptações para o cenário financeiro.

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.fft import rfft, irfft

class SpectralConv1d(nn.Module):
    """1D Fourier layer: spectral convolution via FFT."""

    def __init__(self, in_channels: int, out_channels: int, modes: int):
        super().__init__()
        self.in_channels = in_channels
        self.out_channels = out_channels
        self.modes = modes  # Number of Fourier modes to keep

        scale = 1.0 / (in_channels * out_channels)
        self.weights = nn.Parameter(
            scale * torch.randn(in_channels, out_channels, modes, dtype=torch.cfloat)
        )

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        batch_size = x.shape[0]

        x_ft = rfft(x, dim=-1)

        out_ft = torch.zeros(
            batch_size, self.out_channels, x_ft.size(-1),
            dtype=torch.cfloat, device=x.device
        )
        out_ft[:, :, :self.modes] = torch.einsum(
            "bix,iox->box", x_ft[:, :, :self.modes], self.weights
        )

        return irfft(out_ft, n=x.size(-1), dim=-1)


class FNOBlock(nn.Module):
    """Single Fourier Neural Operator block."""

    def __init__(self, channels: int, modes: int):
        super().__init__()
        self.spectral_conv = SpectralConv1d(channels, channels, modes)
        self.pointwise = nn.Conv1d(channels, channels, kernel_size=1)
        self.norm = nn.InstanceNorm1d(channels)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        return F.gelu(self.norm(self.spectral_conv(x) + self.pointwise(x)))


class FNO1d(nn.Module):
    """
    Fourier Neural Operator for 1D PDE problems.

    Learns the mapping: PDE parameters -> solution function
    """

    def __init__(
        self,
        in_channels: int = 3,    # e.g., sigma(S), payoff(S), grid(S)
        out_channels: int = 1,   # V(S)
        hidden_channels: int = 64,
        modes: int = 32,
        num_layers: int = 4,
    ):
        super().__init__()
        self.lift = nn.Linear(in_channels, hidden_channels)
        self.blocks = nn.ModuleList(
            [FNOBlock(hidden_channels, modes) for _ in range(num_layers)]
        )
        self.proj = nn.Sequential(
            nn.Linear(hidden_channels, 128),
            nn.GELU(),
            nn.Linear(128, out_channels),
        )

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        x = self.lift(x)                    # -> (batch, spatial, hidden)
        x = x.permute(0, 2, 1)              # -> (batch, hidden, spatial)

        for block in self.blocks:
            x = block(x)

        x = x.permute(0, 2, 1)              # -> (batch, spatial, hidden)
        return self.proj(x)                  # -> (batch, spatial, out_channels)

Ciclo de treinamento

import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset

def train_fno_black_scholes():
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

    N_samples = 5000
    N_S = 256
    S_max = 300.0
    S_grid = np.linspace(0, S_max, N_S + 1)

    inputs, targets = [], []
    for _ in range(N_samples):
        sigma = np.random.uniform(0.05, 0.80)
        r = np.random.uniform(0.01, 0.10)
        K = np.random.uniform(50, 150)
        T = np.random.uniform(0.1, 2.0)

        _, V = black_scholes_fd(sigma, r, K, T, S_max=S_max, N_S=N_S)

        sigma_field = np.full(N_S + 1, sigma)
        payoff = np.maximum(S_grid - K, 0)
        grid_norm = S_grid / S_max

        inp = np.stack([sigma_field, payoff, grid_norm], axis=-1)
        inputs.append(inp)
        targets.append(V[:, None])

    X = torch.tensor(np.array(inputs), dtype=torch.float32)
    Y = torch.tensor(np.array(targets), dtype=torch.float32)

    dataset = TensorDataset(X, Y)
    loader = DataLoader(dataset, batch_size=64, shuffle=True)

    model = FNO1d(in_channels=3, out_channels=1, hidden_channels=64, modes=32).to(device)
    optimizer = optim.AdamW(model.parameters(), lr=1e-3, weight_decay=1e-4)
    scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=200)

    for epoch in range(200):
        model.train()
        total_loss = 0.0
        for batch_x, batch_y in loader:
            batch_x, batch_y = batch_x.to(device), batch_y.to(device)

            pred = model(batch_x)
            loss = torch.mean(
                torch.norm(pred - batch_y, dim=1)
                / torch.norm(batch_y, dim=1).clamp(min=1e-8)
            )

            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            total_loss += loss.item()

        scheduler.step()
        if (epoch + 1) % 20 == 0:
            avg = total_loss / len(loader)
            print(f"Epoch {epoch+1:3d} | Relative L2 Loss: {avg:.6f}")

    return model

Inferência: preços em tempo real

@torch.no_grad()
def price_option(model, sigma, K, S_grid, device="cuda"):
    """
    Price a European call for given sigma and strike.
    Returns prices for all S in S_grid — single forward pass.
    """
    S_max = S_grid[-1]
    payoff = np.maximum(S_grid - K, 0)
    grid_norm = S_grid / S_max
    sigma_field = np.full_like(S_grid, sigma)

    inp = np.stack([sigma_field, payoff, grid_norm], axis=-1)
    x = torch.tensor(inp, dtype=torch.float32).unsqueeze(0).to(device)

    pred = model(x)
    return pred.squeeze().cpu().numpy()

FNO vs. PINNs: uma comparação prática

Redes Neurais Informadas pela Física e Operadores Neurais de Fourier representam filosofias fundamentalmente diferentes para resolver EDPs com redes neurais. Compreender suas vantagens e desvantagens é a razão prática para se preocupar com o aprendizado do operador.

PINNs: otimização por instância

PINNs colocam o resíduo PDE diretamente na perda — O problema de Navier-Stokes cobre o mecanismo, o autodiff physics_loss implementação e o resultado da pesquisa de singularidade DeepMind. A única propriedade que importa aqui é estrutural: um PINN é treinado por conjunto de parâmetros. Alteração σ\sigma, rr, KK ou TT e você otimiza novamente do zero.

Pontos fortes: Não são necessários dados rotulados. Aplica diretamente a estrutura do PDE. Funciona para qualquer PDE que você possa anotar.

Pontos fracos: deve ser treinado novamente para cada novo conjunto de parâmetros (σ,r,K,T)(\sigma, r, K, T). O treinamento envolve o equilíbrio de vários termos de perda (resíduos de PDE, condições de contorno, condições iniciais), o que muitas vezes leva a patologias de otimização. A convergência pode ser lenta – normalmente de 10.000 a 100.000 passos de gradiente por instância do problema. Falha em sistemas multiescala e caóticos onde o cenário de perdas se torna altamente não convexo.

FNO: Aprendizagem Amortizada do Operador

O FNO aprende o operador da solução a partir dos dados. Requer um conjunto de dados de treinamento gerado por um solucionador clássico, mas uma vez treinado, generaliza para todo o espaço de parâmetros.

Pontos fortes: Inferência inferior a um milissegundo nos benchmarks publicados. Generaliza para parâmetros invisíveis sem retreinamento. Invariante à resolução – treine em baixa resolução, avalie em alta resolução. Lida naturalmente com soluções PDE suaves por meio de polarização espectral.

Pontos fracos: Requer dados de treinamento de um solucionador clássico (problema do ovo e da galinha para PDEs verdadeiramente novos). O erro de aproximação é limitado, mas diferente de zero. Menos interpretável do que abordagens restritas por PDE. E o viés espectral que ajuda em soluções suaves é um risco com uma distorção de recompensa.

Comparação cara a cara

A tabela abaixo é relatada na literatura, não medida aqui — as linhas de precisão e aceleração em particular vêm de Li et al. (2021) e trabalho de acompanhamento em benchmarks fluidos, não na precificação de opções em nosso hardware. Leia as linhas estruturais (dados necessários, generalização, invariância de resolução) como confiáveis.

Critério PIN FNO
Dados de formação necessários Nenhum (sem supervisão) Pares gerados pelo solucionador
Custo de inferência Requalificação completa por instância Passe único para frente
Generalização Conjunto de parâmetros único Família inteira de parâmetros
Invariância de resolução Não Afirmou que sim — veja a agenda abaixo
EDPs multiescala Muitas vezes falha Reportado como robusto
Precisão (relativa L2L^2, literatura) 10310^{-3} para 10210^{-2} 10410^{-4} para 10310^{-3}

O Híbrido: Operadores Neurais Informados pela Física (PINO)

PINO (Li et al., 2024) combina ambas as abordagens. Ele usa a arquitetura FNO, mas aumenta a perda orientada por dados com um termo residual PDE:

LPINO=Ldata+λLPDE\mathcal{L}_{\text{PINO}} = \mathcal{L}_{\text{data}} + \lambda \, \mathcal{L}_{\text{PDE}}

A decomposição é a parte útil. Ldata\mathcal{L}_{\text{data}} ancora o operador à saída do solucionador onde quer que esteja; λLPDE\lambda \mathcal{L}_{\text{PDE}} restringe-o em todos os lugares onde você não o faz, incluindo regiões do espaço de parâmetros que você nunca amostrou. Para a precificação de opções, esse segundo termo é atraente por uma razão específica para finanças: o resíduo do PDE é uma restrição dura que você também pode avaliar no momento da inferência como uma autoverificação, que é a base do substituto de monitoramento residual abaixo.

Considerações práticas para implantação em produção

A metade genérica disso – orçamentos de latência de inferência, construção do pipeline de dados, monitoramento de desvios, retreinamento periódico – já está coberta para um modelo neural em um sistema de negociação na seção de produção de DeepLOB: Deep Learning on Limit Order Books, e se aplica inalterado. O que se segue é apenas o que é específico de um operador.

Pipeline de dados: amostragem do espaço de parâmetros

A geração de dados de treinamento é o principal gargalo e, diferentemente de um modelo de dados de mercado, você escolhe sua própria distribuição – o que significa que você pode errar de uma forma que fica invisível na perda. Para o operador Black-Scholes com 4 parâmetros, 5.000–10.000 amostras são suficientes. Para Heston com 5 parâmetros mais um domínio espacial 2D, 20.000–50.000 amostras são típicas. Use amostragem adaptativa: concentre amostras em regiões de parâmetros onde a solução varia rapidamente – perto do dinheiro, vencimentos curtos, alta volatilidade – porque a amostragem uniforme da caixa gasta a maior parte de seu orçamento em regiões de deep-ITM e deep-OTM onde o operador é quase linear e aprende bem com poucos exemplos.

Ajuste de arquitetura

  • Modos (kmaxk_{\max}): Comece com N/4N/4 onde NN é o tamanho da grade espacial. Para N=256N=256, use os modos 32–64. Poucos modos perdem detalhes perto dos limites do ataque; muitos overfit ao ruído.
  • Camadas: 4 camadas de Fourier são padrão. Redes mais profundas (6–8) ajudam em problemas 2D como Heston, mas aumentam a memória.
  • Canais ocultos: 64 para 1D Black-Scholes, 128 para 2D Heston. Dimensione com a complexidade do problema.

Precisão: a questão fp32

SpectralConv1d aloca torch.cfloat - complexo de precisão única - e cada viagem de ida e volta da FFT é executada com essa precisão. Este blog já viu um pipeline financeiro fp32 retornar lixo silencioso em The GPU Precision Trap, onde uma formulação de soma de prefixo matematicamente correta perdeu catastroficamente em magnitudes fp32. A questão análoga aqui é direta: em S100S \approx 100 com preços cotados em centavos, uma viagem espectral de ida e volta fp32 se mantém 10210^{-2} absoluto, ou o crescimento de magnitude intermediária da FFT consome os últimos dígitos significativos?

Controle de erros

Para precificação de opções de produção, você precisa de limites de erro que possa defender.

  1. Incerteza calibrada: um desvio padrão de conjunto não é uma garantia de cobertura, e este blog tem o mecanismo para fazê-lo corretamente — divisão conforme em uma grade de parâmetros retida, com ACI/DtACI para o caso não trocável, em Predição Conformal para Dimensionamento de Posição Consciente de Risco. Envolvendo o FNO em conformação dividida sobre o (σ,r,K,T)(\sigma, r, K, T) a grade fornece intervalos livres de distribuição no preço.
  2. Monitoramento residual: Calcule o resíduo PDE da previsão do FNO como uma verificação post-hoc. Se residual>ϵ\|\text{residual}\| > \epsilon, volte para um solucionador clássico. Isso é gratuito na inferência - o resíduo é um estêncil de diferenças finitas em uma matriz que você já possui.
  3. Aprendizado ativo: direcione entradas de alta incerteza para o solucionador clássico, adicione os resultados ao conjunto de treinamento e treine novamente periodicamente. A largura do intervalo conforme de (1) é o sinal de roteamento natural.

A Agenda de Medição

Esta é a parte que decide se vale a pena implantar a arquitetura acima, e nada disso foi feito ainda. Ele está listado aqui, em vez de enterrado, porque a alternativa – afirmar uma aceleração das manchetes – é precisamente o registro que este blog existe para evitar.

1. A aceleração é uma curva, não um número. Quando a GPU compensa estabelece a forma: S(B)=aB/(O+bB)S(B) = aB/(O + bB), subindo de um domínio dominado por despesas gerais em B=1B=1 para um platô vinculado à computação e mostra um título 167x se decompondo em 27x de algoritmo vezes 6,2x de hardware. A medição do FNO deve seguir esse modelo: marque a passagem para frente em B{1,8,64,512}B \in \{1, 8, 64, 512\} e relate toda a curva. Criticamente, a linha de base deve ser um solucionador de diferenças finitas vetorizado e multinúcleo - o black_scholes_fd acima é um loop duplo interpretado, a linha de base exata da "pior implementação de CPU" mencionada no artigo, e comparar um operador de GPU em lote com ele produziria um número que não significa nada.

**2. Precisão em relação à forma fechada. ** Este é o experimento que Black-Scholes faz quase de graça e que os benchmarks de dinâmica de fluidos não podem fazer: treinar com dados gerados por FD e depois pontuar com base em dados exatos norm.cdf preços em todo o (σ,r,K,T)(\sigma, r, K, T) caixa. Denuncie o parente L2L^2, e relate o erro distribuição - especificamente perto do strike e perto do vencimento, onde a solução é menos suave e a base espectral truncada deve ter mais dificuldades.

3. Violações sem arbitragem. Um operador aprendido não tem razão estrutural para respeitar as restrições de forma que uma superfície de preço deve satisfazer: monotonicidade em KK, convexidade em KK, e Vmax(SK,0)V \geq \max(S-K, 0). Medir a taxa de violação na caixa de parâmetros transforma a questão aberta deste artigo - podemos garantir condições de não arbitragem no operador aprendido? - de um aceno manual em um número.

4. Invariância de discretização, testada em vez de afirmada. Treine em NS=128N_S = 128, avaliar em NS=512N_S = 512, relate o erro. O modo de falha esperado é nomeado e específico: Gibbs tocando na torção max(SK,0)\max(S-K, 0). Uma base de Fourier truncada que reconstrói uma função com uma primeira derivada descontínua oscila em torno dela, e a super-resolução de tiro zero pode piorar isso em vez de melhorar, expondo modos que a resolução de treinamento nunca viu. Se a super-resolução se degradar perto do ataque, esse resultado negativo é mais valioso do que a afirmação de marketing que substitui – ninguém na literatura FNO está a precificar opções com uma distorção de recompensa.

Se os experimentos 1 a 4 não puderem ser executados, este artigo não deverá ser enviado. O que resta sem eles é uma exposição bem escrita do artigo do ICLR de outra pessoa.

Além das opções de baunilha

Assumindo que a agenda acima sobrevive ao contacto com a medição, o quadro do FNO estende-se naturalmente a instrumentos mais complexos:

  • Opções americanas: Adicionar um limite de exercício antecipado como um canal de saída adicional. O FNO aprende simultaneamente a superfície de preço e o limite de exercício ideal.
  • Opções de barreira: Codifique níveis de barreira como canais de entrada. Note-se que uma barreira é uma segunda descontinuidade, e a preocupação de Gibbs na agenda de medição aplica-se com mais força, e não menos.
  • Cestas de múltiplos ativos: Use FNO 2D ou 3D para opções de cesta em 2–3 subjacentes. A maldição da dimensionalidade é menos severa do que para os solucionadores baseados em grade porque o FNO opera em um número fixo de modos.
  • Volatilidade local: Insira a superfície completa de volatilidade local Dupire σloc(S,t)\sigma_{\text{loc}}(S,t) como uma função espacial. Este é o caso de uso mais natural para aprendizado de operador — a entrada é uma função, não um parâmetro escalar.

Conclusão

A contribuição do Operador Neural de Fourier é conceitual antes de ser computacional: em vez de resolver um PDE de cada vez, você parametriza o próprio operador de solução, e fazer isso no espaço de Fourier produz uma arquitetura que é O(nlogn)O(n \log n), universal em operadores contínuos e com resolução flexível por construção. Isso decorre de Li et al. (2021) e do código acima, que é executado.

O que não se segue é um número de aceleração. Os números de 100x a 1000x da literatura são medidos em benchmarks fluidos em relação a linhas de base cuja qualidade raramente é declarada, e esta série gastou um artigo inteiro mostrando o quanto de tal título geralmente é algoritmo e não hardware. As alegações que justificariam colocar um operador em um mecanismo de precificação – precisão de fp32 em nível de centavo, uma taxa de violação limitada sem arbitragem, super-resolução que sobrevive a uma torção de retorno e uma curva de aceleração contra um solucionador de CPU competente – são todas mensuráveis, todas baratas em Black-Scholes porque a forma fechada existe, e todas ainda não medidas aqui.

Este é o estado deste projecto: o mecanismo é real, a promessa é plausível e as provas estão pendentes.


Referências e leituras adicionais:

  • Li, Z., Kovachki, N., Azizzadenesheli, K., et al. "Operador Neural de Fourier para Equações Diferenciais Parciais Paramétricas." ICLR 2021. arXiv:2010.08895
  • Lu, L., Jin, P., Pang, G., Zhang, Z., & Karniadakis, GE "Aprendendo operadores não lineares via DeepONet." Inteligência da Máquina da Natureza, 2021. doi:10.1038/s42256-021-00302-5
  • Li, Z., et al. "Operador Neural Informado pela Física para Aprendizagem de Equações Diferenciais Parciais." ACM/IMS Journal of Data Science, 2024. OpenReview
  • neuraloperator Biblioteca PyTorch: github.com/neuraloperator/neuraloperator
  • Salvador, M., et al. "Aprendizado em rede neural da equação de Black-Scholes para preços de opções." arXiv:2405.05780 -Bai, Y., et al. "The AI ​​Black-Scholes: rede neural informada sobre finanças." arXiv:2412.12213
blog.disclaimer

Authors

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

Fique à frente do mercado

Assine nossa newsletter para insights exclusivos sobre trading com IA, análises de mercado e atualizações da plataforma.

Respeitamos sua privacidade. Cancele a inscrição a qualquer momento.