σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyRoteiros
Ctrl K
AO
+1,2 mil alunos
EntrarParticipar ↗
Roteiros
AO
+1,2 mil alunos
Entrar
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Roteiro de Python›Módulo 1 · Fundamentos de Python para quants›Tópico 1.26·~45 minIniciante

Classes e objetos

Posição no roteiroMódulo 1 de 11 · Tópico 26 de 33
1.26 Classes e objetos
—Nota do lab— / 100XP total—Sequência—

Dados e comportamento juntos

Até agora uma posição podia ser uma tupla ou um dicionário, com funções separadas trabalhando sobre ela. Uma classe reúne os dados e as funções que lhes pertencem em um novo tipo. class Position: define a planta; chamá-la, Position("AAPL", 100, 180.0), constrói um objeto (também chamado instância) a partir dela. Cada objeto guarda seus próprios dados, e as funções definidas na classe, chamadas métodos, trabalham sobre esse objeto.

class Position:
    def __init__(self, symbol, quantity=0):
        self.symbol = symbol          # attributes belong to this object
        self.quantity = quantity

    def describe(self):
        return f"{self.quantity} x {self.symbol}"

apple = Position("AAPL", 100)
tesla = Position("TSLA")

print(apple.describe())   # 100 x AAPL
print(tesla.describe())   # 0 x TSLA
print(apple.quantity, tesla.quantity)  # 100 0

__init__ e self

__init__ é o construtor: o Python o executa automaticamente ao criar um objeto, e ele guarda os valores iniciais. Todo método recebe o próprio objeto como primeiro parâmetro, chamado por convenção self; você não o passa, o Python passa (apple.describe() chama Position.describe(apple)). Tudo o que é guardado com self.nome = valor é um atributo daquele objeto e permanece ali entre chamadas de método. __init__ prepara as coisas e não devolve nada.

class Account:
    def __init__(self, cash):
        self.cash = cash

    def deposit(self, amount):
        self.cash += amount          # changes this object's attribute
        return self.cash

first = Account(1000)
second = Account(50)

first.deposit(500)
print(first.cash, second.cash)       # 1500 50  (separate objects, separate data)

same = first                          # a second name for the same object
same.deposit(1)
print(first.cash)                     # 1501

Métodos que mudam o estado ou respondem perguntas

Alguns métodos respondem a uma pergunta sobre o objeto sem alterá-lo (market_value(price)); devem só devolver um resultado e deixar os atributos em paz. Outros alteram o objeto (apply_fill), atualizam atributos e muitas vezes devolvem algo útil, como o lucro realizado. Um método pode chamar outro com self.outro_metodo(...), o que mantém as regras em um só lugar: se unrealized_pnl precisa do valor de mercado, ele pergunta a self.market_value(price) em vez de repetir a fórmula.

class Position:
    def __init__(self, symbol, quantity=0, avg_price=0.0):
        self.symbol = symbol
        self.quantity = quantity
        self.avg_price = avg_price

    def market_value(self, price):
        return self.quantity * price

    def unrealized_pnl(self, price):
        return self.market_value(price) - self.quantity * self.avg_price

pos = Position("AAPL", 100, 180.0)
print(pos.market_value(185.0))       # 18500.0
print(pos.unrealized_pnl(185.0))     # 500.0

Armadilhas e quando usar uma classe

Esquecer self. é o deslize clássico: quantity = 5 dentro de um método cria uma variável local descartável, não um atributo. Use CapWords para nomes de classes (Position) e minúsculas com sublinhados para atributos e métodos; um sublinhado inicial (_cache) marca algo como interno. Nunca use um padrão mutável como def __init__(self, fills=[]): todos os objetos compartilhariam aquela única lista; use fills=None e crie [] dentro. Crie uma classe quando os dados e as regras sobre eles andam juntos; uma função simples ou um dicionário costuma ser mais simples.

class Wrong:
    def __init__(self, quantity):
        quantity = quantity          # forgot self.: nothing is stored

class Shared:
    def __init__(self, fills=[]):    # one list shared by every object
        self.fills = fills

class Right:
    def __init__(self, fills=None):
        self.fills = [] if fills is None else list(fills)

a, b = Shared(), Shared()
a.fills.append(100)
print(b.fills)                        # [100]  (surprise!)

c, d = Right(), Right()
c.fills.append(100)
print(d.fills)                        # []

print(hasattr(Wrong(5), "quantity"))  # False
Verifique se cada objeto mantém seu próprio estadoUm bom hábito ao escrever uma classe: crie dois objetos, altere um e imprima o outro. Se o segundo também mudou, algo está compartilhado sem dever. Os testes do lab fazem exatamente isso, e também verificam que um método que deveria só responder uma pergunta deixa os atributos inalterados.
  • class Nome: define um tipo; Nome(args) constrói um objeto e executa __init__.
  • self.attr = valor guarda dados no objeto; cada método recebe self primeiro.
  • Métodos de consulta devolvem respostas; os de atualização alteram atributos; evite padrões mutáveis.

A seguir: métodos especiais como __repr__ e __eq__, que fazem seus objetos serem impressos bem e comparados como você espera.

Lab: o que é avaliado

  • Construir uma posição com __init__25 pts
  • Avaliar a posição com market_value25 pts
  • Medir o lucro não realizado com unrealized_pnl25 pts
  • Atualizar a posição após uma operação com apply_fill25 pts
Explorador · lab-26-1
▾ lab-26-1
…
bash · no navegador
learner@quantcraft:~/lab-26-1$
Python ainda não carregadoPythonLn 1, Col 1Spaces: 4UTF-8

Redefinir este tópico?

Tudo em lab-26-1 volta aos arquivos iniciais e o terminal é limpo. Sua solução atual será perdida — isso não pode ser desfeito.

Será redefinido
  • main.py → código inicial
  • Histórico do terminal e saída dos testes
  • Alterações não enviadas
Será mantido
  • Melhor nota do lab
  • Seu XP e sua sequência
  • Progresso da aula e anotações

Entre para executar o seu código.

Todas as aulas são gratuitas para ler. Crie uma conta ou entre para executar código, rodar os testes e enviar este lab.

  • IDE no navegador com terminal bash — nada para instalar
  • Correção instantânea, XP e o seu lugar no roteiro
Criar uma contaEntrar
OU
Continuar com o GitHub