Carlos Eduardo Gatti Ferreira

Market Price Module

Módulo para buscar preços de mercado atuais via APIs externas.

📋 Objetivo

Fornecer preços de mercado atualizados para cálculo correto de Gain/Loss no Wealth Tracker, sem alterar schemas existentes.

🏗️ Estrutura

src/market-price/
├── market-price.module.ts      # Módulo NestJS
├── market-price.service.ts     # Lógica de busca e cache
├── market-price.resolver.ts    # GraphQL resolver
├── dto/
│   └── market-price.dto.ts     # DTOs e tipos
└── README.md                    # Esta documentação

🚀 Instalação

1. Instalar dependências

npm install @nestjs/axios axios

2. Configurar variável de ambiente

Adicione ao .env:

MARKET_DATA_API_KEY=sua_api_key_aqui

3. Registrar módulo no AppModule

// app.module.ts
import { MarketPriceModule } from './market-price/market-price.module';

@Module({
  imports: [
    // ... outros módulos
    MarketPriceModule,
  ],
})
export class AppModule {}

📡 Uso

GraphQL Query

query {
  marketPrices(tickers: ["AAPL", "SP500", "BTC"]) {
    ticker
    price
    currency
    source
    fetchedAt
  }
}

Query para um único ticker

query {
  marketPrice(ticker: "AAPL") {
    ticker
    price
    currency
    source
    fetchedAt
  }
}

Uso no Service (outros módulos)

import { MarketPriceService } from '../market-price/market-price.service';

@Injectable()
export class PortfolioService {
  constructor(private marketPriceService: MarketPriceService) {}

  async calculateMarketValue(portfolioId: number) {
    // Buscar tickers do portfolio
    const tickers = ['AAPL', 'MSFT'];
    
    // Buscar preços atuais
    const prices = await this.marketPriceService.getPrices(tickers);
    
    // Usar preços para cálculos
    // ...
  }
}

🔧 Configuração

Cache TTL

O cache padrão é de 10 minutos. Para alterar, modifique DEFAULT_TTL_MS em market-price.service.ts:

private readonly DEFAULT_TTL_MS = 15 * 60 * 1000; // 15 minutos

API Provider

Atualmente implementado para Yahoo Finance via RapidAPI. Para adicionar outros providers:

  1. Adicione método no service (ex: fetchFromPolygon())
  2. Implemente fallback logic em getPriceForTicker()
  3. Atualize MarketPriceSource enum

⚠️ Importante

🧪 Testes

describe('MarketPriceService', () => {
  it('should fetch prices from API', async () => {
    const prices = await service.getPrices(['AAPL']);
    expect(prices).toHaveLength(1);
    expect(prices[0].ticker).toBe('AAPL');
    expect(prices[0].price).toBeGreaterThan(0);
  });

  it('should use cache on second call', async () => {
    await service.getPrices(['AAPL']);
    const cached = await service.getPrices(['AAPL']);
    // Verificar que não fez nova chamada HTTP
  });
});

🔄 Próximos Passos

  1. ✅ Implementar Yahoo Finance (MVP)
  2. ⏳ Adicionar Polygon.io como fallback
  3. ⏳ Adicionar suporte a crypto (CoinGecko)
  4. ⏳ Implementar cache distribuído (Redis)
  5. ⏳ Adicionar métricas de monitoramento

📝 Notas de Implementação