OOP Aplicado a Mercado Financeiro
Aula 2 de 7
Classes — Modelagem de Ordem
public enum OrdemTipo
{
LIMITE,
MERCADO
}
public enum OrdemLado
{
COMPRA,
VENDA
}
public enum OrdemStatus
{
PENDENTE,
PARCIAL,
PREENCHIDA,
CANCELADA
}
public class Ordem
{
public Guid Id { get; private set; }
public string Simbolo { get; private set; }
public OrdemLado Lado { get; private set; }
public int Quantidade { get; private set; }
public int QuantidadeRestante { get; private set; }
public decimal? Preco { get; private set; }
public OrdemTipo Tipo { get; private set; }
public OrdemStatus Status { get; private set; }
public DateTime CriadaEm { get; private set; }
public Ordem(string simbolo, OrdemLado lado, int quantidade,
OrdemTipo tipo = OrdemTipo.LIMITE, decimal? preco = null)
{
Id = Guid.NewGuid();
Simbolo = simbolo;
Lado = lado;
Quantidade = quantidade;
QuantidadeRestante = quantidade;
Tipo = tipo;
Preco = tipo == OrdemTipo.LIMITE
? preco ?? throw new ArgumentException("Preço obrigatório para ordem limite")
: null;
Status = OrdemStatus.PENDENTE;
CriadaEm = DateTime.UtcNow;
}
public bool PreencherParcial(int quantidade)
{
if (quantidade <= 0 || quantidade > QuantidadeRestante)
return false;
QuantidadeRestante -= quantidade;
Status = QuantidadeRestante == 0
? OrdemStatus.PREENCHIDA
: OrdemStatus.PARCIAL;
return true;
}
public bool Cancelar()
{
if (Status == OrdemStatus.PREENCHIDA)
return false;
Status = OrdemStatus.CANCELADA;
return true;
}
public override string ToString()
=> $"{Id}: {Lado} {Quantidade} {Simbolo} @ {(Preco?.ToString("F2") ?? "MERCADO")} [{Status}]";
}
Records — Imutabilidade
// Record — tipo por valor com imutabilidade
public record Trade(
Guid Id,
Guid OrdemCompraId,
Guid OrdemVendaId,
string Simbolo,
int Quantidade,
decimal Preco,
DateTime ExecutadaEm
);
// Comportamento: value equality
var t1 = new Trade(Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid(),
"AAPL", 100, 150.50m, DateTime.UtcNow);
var t2 = t1 with { Id = Guid.NewGuid() }; // cópia imutável
Interfaces e Injeção de Dependência
public interface IOrderBook
{
void AdicionarOrdem(Ordem ordem);
bool CancelarOrdem(Guid ordemId);
IEnumerable<Trade> ExecutarMatches();
OrdemBookSnapshot ObterSnapshot();
}
public interface IMarketDataProvider
{
event Action<Trade> OnTrade;
decimal ObterUltimoPreco(string simbolo);
}
Record Struct — Performance
// Record struct (C# 10+) — baixo overhead
public readonly record struct PrecoNivel(decimal Preco, int QuantidadeTotal);
public class OrderBook
{
private readonly SortedDictionary<decimal, int> _compras = new(); // bid
private readonly SortedDictionary<decimal, int> _vendas = new(); // ask
public IEnumerable<PrecoNivel> Bids
=> _compras.Select(kv => new PrecoNivel(kv.Key, kv.Value));
public IEnumerable<PrecoNivel> Asks
=> _vendas.Select(kv => new PrecoNivel(kv.Key, kv.Value));
}
C# moderno tem records para imutabilidade e value equality. No mercado financeiro, imutabilidade é crucial para integridade de dados de negociação.