Habilitar o ciclo de vida de risco dos serviços financeiros com o Azure e o R

Cálculos de riscos são fundamentais em vários estágios do ciclo de vida de operações chave de serviços financeiros. Por exemplo, uma forma simplificada do ciclo de vida de gerenciamento de produtos de seguro pode ser semelhante ao diagrama a seguir. Os aspectos do cálculo de risco são mostrados em texto azul.

O diagrama mostra os fatores de cálculo de risco.

Um cenário em uma empresa de mercados de capital pode ter esta aparência:

O diagrama mostra o cenário de cálculo de risco para uma empresa de mercado de capitais.

Em processos como esses, há necessidades comuns de modelagem de riscos, incluindo:

  • A necessidade de experimentação ad hoc relacionada a riscos por analistas de risco, como atuários em uma seguradora ou analistas quantitativos em uma empresa de mercados de capital. Esses analistas normalmente trabalham ferramentas de código e modelagem que são populares em seu domínio: R e Python. Muitos currículos universitários incluem treinamento em R ou Python em cursos de matemática financeira e MBA. As duas linguagens têm acesso a uma ampla variedade de bibliotecas de software livre que dão suporte a cálculos de riscos populares.
  • Juntamente com as ferramentas apropriadas, os analistas muitas vezes exigem acesso a:
    • Dados precisos de preços de mercado.
    • Dados de apólices e sinistros.
    • Dados de posição no mercado.
    • Outros dados externos, como:
      • Dados estruturados, como tabelas de mortalidade e dados de preços competitivos.
      • Tipos menos tradicionais, como clima e notícias.
    • Capacidade computacional para realizar investigações de dados rápidas e interativas.
  • Em alguns casos, os algoritmos de aprendizado de máquina ad-hoc para determinar os preços ou a estratégia de mercado.
  • A capacidade de visualizar e apresentar dados para uso em planejamento de produtos, estratégia comercial e discussões semelhantes.
  • A execução rápida de modelos definidos, configurados pelos analistas para precificação, avaliações e risco de mercado. As avaliações usam uma combinação de modelagem de risco dedicada, ferramentas de risco de mercado e código personalizado. A análise é executada em um lote com diferentes cálculos noturnos, semanais, mensais, trimestrais e anuais. Essa análise gera picos nas cargas de trabalho.
  • A integração dos dados com outras medidas de risco amplas empresariais para relatórios de risco consolidados. Em organizações maiores, as estimativas de risco de nível inferior podem ser transferidas para uma ferramenta de modelagem e relatórios de riscos empresariais.
  • Os resultados são relatados em um formato definido nos momentos necessários para atender aos requisitos regulatórios e dos investidores.

A Microsoft ajuda a suprir essas necessidades por meio de uma combinação de serviços do Azure e de ofertas de parceiros no Azure Marketplace. Neste artigo, há exemplos práticos que mostram como executar experimentos ad-hoc usando a linguagem R. Começamos explicando como executar o experimento em uma única máquina. Em seguida, mostraremos como executar o mesmo experimento no Lote do Azure e, por fim, mostraremos como aproveitar os serviços externos para a modelagem. As opções e considerações para a execução de modelos definidos no Azure são descritas nestes artigos que se concentram em bancos e seguradoras.

Modelagem analítica em R

Vamos começar examinando como o R pode ser usado por um analista em um cenário de mercados de capital simplificado e representativo. Você pode fazer isso fazendo referência a uma biblioteca de R existente para o cálculo ou escrevendo o código do zero. Em nosso exemplo, também precisamos buscar dados externos de precificação. Para manter o exemplo simples, mas ilustrativo, podemos calcular a PFE (exposição potencial futura) de um contrato de ações patrimoniais. Este exemplo evita técnicas complexas de modelagem quantitativa para instrumentos como derivativos complexos e se concentra em um único fator de risco para se concentrar no ciclo de vida de risco. Nosso exemplo permite que você faça o seguinte:

  • Seleciona um instrumento de interesse.
  • Obtém preços históricos do instrumento.
  • Modelar o preço das ações usando o cálculo MC (Monte Carlo) simples, que usa GBM (Movimento Browniano Geométrico):
    • Estima o retorno esperado μ (mu) e a volatilidade σ (teta).
    • Calibra o modelo de dados históricos.
  • Visualiza os vários caminhos para comunicar os resultados.
  • Plot max(0,Stock Value) para demonstrar o significado de PFE (exposição potencial futura), a diferença em relação ao VaR (valor em risco) Para esclarecer:

    PFE = Share Price (T) -- Forward Contract Price K

  • Use o quantil 0,95 para obter o valor da PFE em cada etapa/término do período de simulação.

Nós calculamos a PFE de uma ação a termo com base em ações da Microsoft (MSFT). Conforme mencionado anteriormente, para modelar os preços das ações, são necessários os preços históricos das ações da MSFT para que possamos calibrar o modelo de dados históricos. Há várias maneiras de obter preços históricos de ações. Em nosso exemplo, usamos uma versão gratuita de um serviço de preços de ações de um provedor de serviços externo, a Quandl.

Observação

O exemplo usa o Conjunto de dados Preços WIKI, que pode ser usado para o aprendizado dos conceitos. Para obter o preço de ações baseadas nos EUA para uso em produção, a Quandl recomenda usar o conjunto de dados End of Day US Stock Prices.

Para processar os dados e definir o risco associado à ação, é preciso fazer o seguinte:

  • Recuperar dados históricos da ação.
  • Determinar o retorno esperado μ e a volatilidade σ dos dados históricos.
  • Modelar os preços das ações subjacentes usando simulação.
  • Executar o modelo.
  • Determinar a exposição da ação no futuro.

Nós começamos recuperando a ação no serviço da Quandl e plotando o histórico de preços nos últimos 180 dias.

# Lubridate package must be installed
if (!require(lubridate)) install.packages('lubridate')
library(lubridate)

# Quandl package must be installed
if (!require(Quandl)) install.packages('Quandl')
library(Quandl)

# Get your API key from quandl.com
quandl_api = "enter your key here"

# Add the key to the Quandl keychain
Quandl.api_key(quandl_api)

quandl_get <-
    function(sym, start_date = "2018-01-01") {
        require(devtools)
        require(Quandl)
        # Retrieve the Open, High, Low, Close and Volume Column for a given Symbol
        # Column Indices can be deduced from this sample call
        # data <- Quandl(c("WIKI/MSFT"), rows = 1)

        tryCatch(Quandl(c(
        paste0("WIKI/", sym, ".8"),    # Column 8 : Open
        paste0("WIKI/", sym, ".9"),    # Column 9 : High
        paste0("WIKI/", sym, ".10"),   # Column 10: Low
        paste0("WIKI/", sym, ".11"),   # Column 11: Close
        paste0("WIKI/", sym, ".12")),  # Column 12: Volume
        start_date = start_date,
        type = "raw"
        ))
    }

# Define the Equity Forward
instrument.name <- "MSFT"
instrument.premium <- 100.1
instrument.pfeQuantile <- 0.95

# Get the stock price for the last 180 days
instrument.startDate <- today() - days(180)

# Get the quotes for an equity and transform them to a data frame
df_instrument.timeSeries <- quandl_get(instrument.name,start_date = instrument.startDate)

#Rename the columns
colnames(df_instrument.timeSeries) <- c()
colnames(df_instrument.timeSeries) <- c("Date","Open","High","Low","Close","Volume")

# Plot the closing price history to get a better feel for the data
plot(df_instrument.timeSeries$Date, df_instrument.timeSeries$Close)

Com os dados em mãos, podemos calibrar o modelo de GBM.

# Code inspired by the book Computational Finance, An Introductory Course with R by
#    A. Arratia.

# Calculate the daily return in order to estimate sigma and mu in the Wiener Process
df_instrument.dailyReturns <- c(diff(log(df_instrument.timeSeries$Close)), NA)

# Estimate the mean of std deviation of the log returns to estimate the parameters of the Wiener Process

estimateGBM_Parameters <- function(logReturns,dt = 1/252) {

    # Volatility
    sigma_hat = sqrt(var(logReturns)) / sqrt(dt)

    # Drift
    mu_hat = mean(logReturns) / dt + sigma_hat**2 / 2.0

    # Return the parameters
    parameter.list <- list("mu" = mu_hat,"sigma" = sigma_hat)

    return(parameter.list)
}

# Calibrate the model to historic data
GBM_Parameters <- estimateGBM_Parameters(df_instrument.dailyReturns[1:length(df_instrument.dailyReturns) - 1])

Em seguida, modelamos os preços de ações subjacentes. Podemos implementar o processo de GBM discreto do zero ou usar um dos muitos pacotes de R que fornecem essa funcionalidade. Usamos o pacote de R sde (Simulation and Inference for Stochastic Differential Equations) que fornece um método para solucionar este problema. O método GBM requer um conjunto de parâmetros que são calibrados para dados históricos ou fornecidos como parâmetros de simulação. Nós usamos os dados históricos, fornecendo μ, σ e os preços das ações no início da simulação (P0).

if (!require(sde)) install.packages('sde')
library(sde)

sigma <- GBM_Parameters$sigma
mu <- GBM_Parameters$mu
P0 <- tail(df_instrument.timeSeries$Close, 1)

# Calculate the PFE looking one month into the future
T <- 1 / 12

# Consider nt MC paths
nt=50

# Divide the time interval T into n discrete time steps
n = 2 ^ 8

dt <- T / n
t <- seq(0,T,by=dt)

Agora, estamos prontos para começar uma simulação de Monte Carlo para modelar a exposição potencial para certo número de caminhos de simulação. Limitaremos a simulação a 50 caminhos de Monte Carlo e 256 etapas de tempo. Na preparação para dimensionar a simulação e aproveitar a paralelização em R, o loop de simulação de Monte Carlo usa uma instrução foreach.

# Track the start time of the simulation
start_s <- Sys.time()

# Instead of a simple for loop to execute a simulation per MC path, call the
# simulation with the foreach package
# in order to demonstrate the similarity to the AzureBatch way to call the method.

library(foreach)
# Execute the MC simulation for the wiener process by using the GBM method from the sde package
exposure_mc <- foreach (i=1:nt, .combine = rbind ) %do% GBM(x = P0, r = mu, sigma = sigma, T = T, N = n)
rownames(exposure_mc) <- c()

# Track the end time of the simulation
end_s <- Sys.time()

# Duration of the simulation

difftime(end_s, start_s)

Agora, simulamos o preço das ações da MSFT subjacentes. Para calcular a exposição da ação, podemos subtrair o prêmio e limitar a exposição somente a valores positivos.

# Calculate the total Exposure as V_i(t) - K, put it to zero for negative exposures
pfe_mc <- pmax(exposure_mc - instrument.premium ,0)

ymax <- max(pfe_mc)
ymin <- min(pfe_mc)
plot(t, pfe_mc[1,], t = 'l', ylim = c(ymin, ymax), col = 1, ylab="Credit Exposure in USD", xlab="time t in Years")
for (i in 2:nt) {
    lines(t, pfe_mc[i,], t = 'l', ylim = c(ymin, ymax), col = i)
}

As próximas duas imagens mostram o resultado da simulação. A primeira imagem mostra a simulação de Monte Carlo do preço da ação subjacente para 50 caminhos. A segunda imagem ilustra a exposição de crédito subjacente da ação a termo após a subtração do prêmio da ação a termo e da limitação da exposição somente a valores positivos.

Figura 1 – 50 caminhos de Monte Carlo

Figura 1 – 50 caminhos de Monte Carlo

Figura 2 – Exposição de Crédito para a Ação

Figura 2 – Exposição de crédito para a ação a termo

Na última etapa, o PFE do quantil 0,95 de 1 mês é calculado com o código a seguir.

# Calculate the PFE at each time step
df_pfe <- cbind(t,apply(pfe_mc,2,quantile,probs = instrument.pfeQuantile ))

resulting in the final PFE plot
plot(df_pfe, t = 'l', ylab = "Potential future exposure in USD", xlab = "time t in Years")
Exposição futura potencial para MSFT Equity Forward

Figura 3 – Exposição potencial futura para ações a termo da MSFT

Usando o Lote do Azure com R

A solução de R descrita acima pode ser conectada ao Lote do Azure para aproveitar a nuvem para cálculos de riscos. Isso demanda pouco esforço extra para um cálculo paralelo como o nosso. O tutorial Executar uma simulação de R paralela com o Lote do Azure fornece informações detalhadas sobre como conectar o R ao Lote do Azure. A seguir, mostramos o código e o resumo do processo para se conectar ao Lote do Azure e como tirar proveito da extensão para a nuvem em um cálculo de PFE simplificado.

Este exemplo lida com o mesmo modelo descrito anteriormente. Como vimos anteriormente, esse cálculo pode ser executado em nosso PC. Aumentos no número de caminhos de Monte Carlo ou o uso de etapas de tempo menores resulta em tempos de execução muito maiores. Quase todo o código R permanecerá inalterado. Vamos destacar as diferenças nesta seção.

Cada caminho da simulação de Monte Carlo é executado no Azure. Podemos fazer isso porque cada caminho é independente dos outros, o que nos dá um cálculo que é facilmente paralelizado.

Para usar o Lote do Azure, podemos definir o cluster subjacente e referenciá-lo no código antes do cluster poder ser usado nos cálculos. Para executar os cálculos, usamos a seguinte definição de JSON:

{
  "name": "myMCPool",
  "vmSize": "Standard_D2_v2",
  "maxTasksPerNode": 4,
  "poolSize": {
    "dedicatedNodes": {
      "min": 1,
      "max": 1
    },
    "lowPriorityNodes": {
      "min": 3,
      "max": 3
    },
    "autoscaleFormula": "QUEUE"
  },
  "containerImage": "rocker/tidyverse:latest",
  "rPackages": {
    "cran": [],
    "github": [],
    "bioconductor": []
  },
  "commandLine": [],
  "subnetId": ""
}

Com essa definição de cluster, o seguinte código de R usa o cluster:


# Define the cloud burst environment
library(doAzureParallel)

# set your credentials
setCredentials("credentials.json")

# Create your cluster if not exist
cluster <- makeCluster("cluster.json")

# register your parallel backend
registerDoAzureParallel(cluster)

# check that your workers are up
getDoParWorkers()

Por fim, podemos atualizar a instrução foreach de antes para usar o pacote doAzureParallel. É uma pequena alteração, adicionando uma referência ao pacote sde e alterando %do% para %dopar%:

# Execute the MC simulation for the wiener process using the GBM method from the sde package and extend the computation to the cloud
exposure_mc <- foreach(i = 1:nt, .combine = rbind, .packages = 'sde') %dopar% GBM(x = P0, r = mu, sigma = sigma, T = T, N = n)
rownames(exposure_mc) <- c()

Cada simulação de Monte Carlo é enviada como uma tarefa ao Lote do Azure. A tarefa é executada na nuvem. Os resultados são mesclados antes de serem enviados para o workbench de analista. O trabalho pesado e os cálculos são executados na nuvem para aproveitar ao máximo a escala e a infraestrutura subjacente exigida pelos cálculos solicitados.

Após o fim da execução dos cálculos, os recursos adicionais podem facilmente ser desligados invocando a seguinte instrução única:

# Stop the cloud cluster
stopCluster(cluster)

Usar uma oferta de SaaS

Os dois primeiros exemplos mostram como usar a infraestrutura local e de nuvem para desenvolver de um modelo de avaliação adequado. Esse paradigma começou a mudar. Da mesma maneira que a infraestrutura local se transformou serviços de IaaS e PaaS baseados em nuvem, a modelagem de cálculos de risco relevantes se transformou em um processo orientado a serviços. Os analistas de hoje enfrentam dois grandes desafios:

  • Os requisitos regulatórios usam cada vez mais capacidade de computação para adicionar a requisitos de modelagem. Os reguladores pedem cálculos de risco cada vez mais frequentes e atualizados.
  • A infraestrutura de risco existente cresceu de maneira orgânica com o tempo e cria desafios ao implementar novos requisitos e uma modelagem de risco mais avançada de maneira ágil.

Serviços baseados em nuvem podem fornecer a funcionalidade necessária e dar suporte à análise de risco. Essa abordagem tem algumas vantagens:

  • Os cálculos de riscos mais comuns exigidos pelo regulador devem ser implementados por todos os usuários sujeitos à regulamentação. Usando os serviços de um provedor especializado, o analista se beneficia de cálculos de riscos em conformidade com as exigências do regulador e prontos para uso. Esses serviços podem incluir cálculos de riscos de mercado, cálculos de riscos de contraparte, XVA (ajuste do valor de X) e até mesmo cálculos de FRTB (Fundamental Review of Trading Book).
  • Esses serviços expõem suas interfaces por meio de serviços Web. A infraestrutura de risco existente pode ser aprimorada por esses outros serviços.

Em nosso exemplo, gostaríamos de invocar um serviço baseado em nuvem para cálculos de FRTB. Vários desses podem ser encontrados no AppSource. Para este artigo, escolhemos uma opção de avaliação da Vector Risk. Continuaremos a modificar nosso sistema. Desta vez, usamos um serviço para calcular o risco dos juros. O processo é composto pelas seguintes etapas:

  1. Chamar o serviço de risco relevante com os parâmetros certos.
  2. Aguardar até que o serviço termine o cálculo.
  3. Recuperar e incorporar os resultados da análise de risco.

Traduzido em código R, nosso código R pode ser aprimorado pela definição dos valores de entrada necessários de um modelo de entrada preparado.

Template <- readLines('RequiredInputData.json')
data <- list(
# drilldown setup
  timeSteps = seq(0, n, by = 1),
  paths = as.integer(seq(0, nt, length.out = min(nt, 100))),
# calc setup
  calcDate = instrument.startDate,
  npaths = nt,
  price = P0,
  vol = sigma,
  drift = mu,
  premium = instrument.premium,
  maturityDate = today()
  )
body <- whisker.render(template, data)

Em seguida, precisamos chamar o serviço Web. Nesse caso, chamamos o método StartCreditExposure para disparar o cálculo. Armazenamos o ponto de extremidade da API em uma variável chamada endpoint.

# make the call
result <- POST( paste(endpoint, "StartCreditExposure", sep = ""),
                authenticate(username, password, type = "basic"),
                content_type("application/json"),
                add_headers(`Ocp-Apim-Subscription-Key` = api_key),
                body = body, encode = "raw"
               )

result <- content(result)

Depois de terminar de executar os cálculos, podemos recuperar os resultados.

# get back high level results
result <- POST( paste(endpoint, "GetCreditExposureResults", sep = ""),
                authenticate(username, password, type = "basic"),
                content_type("application/json"),
                add_headers(`Ocp-Apim-Subscription-Key` = api_key),
               body = sprintf('{"getCreditExposureResults": {"token":"DataSource=Production;Organisation=Microsoft", "ticket": "%s"}}', ticket), encode = "raw")

result <- content(result)

Depois disso, o analista continua com os resultados recebidos. Os cálculos de risco relevantes de juros são extraídos dos resultados e plotados.

if (!is.null(result$error)) {
    cat(result$error$message)
} else {
    # plot PFE
    result <- result$getCreditExposureResultsResponse$getCreditExposureResultsResult
    df <- do.call(rbind, result$exposures)
    df <- as.data.frame(df)
    df <- subset(df, term <= n)
}

plot(as.numeric(df$term[df$statistic == 'PFE']) / 365, df$result[df$statistic == 'PFE'], type = "p", xlab = ("time t in Years"), ylab = ("Potential future exposure in USD"), ylim = range(c(df$result[df$statistic == 'PFE'], df$result[df$statistic == 'PFE'])), col = "red")

Os gráficos resultantes são semelhantes a este:

Figura 4 - Exposição de crédito para ações MSFT a termo - Calculada com um mecanismo de risco baseado em nuvem.

Figura 4 – Exposição de crédito para a ação a termo da MSFT (calculada com um mecanismo de risco baseado em nuvem)

Figura 5 – Exposição potencial futura para a ação a termo da MSFT (calculada com um mecanismo de risco baseado em nuvem)

Figura 5 – Exposição potencial futura para a ação a termo da MSFT (calculada com um mecanismo de risco baseado em nuvem)

Considerações

O acesso flexível à nuvem por meio da infraestrutura de computação e de serviços de análise de risco baseada em SaaS pode oferecer melhorias na velocidade e na agilidade para analistas de risco que trabalham com seguros e mercado de capital. Neste artigo, trabalhamos em um exemplo que ilustra como usar o Azure e outros serviços usando ferramentas que analistas de risco conhecem. Tente tirar proveito dos recursos do Azure conforme você cria e aprimora seus modelos de risco.

Colaboradores

Esse artigo é mantido pela Microsoft. Ele foi originalmente escrito pelos colaboradores a seguir.

Principais autores:

  • Dr. Darko Mocelj - Brasil | HPC Global Blackbelt & AI Especialista em Tecnologia Sr.
  • Rupert Nicolay | Líder de soluções do setor de serviços financeiros

Próximas etapas