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

Os cálculos de risco são fundamentais em várias fases do ciclo de vida das principais operações de serviços financeiros. Por exemplo, uma forma simplificada do ciclo de vida da gestão de produtos de seguros pode ser semelhante ao diagrama abaixo. Os aspetos do cálculo do risco são apresentados em texto azul.

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

Um cenário em uma empresa de mercado de capitais pode ser assim:

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

Em processos como estes, existem necessidades comuns de modelagem de risco, incluindo:

  • A necessidade de experimentação ad hoc relacionada com o risco por parte de analistas de risco, tais como atuários numa empresa de seguros ou quants numa empresa do mercado de capitais. Esses analistas normalmente trabalham com ferramentas de código e modelagem que são populares em seu domínio: R e Python. Muitos currículos universitários incluem formação em R ou Python em finanças matemáticas e cursos de MBA. Ambas as línguas têm acesso a uma vasta gama de bibliotecas de código aberto que suportam cálculos de risco populares.
  • Juntamente com as ferramentas apropriadas, os analistas geralmente precisam ter acesso a:
    • Dados precisos de preços de mercado.
    • Dados de políticas e reclamações.
    • Dados de posição no mercado.
    • Outros dados externos, tais como:
      • Dados estruturados, como tabelas de mortalidade e dados de preços competitivos.
      • Tipos menos tradicionais, como clima e notícias.
    • Capacidade computacional para investigações rápidas e interativas de dados.
  • Em alguns casos, algoritmos ad-hoc de aprendizado de máquina para precificar ou determinar a estratégia de mercado.
  • A capacidade de visualizar e apresentar dados para uso no planejamento de produtos, estratégia de negociação e discussões semelhantes.
  • A rápida execução 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 cálculos noturnos, semanais, mensais, trimestrais e anuais variáveis. Essa análise gera picos nas cargas de trabalho.
  • A integração de dados com outras medidas de risco em toda a empresa para relatórios de risco consolidados. Em organizações maiores, estimativas de risco de nível mais baixo podem ser transferidas para uma ferramenta para modelagem e relatórios de risco empresarial.
  • Resultados reportados num formato definido nos momentos necessários para cumprir os requisitos regulamentares e dos investidores.

A Microsoft ajuda a atender a essas necessidades por meio de uma combinação de serviços do Azure e ofertas de parceiros no Azure Marketplace. Neste artigo, há exemplos práticos que mostram como realizar experimentação ad-hoc usando R. Começamos explicando como executar o experimento em uma única máquina. Em seguida, mostramos como executar o mesmo experimento no Azure Batch e encerramos mostrando 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 seguros.

Analista de modelagem em R

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

  • Selecione um instrumento de interesse.
  • Fonte: preços históricos para o instrumento.
  • Modele a ação do preço da ação usando o cálculo simples de Monte Carlo (MC), que usa o Movimento Browniano Geométrico (GBM):
    • Estimar μ de retorno esperado (mu) e σ de volatilidade (theta).
    • Calibrar o modelo para dados históricos.
  • Visualize os vários caminhos para comunicar os resultados.
  • Plotar max(0,Stock Value) para demonstrar o significado de PFE, a diferença para o valor em risco (VaR). Para esclarecer:

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

  • Pegue o Quantil 0,95 para obter o valor PFE em cada etapa de tempo / final do período de simulação.

Vamos calcular o PFE para um forward de capital com base nas ações da Microsoft (MSFT). Como mencionado anteriormente, para modelar os preços das ações, os preços históricos para as ações MSFT são necessários para que possamos calibrar o modelo para dados históricos. Existem muitas maneiras de adquirir preços históricos de ações. Em nosso exemplo, usamos uma versão gratuita de um serviço de preço de ações de um provedor de serviços externo, Quandl.

Nota

O exemplo usa o conjunto de dados WIKI Prices que pode ser usado para aprender conceitos. Para o uso de produção de ações baseadas nos EUA, Quandl recomenda o uso do conjunto de dados de preços de ações dos EUA no final do dia.

Para processar os dados e definir o risco associado ao patrimônio, precisamos fazer as seguintes coisas:

  • Recupere dados do histórico do patrimônio.
  • Determine o μ de retorno esperado e os σ de volatilidade a partir dos dados históricos.
  • Modele os preços das ações subjacentes usando alguma simulação.
  • Execute o modelo.
  • Determinar a exposição do capital no futuro.

Começamos recuperando o estoque do serviço Quandl e traçando o histórico de preços de fechamento 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, calibramos o modelo 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 das ações subjacentes. Podemos implementar o processo GBM discreto a partir do zero ou usar um dos muitos pacotes R que fornecem essa funcionalidade. Utilizamos o pacote R sde (Simulação e Inferência para Equações Diferenciais Estocásticas) que fornece um método para resolver 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. Utilizamos 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 iniciar uma simulação de Monte Carlo para modelar a exposição potencial para algum número de caminhos de simulação. Vamos limitar a simulação a 50 caminhos de Monte Carlo e 256 passos de tempo. Em preparação para dimensionar a simulação e tirar proveito da 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 subjacentes da MSFT. Para calcular a exposição do capital a prazo, subtraímos o prémio e limitamos a exposição apenas 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 duas imagens seguintes mostram o resultado da simulação. A primeira imagem mostra a simulação de Monte Carlo do preço das ações subjacentes para 50 caminhos. O segundo quadro ilustra a exposição de crédito subjacente ao capital a prazo após subtrair o prémio do capital a prazo e limitar a exposição 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ções a prazo

Figura 2 - Posição em risco de crédito relativa a ações a prazo

Na última etapa, o PFE quantílico de 0,95 mês é calculado pelo 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 futura potencial para ações da MSFT a prazo

Usando o Azure Batch com R

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

Este exemplo aborda o mesmo modelo descrito anteriormente. Como vimos anteriormente, este cálculo pode ser executado no nosso computador pessoal. Aumentos no número de caminhos de Monte Carlo ou o uso de etapas de tempo menores resultarão em tempos de execução muito mais longos. Quase todo o código R permanecerá inalterado. Destacaremos 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, dando-nos um cálculo que é facilmente paralelizado.

Para usar o Lote do Azure, definimos o cluster subjacente e o referenciamos no código antes que o cluster possa ser usado nos cálculos. Para executar os cálculos, usamos a seguinte definição de cluster.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 R faz uso do 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()

Finalmente, atualizamos 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 para o Azure Batch. A tarefa é executada na nuvem. Os resultados são mesclados antes de serem enviados de volta para a bancada de trabalho do analista. O trabalho pesado e os cálculos são executados na nuvem para tirar o máximo proveito do dimensionamento e da infraestrutura subjacente exigida pelos cálculos solicitados.

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

# Stop the cloud cluster
stopCluster(cluster)

Use uma oferta SaaS

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

  • Os requisitos normativos usam uma capacidade de computação crescente para aumentar os requisitos de modelagem. Os reguladores pedem números de risco mais frequentes e atualizados.
  • A infraestrutura de risco existente cresceu organicamente com o tempo e cria desafios ao implementar novos requisitos e modelagem de risco mais avançada de forma ágil.

Os serviços baseados na nuvem podem fornecer a funcionalidade necessária e suportar a análise de risco. Esta abordagem tem algumas vantagens:

  • Os cálculos de risco mais comuns exigidos pelo regulador devem ser implementados por todos ao abrigo do regulamento. Ao usar serviços de um provedor de serviços especializado, o analista se beneficia de cálculos de risco prontos para uso e em conformidade com o regulador. Tais serviços podem incluir cálculos de risco de mercado, cálculos de risco de contraparte, Ajuste de Valor X (XVA) e até mesmo caculações de Revisão Fundamental da Carteira de Negociação (FRTB).
  • Esses serviços expõem suas interfaces por meio de serviços da Web. A infraestrutura de risco existente pode ser reforçada por estes outros serviços.

Em nosso exemplo, queremos invocar um serviço baseado em nuvem para cálculos de FRTB. Vários deles podem ser encontrados no AppSource. Para este artigo, escolhemos uma opção de avaliação do Vetor Risk. Continuaremos a modificar o nosso sistema. Desta vez, usamos um serviço para calcular o valor de risco de interesse. Este processo consiste nas seguintes etapas:

  1. Ligue para o serviço de risco relevante com os parâmetros corretos.
  2. Aguarde até que o serviço termine o cálculo.
  3. Recuperar e incorporar os resultados na 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 a partir 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 acionar 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)

Uma vez terminados os cálculos, recuperamos 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)

Isso deixa o analista para continuar com os resultados recebidos. Os valores de risco relevantes de interesse 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 assim:

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

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

Figura 5 - Exposição futura potencial para ações MSFT forward - Calculado com um mecanismo de risco baseado em nuvem

Figura 5 - Exposição futura potencial para ações MSFT forward - Calculado com um mecanismo de risco baseado em nuvem

Considerações

O acesso flexível à nuvem por meio de infraestrutura de computação e serviços de análise de risco baseados em SaaS pode oferecer melhorias em velocidade e agilidade para analistas de risco que trabalham em mercados de capitais e seguros. Neste artigo, trabalhamos com um exemplo que ilustra como usar o Azure e outros serviços usando ferramentas que os analistas de risco conhecem. Experimente tirar partido das capacidades do Azure à medida que cria e melhora os seus modelos de risco.

Contribuidores

Este artigo é mantido pela Microsoft. Foi originalmente escrito pelos seguintes contribuidores.

Principais autores:

  • Dr. Darko Mocelj - Brasil | HPC Global Blackbelt & AI Especialista em Tecnologia Sr.
  • Rupert Nicolay - Brasil | Líder de Soluções para o Setor de Serviços Financeiros

Próximos passos