Computação em Finanças em Hardware Gráfico
SEMAC 2012 - UNESP




Thársis T. P. Souza
t.souza@usp.br


                      Instituto de Matemática e Estatística - Universidade de São Paulo
    GPU Computing

    CUDA

    Aplicações em Finanças
      Precificação de Opções
      Risco de Mercado

    Conclusão



16/05/2012        Instituto de Matemática e Estatística - Universidade de São Paulo   2
    GPU Computing

    CUDA

    Aplicações em Finanças
      Precificação de Opções
      Risco de Mercado

    Conclusão



16/05/2012        Instituto de Matemática e Estatística - Universidade de São Paulo   3
CPU                                                             GPU
     Tarefas sequenciais                                     Tarefas com paralelismo de dados
     Cache eficiente                                         Múltiplas ULAs
     Maior quantidade de memória                             Maior (capacidade) operações de
      principal                                                ponto flutuante por segundo
                                                              Alto throughput de memória
     Controle de fluxo
                                                              Dezenas de multiprocessors
     Número de cores de 1 ordem
      de grandeza                                             Múltiplas threads por
                                                               multiprocessor
     1, 2 threads por core
16/05/2012         Instituto de Matemática e Estatística - Universidade de São Paulo              4
Figura 1: Número de operações de ponto flutuante por segundo
16/05/2012            Instituto de Matemática e Estatística - Universidade de São Paulo   5
Figura 2: Throughput de memória CPU x GPU
16/05/2012      Instituto de Matemática e Estatística - Universidade de São Paulo   6
48 GPUs          42x Lower Space                                                     2000 CPUs

  $144K             28x Lower Cost                                                    $4 Million

$31K / year     38x Lower Power Cost                                          $1.2 Million / year
                                                                                               Fonte: NVIDIA Brasil
   16/05/2012     Instituto de Matemática e Estatística - Universidade de São Paulo                            7
2 Tesla S1070s    16x Less Space                                          500 CPU Servers

    $24 K         10x Lower Cost                                                     $250 K

 2.8 kWatts      13x Lower Power                                               37.5 kWatts
                                                                                              Fonte: NVIDIA Brasil
 16/05/2012      Instituto de Matemática e Estatística - Universidade de São Paulo                            8
    General-purpose computing on Graphics Processing Units
      Técnica de uso de GPU para computação de propósito geral

    Linguagens/API’s
        OpenGL
        DirectX
        Cg
        Brook
        Brook+
        OpenCL
        CUDA




16/05/2012
01/04/2011         Instituto de Matemática e Estatística - Universidade de São Paulo   9
16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo   10
   Compute capability: 2.0        Total dedicated memory:               Registers por mp: 32768
     Single Precision Floating       3GB GDDR5                             Threads in warp: 32
      Point Performance : 1.03
      TFlops                         Constant mem: 64KB                    Max threads per block: 1024
     Device copy overlap:                                                  Max thread dimension:
      Enabled                        Numero de                              (1024, 1024, 64)
     Kernel timeout : Disabled       multiprocessadores: 14                Max grid dimension: (65535,
                                                                             65535, 1)
                                     Shared mem por mp: 48KB

16/05/2012                Instituto de Matemática e Estatística - Universidade de São Paulo                11
    GPU Computing

    CUDA

    Aplicações em Finanças
      Precificação de Opções
      Risco de Mercado

    Conclusão



16/05/2012        Instituto de Matemática e Estatística - Universidade de São Paulo   12
   Compute Unified Device Architecture
                Arquitetura paralela de propósito geral
                Tecnologia proprietária NVIDIA

16/05/2012        Instituto de Matemática e Estatística - Universidade de São Paulo   13
    Arquitetura de Computação Paralela
     para propósito geral
      Facilita computação heterogênea (CPU +
         GPU)

    Suporte a varias linguagens e APIs

    CUDA define:
      Modelo de programação
      Modelo de memória
      Modelo de execução




16/05/2012            Instituto de Matemática e Estatística - Universidade de São Paulo   14
    Porções paralelas da aplicação são executadas como kernels

    CUDA threads
      Lighweight
      Fast switching
      Milhares (potencialmente) executadas ao mesmo tempo




16/05/2012         Instituto de Matemática e Estatística - Universidade de São Paulo   15
    Um kernel executa um grid de blocos
     de threads

    Um bloco é formado por um conjunto
     de threads

    Cada thread pode ser unicamente
     endereçada




16/05/2012         Instituto de Matemática e Estatística - Universidade de São Paulo   16
    Thread
      Registradores




16/05/2012         Instituto de Matemática e Estatística - Universidade de São Paulo   17
    Thread
      Registradores

    Thread
      Local Memory




16/05/2012         Instituto de Matemática e Estatística - Universidade de São Paulo   18
    Thread
      Registradores

    Thread
      Local Memory

    Bloco
      Shared Memory




16/05/2012         Instituto de Matemática e Estatística - Universidade de São Paulo   19
    Thread
      Registradores

    Thread
      Local Memory

    Bloco
      Shared Memory

    Grid
      Global Memory




16/05/2012         Instituto de Matemática e Estatística - Universidade de São Paulo   20
    Biblioteca e um compilador para criação de rotinas em GPUs
     NVIDIA

    API de mais alto nível em comparação com: Cg, OpenGL, DirectX

    Exige conhecimento de arquitetura para codificação

    Amplamente utilizada

    Possui grande comunidade e boa documentação

    Maioria de artigos publicados em programação em GPGPU utiliza
     CUDA C


16/05/2012         Instituto de Matemática e Estatística - Universidade de São Paulo   21
#include <stdlib.h>
#include <stdio.h>                                         int block_size = 128;
                                                           int grid_size = num_elements /
__global__ void kernel(int *array)                            block_size;
{
   //do work
}                                                            kernel<<<grid_size,block_size>>>(de
                                                             vice_array);
int main(void)
{                                                          cudaMemcpy(host_array, device_array,
  int num_elements = 256;                                    num_bytes,
                                                             cudaMemcpyDeviceToHost);
  int num_bytes = num_elements *
     sizeof(int);                                          for(int i=0; i < num_elements; ++i)
                                                           {
  int *host_array = 0;                                       printf("%d ", host_array[i]);
                                                           }
  host_array = (int*)malloc(num_bytes);
                                                           free(host_array);
 int *device_array = 0;                                    cudaFree(device_array);
                                                       }
  cudaMalloc((void**)&device_array,
    num_bytes);

16/05/2012                Instituto de Matemática e Estatística - Universidade de São Paulo        22
#include <stdlib.h>
#include <stdio.h>                                         int block_size = 128;
                                                           int grid_size = num_elements /
__global__ void kernel(int *array)                            block_size;
{
     //do work
}                                                            kernel<<<grid_size,block_size>>>(de
// C function                                                vice_array);
int main(void)
{                                                          cudaMemcpy(host_array, device_array,
  int num_elements = 256;                                    num_bytes,
                                                             cudaMemcpyDeviceToHost);
  int num_bytes = num_elements *
     sizeof(int);                                          for(int i=0; i < num_elements; ++i)
                                                           {
  int *host_array = 0;                                       printf("%d ", host_array[i]);
                                                           }
  host_array = (int*)malloc(num_bytes);
                                                           free(host_array);
 int *device_array = 0;                                    cudaFree(device_array);
                                                       }
  cudaMalloc((void**)&device_array,
    num_bytes);

16/05/2012                Instituto de Matemática e Estatística - Universidade de São Paulo        23
#include <stdlib.h>
#include <stdio.h>                                         int block_size = 128;
                                                           int grid_size = num_elements /
__global__ void kernel(int *array)                            block_size;
{
   //do work
}                                                            kernel<<<grid_size,block_size>>>(de
                                                             vice_array);
int main(void)
{                                                          cudaMemcpy(host_array, device_array,
  int num_elements = 256;                                    num_bytes,
                                                             cudaMemcpyDeviceToHost);
 int num_bytes = num_elements *
     sizeof(int);                                          for(int i=0; i < num_elements; ++i)
// ponteiro para host memory                               {
 int *host_array = 0;                                        printf("%d ", host_array[i]);
// aloca espaço em host memory                             }
 host_array = (int*)malloc(num_bytes);
                                                           free(host_array);
 int *device_array = 0;                                    cudaFree(device_array);
                                                       }
  cudaMalloc((void**)&device_array,
    num_bytes);

16/05/2012                Instituto de Matemática e Estatística - Universidade de São Paulo        24
#include <stdlib.h>
#include <stdio.h>                                        int block_size = 128;
                                                          int grid_size = num_elements /
__global__ void kernel(int *array)                           block_size;
{
   //do work
}                                                           kernel<<<grid_size,block_size>>>(de
                                                            vice_array);
int main(void)
{                                                         cudaMemcpy(host_array, device_array,
  int num_elements = 256;                                   num_bytes,
                                                            cudaMemcpyDeviceToHost);
  int num_bytes = num_elements *
     sizeof(int);                                         for(int i=0; i < num_elements; ++i)
                                                          {
  int *host_array = 0;                                      printf("%d ", host_array[i]);
                                                          }
  host_array = (int*)malloc(num_bytes);
// Ponteiro para device memory                            free(host_array);
 int *device_array = 0;                                   cudaFree(device_array);
// Aloca espaço em device memory                      }
  cudaMalloc((void**)&device_array,
     num_bytes);

16/05/2012               Instituto de Matemática e Estatística - Universidade de São Paulo        25
#include <stdlib.h>                                        // configuracao de bloco e grid
#include <stdio.h>                                         int block_size = 128;
                                                           int grid_size = num_elements /
__global__ void kernel(int *array)                             block_size;
{
   //do work
}                                                            kernel<<<grid_size,block_size>>>(de
                                                             vice_array);
int main(void)
{                                                          cudaMemcpy(host_array, device_array,
  int num_elements = 256;                                    num_bytes,
                                                             cudaMemcpyDeviceToHost);
  int num_bytes = num_elements *
     sizeof(int);                                          for(int i=0; i < num_elements; ++i)
                                                           {
  int *host_array = 0;                                       printf("%d ", host_array[i]);
                                                           }
  host_array = (int*)malloc(num_bytes);
                                                           free(host_array);
 int *device_array = 0;                                    cudaFree(device_array);
                                                       }
  cudaMalloc((void**)&device_array,
    num_bytes);

16/05/2012                Instituto de Matemática e Estatística - Universidade de São Paulo        26
#include <stdlib.h>
#include <stdio.h>                                         int block_size = 128;
// extensao __global __ define kernel                      int grid_size = num_elements /
__global__ void kernel(int *array)                            block_size;
{
    //do work                                          // lancamento do kernel
}                                                           kernel<<<grid_size,block_size>>>(de
                                                            vice_array);
int main(void)
{                                                          cudaMemcpy(host_array, device_array,
  int num_elements = 256;                                    num_bytes,
                                                             cudaMemcpyDeviceToHost);
  int num_bytes = num_elements *
     sizeof(int);                                          for(int i=0; i < num_elements; ++i)
                                                           {
  int *host_array = 0;                                       printf("%d ", host_array[i]);
                                                           }
  host_array = (int*)malloc(num_bytes);
                                                           free(host_array);
 int *device_array = 0;                                    cudaFree(device_array);
                                                       }
  cudaMalloc((void**)&device_array,
    num_bytes);

16/05/2012                Instituto de Matemática e Estatística - Universidade de São Paulo       27
#include <stdlib.h>
#include <stdio.h>                                         int block_size = 128;
                                                           int grid_size = num_elements /
__global__ void kernel(int *array)                            block_size;
{
   //do work
}                                                           kernel<<<grid_size,block_size>>>(de
                                                            vice_array);
int main(void)                                         // transfere resultado da GPU para CPU
{                                                        cudaMemcpy(host_array, device_array,
  int num_elements = 256;                                   num_bytes,
                                                            cudaMemcpyDeviceToHost);
  int num_bytes = num_elements *
     sizeof(int);                                          for(int i=0; i < num_elements; ++i)
                                                           {
  int *host_array = 0;                                       printf("%d ", host_array[i]);
                                                           }
  host_array = (int*)malloc(num_bytes);
                                                           free(host_array);
 int *device_array = 0;                                    cudaFree(device_array);
                                                       }
  cudaMalloc((void**)&device_array,
    num_bytes);

16/05/2012                Instituto de Matemática e Estatística - Universidade de São Paulo       28
#include <stdlib.h>
#include <stdio.h>                                         int block_size = 128;
                                                           int grid_size = num_elements /
__global__ void kernel(int *array)                            block_size;
{
   //do work
}                                                            kernel<<<grid_size,block_size>>>(de
                                                             vice_array);
int main(void)
{                                                        cudaMemcpy(host_array, device_array,
  int num_elements = 256;                                   num_bytes,
                                                            cudaMemcpyDeviceToHost);
  int num_bytes = num_elements *                       // inspecao do resultado
     sizeof(int);                                       for(int i=0; i < num_elements; ++i)
                                                        {
  int *host_array = 0;                                    printf("%d ", host_array[i]);
                                                        }
  host_array = (int*)malloc(num_bytes);
                                                           free(host_array);
 int *device_array = 0;                                    cudaFree(device_array);
                                                       }
  cudaMalloc((void**)&device_array,
    num_bytes);

16/05/2012                Instituto de Matemática e Estatística - Universidade de São Paulo        29
#include <stdlib.h>
#include <stdio.h>                                      int block_size = 128;
                                                        int grid_size = num_elements /
__global__ void kernel(int *array)                         block_size;
{
   //do work
}                                                           kernel<<<grid_size,block_size>>>(de
                                                            vice_array);
int main(void)
{                                                        cudaMemcpy(host_array, device_array,
  int num_elements = 256;                                  num_bytes,
                                                           cudaMemcpyDeviceToHost);
  int num_bytes = num_elements *
     sizeof(int);                                        for(int i=0; i < num_elements; ++i)
                                                         {
  int *host_array = 0;                                     printf("%d ", host_array[i]);
                                                         }
  host_array = (int*)malloc(num_bytes);                 // desaloca memoria
                                                         free(host_array);
 int *device_array = 0;                                  cudaFree(device_array);
                                                       }
  cudaMalloc((void**)&device_array,
    num_bytes);

16/05/2012                Instituto de Matemática e Estatística - Universidade de São Paulo       30
16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo   31
    Definido por extensão __global__

    Configurado por sintaxe <<<grid_size, block_size>>>




16/05/2012         Instituto de Matemática e Estatística - Universidade de São Paulo   32
16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo   33
    Todas as threads em um mesmo grid executam o mesmo kernel
      Necessidade de haver coordenadas únicas para distinção

    Coordenadas criadas pelo CUDA Runtime System:
        blockIdx índice do bloco
        threadIdx índice da thread
        gridDim dimensão do grid
        blockDim dimensão dos blocos




16/05/2012            Instituto de Matemática e Estatística - Universidade de São Paulo   34
    Kernel é bidimensional

    Indexação de bloco
            blockIdx.x
            blockIdx.y

    Blocos são tridimensionais

    Indexação de thread
      threadIdx.x
      threadIdx.y
      threadIdx.z




16/05/2012                Instituto de Matemática e Estatística - Universidade de São Paulo   35
16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo   36
16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo   37
    GPU Computing

    CUDA

    Aplicações em Finanças
      Precificação de Opções
      Risco de Mercado

    Conclusão



16/05/2012        Instituto de Matemática e Estatística - Universidade de São Paulo   38
    GPU Computing

    CUDA

    Aplicações em Finanças
      Precificação de Opções
      Risco de Mercado

    Conclusão



16/05/2012        Instituto de Matemática e Estatística - Universidade de São Paulo   39
    Opção: Direito negociável de compra de mercadorias, títulos,
     ações etc., com pagamento em data futura e preços pré
     determinados

    Ativo objeto: ativo ao qual o direito de compra e venda está
     sendo negociado

    Prêmio: Preço da Opção

    Spot: Preço à vista do ativo objeto

    Strike: Preço de exercício da opção. Valor futuro negociado.


16/05/2012         Instituto de Matemática e Estatística - Universidade de São Paulo   40
16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo   41
    Exemplo: Uma Opção de Compra (Call) de Ouro à R$100 em
     24/12 é vendida a R$5. Paga-se um prêmio de R$5 para se ter
     a opção de comprar Ouro à R$100 na data futura 24/12.

    Caso em 24/12 o preço à vista (Spot) do ouro seja maior do
     que R$100 (in-the-money), podemos lucrar ao exercer a
     opção de compra e vendê-la em seguida (day-trade).

    Caso em 24/12 o preço à vista (Spot) do ouro seja menor do
     que R$100 (out-of-money), não vale a pena o exercício da
     opção.



16/05/2012        Instituto de Matemática e Estatística - Universidade de São Paulo   42
       O Modelo de Black & Scholes fornece um valor de prêmio (V)
        para uma Opção:




        S (Spot); X (Strike); T (tempo para vencimento); r (taxa de
         juros); v (Volatilidade); CND (Distribuição Normal Padrão
         Acumulada)
16/05/2012            Instituto de Matemática e Estatística - Universidade de São Paulo   43
    Distribuição Normal Padrão Acumulada:




16/05/2012       Instituto de Matemática e Estatística - Universidade de São Paulo   44
    Distribuição Normal Padrão Acumulada:




    Aproximação como um polinômio de quinta ordem [Hull]:




16/05/2012       Instituto de Matemática e Estatística - Universidade de São Paulo   45
    Passos para Precificação:

      Alocar vetores no Host: hOptSpot(N), hOptStrike(N), ...
      Alocar vetores no Device: dOptSpot(N), dOptStrike(N), ...




16/05/2012           Instituto de Matemática e Estatística - Universidade de São Paulo   46
    Passos para Precificação:

      Alocar vetores no Host: hOptSpot(N), hOptStrike(N), ...
      Alocar vetores no Device: dOptSpot(N), dOptStrike(N), ...

      Inicializar vetores com variáveis dos contratos e mercado
      Transferir vetores da memória host para device memory




16/05/2012           Instituto de Matemática e Estatística - Universidade de São Paulo   47
    Passos para Precificação:

      Alocar vetores no Host: hOptSpot(N), hOptStrike(N), ...
      Alocar vetores no Device: dOptSpot(N), dOptStrike(N), ...

      Inicializar vetores com variáveis dos contratos e mercado
      Transferir vetores da memória host para device memory

      Precificar opção em GPU via Black&Scholes




16/05/2012           Instituto de Matemática e Estatística - Universidade de São Paulo   48
    Passos para Precificação:

      Alocar vetores no Host: hOptSpot(N), hOptStrike(N), ...
      Alocar vetores no Device: dOptSpot(N), dOptStrike(N), ...

      Inicializar vetores com variáveis dos contratos e mercado
      Transferir vetores da memória host para device memory

      Precificar opção em GPU via Black&Scholes

      Transferir resultado da GPU para Host
      Desalocar memória



16/05/2012           Instituto de Matemática e Estatística - Universidade de São Paulo   49
16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo   50
16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo   51
16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo   52
16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo   53
16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo   54
16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo   55
16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo   56
Desempenho CPU vs. GPU
                Precificação de Opções via Black-Scholes




                                                                                 Fonte: Oneye, 2008


16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo                        57
Desempenho CPU vs. GPU
                Precificação de Opções via Black-Scholes




                                                                                 Fonte: Oneye, 2008


16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo                        58
    Muitas vezes, não é possível encontrar uma expressão
     analítica para precificar um derivativo.

    Simulação de Monte Carlo é uma alternativa:

     1.      Definição do comportamento estocástico para os preços do
             instrumento financeiro
     2.      Geração de números aleatórios para simulação
     3.      Cálculo dos valores do instrumento
     4.      Repetir N vezes os passos 2 e 3, com N tendendo ao infinito
     5.      Determinação da precificação a partir da distribuição dos valores
             obtidos anteriormente



16/05/2012               Instituto de Matemática e Estatística - Universidade de São Paulo   59
1.       Definição do Processo Estocástico:

            Assume-se, geralmente, que o preço do instrumento financeiro
             segue um movimento Browniano Geométrico




             sendo, µ = taxa de rentabilidade esperada para o instrumento
                    σ = desvio padrão da taxa de rentabilidade do instrumento
                    dW = representa parcela aleatória do movimento




16/05/2012              Instituto de Matemática e Estatística - Universidade de São Paulo   60
1.       Definição do Processo Estocástico:

            Assim, chega-se a uma expressão que fornece a variação do preço do
             instrumento em um δt:




           onde, 𝜀 𝑡 representa uma variável aleatória que segue uma
     distribuição normal entre 0 e 1.




16/05/2012              Instituto de Matemática e Estatística - Universidade de São Paulo   61
2.     Para geração dos números aleatórios desejados, podemos
       utilizar o método de Box-Muller




             onde, 𝑥1 , 𝑥2 ∈ 𝑁 e 𝑧1 , 𝑧2 ∈ 𝑁(0,1)




16/05/2012             Instituto de Matemática e Estatística - Universidade de São Paulo   62
3.     O Prêmio da Opção (𝑐 𝑡 ) pode ser calculado a partir de um
       valor esperado de seu retorno (Spot – Preço de Exercício)




4.     Ao simular aleatoriamente o preço do instrumento 𝑆 𝑇 ,
       podemos precificar a opção como




16/05/2012         Instituto de Matemática e Estatística - Universidade de São Paulo   63
    Toda a geração de números aleatórios pode ser
     naturalmente realizada de forma paralela na GPU

    As simulações dos preços dos instrumentos são
     independentes, portanto podem ser realizadas ao mesmo
     tempo

    A capacidade de gerar maior número de simulações resulta
     em maior precisão no resultado




16/05/2012        Instituto de Matemática e Estatística - Universidade de São Paulo   64
Desempenho CPU vs. GPU
                            Método Box-Muller




                                                                                 [Myungho]


16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo               65
Desempenho CPU vs. GPU
                            Método Box-Muller




                                                                                 [Myungho]


16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo               66
Desempenho CPU vs. GPU
                      Simulação de Monte Carlo




                                                                                 [Myungho]


16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo               67
Desempenho CPU vs. GPU
                      Simulação de Monte Carlo




                                                                                 [Myungho]


16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo               68
    GPU Computing

    CUDA

    Aplicações em Finanças
      Precificação de Opções
      Risco de Mercado

    Conclusão



16/05/2012        Instituto de Matemática e Estatística - Universidade de São Paulo   69
    Possibilidade de ocorrência de perdas resultantes da flutuação
     nos valores de mercado de posições ativas e passivas detidas
     pelas instituições financeiras. (JP Morgan)

    O risco de mercado inclui os riscos das operações sujeitas a
         variação cambial,
        taxa de juros,
        preços das ações e
        preços de mercadorias (commodities)




16/05/2012            Instituto de Matemática e Estatística - Universidade de São Paulo   70
    Value-at-Risk representa a perda máxima potencial de uma
     carteira, em um horizonte de tempo definido, com determinado
     grau de confiança

    Exemplo: Banco anuncia para carteira de sua tesouraria, um
     VaR de US$ 15 milhões, para o horizonte de tempo de 1 dia e
     grau de confiança 95%.




16/05/2012        Instituto de Matemática e Estatística - Universidade de São Paulo   71
    Ex.: Supondo uma exposição ao mercado de R$1.000.000,
     teríamos um risco de perda máxima de R$40.000, em um
     dia, com uma confiança de 95%.




16/05/2012       Instituto de Matemática e Estatística - Universidade de São Paulo   72
    VaR Stress: teste que visa a validar a qualidade do VaR
     estimado.

    Simulação de caminhos alternativos do comportamento do
     preço dos instrumentos de uma carteira para avaliar se o
     resultante valor do portfolio excedeu a perda máxima
     prevista pelo VaR.




16/05/2012         Instituto de Matemática e Estatística - Universidade de São Paulo   73
    Como já visto, o preço de um instrumento pode ser simulado
     como:


    Em uma arquitetura serial, cada carteira deve ser precificada
     sequencialmente e os instrumentos são simulados
     iterativamente.




16/05/2012         Instituto de Matemática e Estatística - Universidade de São Paulo   74
    Em uma GPU podemos simular o comportamento de um
     portfólio de modo paralelo. Cada thread precificando os
     instrumentos de simulações diferentes.




16/05/2012        Instituto de Matemática e Estatística - Universidade de São Paulo   75
    Outra abordagem possível seria a paralelização da
     precificação dos instrumentos. Assim, teríamos uma thread
     para cada ativo em diferentes simulações de carteira.




16/05/2012        Instituto de Matemática e Estatística - Universidade de São Paulo   76
[Gregoriou]


16/05/2012   Instituto de Matemática e Estatística - Universidade de São Paulo            77
    GPU Computing

    CUDA

    Aplicações em Finanças
      Precificação de Opções
      Risco de Mercado

    Conclusão



16/05/2012        Instituto de Matemática e Estatística - Universidade de São Paulo   78
    Computação de propósito geral em GPU é uma realidade.

    Novo paradigma de computação. Algoritmos precisam ser
     repensados.

    Problemas em Finanças podem exigir muita capacidade
     computacional

    GPGPU pode viabilizar a solução desses problemas




16/05/2012        Instituto de Matemática e Estatística - Universidade de São Paulo   79
I.      GPUBrasil (http://gpubrasil.com), Maio 2012.

II.     CUDA by example, an introduction to General-Purpose GPU Programming, J. Sanders and E. Kandrot, Addison
        Wesley.

III.    Programming Massively Parallel Processors: A Hands-on Approach, D. Kirk, W. Hwu, Morgan Kaufman.

IV.     NVIDIA CUDA C Best Practices Guide. NVIDIA, Version 3.2, 20/8/2010.

V.      NVIDIA CUDA C Programming Guide. NVIDIA, Version 3.2, 11/9/2010.

VI.     NVIDIA's Next Generation CUDA Compute Architecture: Fermi. NVIDIA Whitepaper, Version 1.1.

VII.    Optimization principles and application performance evaluation of a multithreaded gpu using cuda. Shane
        Ryoo, Christopher I. Rodrigues, Sara S. Baghsorkhi, Sam S. Stone, David B. Kirk, and Wen mei W. Hwu. In
        PPoPP, pages 73-82. ACM, 2008.

VIII.   [Gregoriou] The VaR Implementation Handbook. Greg N. Gregoriou.

IX.     [Hull] Options, Futures, and Other Derivatives. John C. Hull.

X.      [Myungho] Parallel Implementation of a Financial Application on a GPU. Myungho Lee, Jin-hong Jeon, Jongwoo
        Bae, Hyuk-Soo Jang.

XI.     [Solomon] Option Pricing on GPU. Steven Solomon, Ruppa K. Thulasiram and Parimala Thulasiraman.
16/05/2012                     Instituto de Matemática e Estatística - Universidade de São Paulo                     80
Download da Apresentação:

                                             gpubrasil.com




   Computação em Finanças em Hardware Gráfico
   SEMAC 2012 - UNESP




    Thársis T. P. Souza
    t.souza@usp.br


16/05/2012                Instituto de Matemática e Estatística - Universidade de São Paulo   81

Computação em Finanças em Hardware Gráfico

  • 1.
    Computação em Finançasem Hardware Gráfico SEMAC 2012 - UNESP Thársis T. P. Souza t.souza@usp.br Instituto de Matemática e Estatística - Universidade de São Paulo
  • 2.
    GPU Computing  CUDA  Aplicações em Finanças  Precificação de Opções  Risco de Mercado  Conclusão 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 2
  • 3.
    GPU Computing  CUDA  Aplicações em Finanças  Precificação de Opções  Risco de Mercado  Conclusão 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 3
  • 4.
    CPU GPU  Tarefas sequenciais  Tarefas com paralelismo de dados  Cache eficiente  Múltiplas ULAs  Maior quantidade de memória  Maior (capacidade) operações de principal ponto flutuante por segundo  Alto throughput de memória  Controle de fluxo  Dezenas de multiprocessors  Número de cores de 1 ordem de grandeza  Múltiplas threads por multiprocessor  1, 2 threads por core 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 4
  • 5.
    Figura 1: Númerode operações de ponto flutuante por segundo 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 5
  • 6.
    Figura 2: Throughputde memória CPU x GPU 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 6
  • 7.
    48 GPUs 42x Lower Space 2000 CPUs $144K 28x Lower Cost $4 Million $31K / year 38x Lower Power Cost $1.2 Million / year Fonte: NVIDIA Brasil 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 7
  • 8.
    2 Tesla S1070s 16x Less Space 500 CPU Servers $24 K 10x Lower Cost $250 K 2.8 kWatts 13x Lower Power 37.5 kWatts Fonte: NVIDIA Brasil 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 8
  • 9.
    General-purpose computing on Graphics Processing Units  Técnica de uso de GPU para computação de propósito geral  Linguagens/API’s  OpenGL  DirectX  Cg  Brook  Brook+  OpenCL  CUDA 16/05/2012 01/04/2011 Instituto de Matemática e Estatística - Universidade de São Paulo 9
  • 10.
    16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 10
  • 11.
    Compute capability: 2.0  Total dedicated memory:  Registers por mp: 32768  Single Precision Floating 3GB GDDR5  Threads in warp: 32 Point Performance : 1.03 TFlops  Constant mem: 64KB  Max threads per block: 1024  Device copy overlap:  Max thread dimension: Enabled  Numero de (1024, 1024, 64)  Kernel timeout : Disabled multiprocessadores: 14  Max grid dimension: (65535, 65535, 1)  Shared mem por mp: 48KB 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 11
  • 12.
    GPU Computing  CUDA  Aplicações em Finanças  Precificação de Opções  Risco de Mercado  Conclusão 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 12
  • 13.
    Compute Unified Device Architecture  Arquitetura paralela de propósito geral  Tecnologia proprietária NVIDIA 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 13
  • 14.
    Arquitetura de Computação Paralela para propósito geral  Facilita computação heterogênea (CPU + GPU)  Suporte a varias linguagens e APIs  CUDA define:  Modelo de programação  Modelo de memória  Modelo de execução 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 14
  • 15.
    Porções paralelas da aplicação são executadas como kernels  CUDA threads  Lighweight  Fast switching  Milhares (potencialmente) executadas ao mesmo tempo 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 15
  • 16.
    Um kernel executa um grid de blocos de threads  Um bloco é formado por um conjunto de threads  Cada thread pode ser unicamente endereçada 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 16
  • 17.
    Thread  Registradores 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 17
  • 18.
    Thread  Registradores  Thread  Local Memory 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 18
  • 19.
    Thread  Registradores  Thread  Local Memory  Bloco  Shared Memory 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 19
  • 20.
    Thread  Registradores  Thread  Local Memory  Bloco  Shared Memory  Grid  Global Memory 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 20
  • 21.
    Biblioteca e um compilador para criação de rotinas em GPUs NVIDIA  API de mais alto nível em comparação com: Cg, OpenGL, DirectX  Exige conhecimento de arquitetura para codificação  Amplamente utilizada  Possui grande comunidade e boa documentação  Maioria de artigos publicados em programação em GPGPU utiliza CUDA C 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 21
  • 22.
    #include <stdlib.h> #include <stdio.h> int block_size = 128; int grid_size = num_elements / __global__ void kernel(int *array) block_size; { //do work } kernel<<<grid_size,block_size>>>(de vice_array); int main(void) { cudaMemcpy(host_array, device_array, int num_elements = 256; num_bytes, cudaMemcpyDeviceToHost); int num_bytes = num_elements * sizeof(int); for(int i=0; i < num_elements; ++i) { int *host_array = 0; printf("%d ", host_array[i]); } host_array = (int*)malloc(num_bytes); free(host_array); int *device_array = 0; cudaFree(device_array); } cudaMalloc((void**)&device_array, num_bytes); 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 22
  • 23.
    #include <stdlib.h> #include <stdio.h> int block_size = 128; int grid_size = num_elements / __global__ void kernel(int *array) block_size; { //do work } kernel<<<grid_size,block_size>>>(de // C function vice_array); int main(void) { cudaMemcpy(host_array, device_array, int num_elements = 256; num_bytes, cudaMemcpyDeviceToHost); int num_bytes = num_elements * sizeof(int); for(int i=0; i < num_elements; ++i) { int *host_array = 0; printf("%d ", host_array[i]); } host_array = (int*)malloc(num_bytes); free(host_array); int *device_array = 0; cudaFree(device_array); } cudaMalloc((void**)&device_array, num_bytes); 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 23
  • 24.
    #include <stdlib.h> #include <stdio.h> int block_size = 128; int grid_size = num_elements / __global__ void kernel(int *array) block_size; { //do work } kernel<<<grid_size,block_size>>>(de vice_array); int main(void) { cudaMemcpy(host_array, device_array, int num_elements = 256; num_bytes, cudaMemcpyDeviceToHost); int num_bytes = num_elements * sizeof(int); for(int i=0; i < num_elements; ++i) // ponteiro para host memory { int *host_array = 0; printf("%d ", host_array[i]); // aloca espaço em host memory } host_array = (int*)malloc(num_bytes); free(host_array); int *device_array = 0; cudaFree(device_array); } cudaMalloc((void**)&device_array, num_bytes); 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 24
  • 25.
    #include <stdlib.h> #include <stdio.h> int block_size = 128; int grid_size = num_elements / __global__ void kernel(int *array) block_size; { //do work } kernel<<<grid_size,block_size>>>(de vice_array); int main(void) { cudaMemcpy(host_array, device_array, int num_elements = 256; num_bytes, cudaMemcpyDeviceToHost); int num_bytes = num_elements * sizeof(int); for(int i=0; i < num_elements; ++i) { int *host_array = 0; printf("%d ", host_array[i]); } host_array = (int*)malloc(num_bytes); // Ponteiro para device memory free(host_array); int *device_array = 0; cudaFree(device_array); // Aloca espaço em device memory } cudaMalloc((void**)&device_array, num_bytes); 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 25
  • 26.
    #include <stdlib.h> // configuracao de bloco e grid #include <stdio.h> int block_size = 128; int grid_size = num_elements / __global__ void kernel(int *array) block_size; { //do work } kernel<<<grid_size,block_size>>>(de vice_array); int main(void) { cudaMemcpy(host_array, device_array, int num_elements = 256; num_bytes, cudaMemcpyDeviceToHost); int num_bytes = num_elements * sizeof(int); for(int i=0; i < num_elements; ++i) { int *host_array = 0; printf("%d ", host_array[i]); } host_array = (int*)malloc(num_bytes); free(host_array); int *device_array = 0; cudaFree(device_array); } cudaMalloc((void**)&device_array, num_bytes); 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 26
  • 27.
    #include <stdlib.h> #include <stdio.h> int block_size = 128; // extensao __global __ define kernel int grid_size = num_elements / __global__ void kernel(int *array) block_size; { //do work // lancamento do kernel } kernel<<<grid_size,block_size>>>(de vice_array); int main(void) { cudaMemcpy(host_array, device_array, int num_elements = 256; num_bytes, cudaMemcpyDeviceToHost); int num_bytes = num_elements * sizeof(int); for(int i=0; i < num_elements; ++i) { int *host_array = 0; printf("%d ", host_array[i]); } host_array = (int*)malloc(num_bytes); free(host_array); int *device_array = 0; cudaFree(device_array); } cudaMalloc((void**)&device_array, num_bytes); 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 27
  • 28.
    #include <stdlib.h> #include <stdio.h> int block_size = 128; int grid_size = num_elements / __global__ void kernel(int *array) block_size; { //do work } kernel<<<grid_size,block_size>>>(de vice_array); int main(void) // transfere resultado da GPU para CPU { cudaMemcpy(host_array, device_array, int num_elements = 256; num_bytes, cudaMemcpyDeviceToHost); int num_bytes = num_elements * sizeof(int); for(int i=0; i < num_elements; ++i) { int *host_array = 0; printf("%d ", host_array[i]); } host_array = (int*)malloc(num_bytes); free(host_array); int *device_array = 0; cudaFree(device_array); } cudaMalloc((void**)&device_array, num_bytes); 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 28
  • 29.
    #include <stdlib.h> #include <stdio.h> int block_size = 128; int grid_size = num_elements / __global__ void kernel(int *array) block_size; { //do work } kernel<<<grid_size,block_size>>>(de vice_array); int main(void) { cudaMemcpy(host_array, device_array, int num_elements = 256; num_bytes, cudaMemcpyDeviceToHost); int num_bytes = num_elements * // inspecao do resultado sizeof(int); for(int i=0; i < num_elements; ++i) { int *host_array = 0; printf("%d ", host_array[i]); } host_array = (int*)malloc(num_bytes); free(host_array); int *device_array = 0; cudaFree(device_array); } cudaMalloc((void**)&device_array, num_bytes); 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 29
  • 30.
    #include <stdlib.h> #include <stdio.h> int block_size = 128; int grid_size = num_elements / __global__ void kernel(int *array) block_size; { //do work } kernel<<<grid_size,block_size>>>(de vice_array); int main(void) { cudaMemcpy(host_array, device_array, int num_elements = 256; num_bytes, cudaMemcpyDeviceToHost); int num_bytes = num_elements * sizeof(int); for(int i=0; i < num_elements; ++i) { int *host_array = 0; printf("%d ", host_array[i]); } host_array = (int*)malloc(num_bytes); // desaloca memoria free(host_array); int *device_array = 0; cudaFree(device_array); } cudaMalloc((void**)&device_array, num_bytes); 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 30
  • 31.
    16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 31
  • 32.
    Definido por extensão __global__  Configurado por sintaxe <<<grid_size, block_size>>> 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 32
  • 33.
    16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 33
  • 34.
    Todas as threads em um mesmo grid executam o mesmo kernel  Necessidade de haver coordenadas únicas para distinção  Coordenadas criadas pelo CUDA Runtime System:  blockIdx índice do bloco  threadIdx índice da thread  gridDim dimensão do grid  blockDim dimensão dos blocos 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 34
  • 35.
    Kernel é bidimensional  Indexação de bloco  blockIdx.x  blockIdx.y  Blocos são tridimensionais  Indexação de thread  threadIdx.x  threadIdx.y  threadIdx.z 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 35
  • 36.
    16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 36
  • 37.
    16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 37
  • 38.
    GPU Computing  CUDA  Aplicações em Finanças  Precificação de Opções  Risco de Mercado  Conclusão 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 38
  • 39.
    GPU Computing  CUDA  Aplicações em Finanças  Precificação de Opções  Risco de Mercado  Conclusão 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 39
  • 40.
    Opção: Direito negociável de compra de mercadorias, títulos, ações etc., com pagamento em data futura e preços pré determinados  Ativo objeto: ativo ao qual o direito de compra e venda está sendo negociado  Prêmio: Preço da Opção  Spot: Preço à vista do ativo objeto  Strike: Preço de exercício da opção. Valor futuro negociado. 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 40
  • 41.
    16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 41
  • 42.
    Exemplo: Uma Opção de Compra (Call) de Ouro à R$100 em 24/12 é vendida a R$5. Paga-se um prêmio de R$5 para se ter a opção de comprar Ouro à R$100 na data futura 24/12.  Caso em 24/12 o preço à vista (Spot) do ouro seja maior do que R$100 (in-the-money), podemos lucrar ao exercer a opção de compra e vendê-la em seguida (day-trade).  Caso em 24/12 o preço à vista (Spot) do ouro seja menor do que R$100 (out-of-money), não vale a pena o exercício da opção. 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 42
  • 43.
    O Modelo de Black & Scholes fornece um valor de prêmio (V) para uma Opção:  S (Spot); X (Strike); T (tempo para vencimento); r (taxa de juros); v (Volatilidade); CND (Distribuição Normal Padrão Acumulada) 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 43
  • 44.
    Distribuição Normal Padrão Acumulada: 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 44
  • 45.
    Distribuição Normal Padrão Acumulada:  Aproximação como um polinômio de quinta ordem [Hull]: 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 45
  • 46.
    Passos para Precificação:  Alocar vetores no Host: hOptSpot(N), hOptStrike(N), ...  Alocar vetores no Device: dOptSpot(N), dOptStrike(N), ... 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 46
  • 47.
    Passos para Precificação:  Alocar vetores no Host: hOptSpot(N), hOptStrike(N), ...  Alocar vetores no Device: dOptSpot(N), dOptStrike(N), ...  Inicializar vetores com variáveis dos contratos e mercado  Transferir vetores da memória host para device memory 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 47
  • 48.
    Passos para Precificação:  Alocar vetores no Host: hOptSpot(N), hOptStrike(N), ...  Alocar vetores no Device: dOptSpot(N), dOptStrike(N), ...  Inicializar vetores com variáveis dos contratos e mercado  Transferir vetores da memória host para device memory  Precificar opção em GPU via Black&Scholes 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 48
  • 49.
    Passos para Precificação:  Alocar vetores no Host: hOptSpot(N), hOptStrike(N), ...  Alocar vetores no Device: dOptSpot(N), dOptStrike(N), ...  Inicializar vetores com variáveis dos contratos e mercado  Transferir vetores da memória host para device memory  Precificar opção em GPU via Black&Scholes  Transferir resultado da GPU para Host  Desalocar memória 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 49
  • 50.
    16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 50
  • 51.
    16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 51
  • 52.
    16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 52
  • 53.
    16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 53
  • 54.
    16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 54
  • 55.
    16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 55
  • 56.
    16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 56
  • 57.
    Desempenho CPU vs.GPU Precificação de Opções via Black-Scholes Fonte: Oneye, 2008 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 57
  • 58.
    Desempenho CPU vs.GPU Precificação de Opções via Black-Scholes Fonte: Oneye, 2008 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 58
  • 59.
    Muitas vezes, não é possível encontrar uma expressão analítica para precificar um derivativo.  Simulação de Monte Carlo é uma alternativa: 1. Definição do comportamento estocástico para os preços do instrumento financeiro 2. Geração de números aleatórios para simulação 3. Cálculo dos valores do instrumento 4. Repetir N vezes os passos 2 e 3, com N tendendo ao infinito 5. Determinação da precificação a partir da distribuição dos valores obtidos anteriormente 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 59
  • 60.
    1. Definição do Processo Estocástico:  Assume-se, geralmente, que o preço do instrumento financeiro segue um movimento Browniano Geométrico sendo, µ = taxa de rentabilidade esperada para o instrumento σ = desvio padrão da taxa de rentabilidade do instrumento dW = representa parcela aleatória do movimento 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 60
  • 61.
    1. Definição do Processo Estocástico:  Assim, chega-se a uma expressão que fornece a variação do preço do instrumento em um δt: onde, 𝜀 𝑡 representa uma variável aleatória que segue uma distribuição normal entre 0 e 1. 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 61
  • 62.
    2. Para geração dos números aleatórios desejados, podemos utilizar o método de Box-Muller onde, 𝑥1 , 𝑥2 ∈ 𝑁 e 𝑧1 , 𝑧2 ∈ 𝑁(0,1) 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 62
  • 63.
    3. O Prêmio da Opção (𝑐 𝑡 ) pode ser calculado a partir de um valor esperado de seu retorno (Spot – Preço de Exercício) 4. Ao simular aleatoriamente o preço do instrumento 𝑆 𝑇 , podemos precificar a opção como 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 63
  • 64.
    Toda a geração de números aleatórios pode ser naturalmente realizada de forma paralela na GPU  As simulações dos preços dos instrumentos são independentes, portanto podem ser realizadas ao mesmo tempo  A capacidade de gerar maior número de simulações resulta em maior precisão no resultado 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 64
  • 65.
    Desempenho CPU vs.GPU Método Box-Muller [Myungho] 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 65
  • 66.
    Desempenho CPU vs.GPU Método Box-Muller [Myungho] 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 66
  • 67.
    Desempenho CPU vs.GPU Simulação de Monte Carlo [Myungho] 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 67
  • 68.
    Desempenho CPU vs.GPU Simulação de Monte Carlo [Myungho] 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 68
  • 69.
    GPU Computing  CUDA  Aplicações em Finanças  Precificação de Opções  Risco de Mercado  Conclusão 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 69
  • 70.
    Possibilidade de ocorrência de perdas resultantes da flutuação nos valores de mercado de posições ativas e passivas detidas pelas instituições financeiras. (JP Morgan)  O risco de mercado inclui os riscos das operações sujeitas a  variação cambial,  taxa de juros,  preços das ações e  preços de mercadorias (commodities) 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 70
  • 71.
    Value-at-Risk representa a perda máxima potencial de uma carteira, em um horizonte de tempo definido, com determinado grau de confiança  Exemplo: Banco anuncia para carteira de sua tesouraria, um VaR de US$ 15 milhões, para o horizonte de tempo de 1 dia e grau de confiança 95%. 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 71
  • 72.
    Ex.: Supondo uma exposição ao mercado de R$1.000.000, teríamos um risco de perda máxima de R$40.000, em um dia, com uma confiança de 95%. 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 72
  • 73.
    VaR Stress: teste que visa a validar a qualidade do VaR estimado.  Simulação de caminhos alternativos do comportamento do preço dos instrumentos de uma carteira para avaliar se o resultante valor do portfolio excedeu a perda máxima prevista pelo VaR. 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 73
  • 74.
    Como já visto, o preço de um instrumento pode ser simulado como:  Em uma arquitetura serial, cada carteira deve ser precificada sequencialmente e os instrumentos são simulados iterativamente. 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 74
  • 75.
    Em uma GPU podemos simular o comportamento de um portfólio de modo paralelo. Cada thread precificando os instrumentos de simulações diferentes. 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 75
  • 76.
    Outra abordagem possível seria a paralelização da precificação dos instrumentos. Assim, teríamos uma thread para cada ativo em diferentes simulações de carteira. 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 76
  • 77.
    [Gregoriou] 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 77
  • 78.
    GPU Computing  CUDA  Aplicações em Finanças  Precificação de Opções  Risco de Mercado  Conclusão 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 78
  • 79.
    Computação de propósito geral em GPU é uma realidade.  Novo paradigma de computação. Algoritmos precisam ser repensados.  Problemas em Finanças podem exigir muita capacidade computacional  GPGPU pode viabilizar a solução desses problemas 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 79
  • 80.
    I. GPUBrasil (http://gpubrasil.com), Maio 2012. II. CUDA by example, an introduction to General-Purpose GPU Programming, J. Sanders and E. Kandrot, Addison Wesley. III. Programming Massively Parallel Processors: A Hands-on Approach, D. Kirk, W. Hwu, Morgan Kaufman. IV. NVIDIA CUDA C Best Practices Guide. NVIDIA, Version 3.2, 20/8/2010. V. NVIDIA CUDA C Programming Guide. NVIDIA, Version 3.2, 11/9/2010. VI. NVIDIA's Next Generation CUDA Compute Architecture: Fermi. NVIDIA Whitepaper, Version 1.1. VII. Optimization principles and application performance evaluation of a multithreaded gpu using cuda. Shane Ryoo, Christopher I. Rodrigues, Sara S. Baghsorkhi, Sam S. Stone, David B. Kirk, and Wen mei W. Hwu. In PPoPP, pages 73-82. ACM, 2008. VIII. [Gregoriou] The VaR Implementation Handbook. Greg N. Gregoriou. IX. [Hull] Options, Futures, and Other Derivatives. John C. Hull. X. [Myungho] Parallel Implementation of a Financial Application on a GPU. Myungho Lee, Jin-hong Jeon, Jongwoo Bae, Hyuk-Soo Jang. XI. [Solomon] Option Pricing on GPU. Steven Solomon, Ruppa K. Thulasiram and Parimala Thulasiraman. 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 80
  • 81.
    Download da Apresentação: gpubrasil.com Computação em Finanças em Hardware Gráfico SEMAC 2012 - UNESP Thársis T. P. Souza t.souza@usp.br 16/05/2012 Instituto de Matemática e Estatística - Universidade de São Paulo 81