σμ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 11 · Sistemas de produção e modelos de ponta›Tópico 11.5·~1 hEspecialista

Execução VWAP

Posição no roteiroMódulo 11 de 11 · Tópico 5 de 13
11.5 Execução VWAP
—Nota do lab— / 100XP total—Sequência—

Negociar quando o mercado negocia

O preço médio ponderado por volume é o preço médio de tudo que foi negociado, cada negócio ponderado pelo seu tamanho: sum(price * volume) / sum(volume). É a referência mais comum no trading institucional porque é o que um participante médio pagou naquele dia. Um algoritmo VWAP tenta igualá-lo ou superá-lo negociando *em proporção ao volume do mercado*: muito quando o mercado está ativo (a abertura, o fechamento), pouco quando está calmo (hora do almoço). Onde o TWAP segue o relógio, o VWAP segue a multidão, de modo que cada uma de suas ordens é uma fração parecida do que todos os outros fazem e move menos o preço.

# The benchmark: each price counts as much as the volume that traded at it
def vwap(prices, volumes):
    return sum(p * v for p, v in zip(prices, volumes)) / sum(volumes)

prices = [100.0, 101.0, 102.0]
volumes = [100, 300, 600]
print(round(vwap(prices, volumes), 4))               # 101.5     most volume traded near 102, so the VWAP leans that way
print(sum(prices) / len(prices))                     # 101.0     the plain average ignores how much traded at each price

Um perfil de volume e um cronograma que o segue

Não se pode saber o volume de hoje com antecedência, então um algoritmo VWAP usa um perfil de volume estimado do histórico: a fatia média do volume do dia negociada em cada intervalo nas últimas 20 sessões, digamos. O volume intradiário costuma ter forma de U, alto na abertura e no fechamento. O cronograma dá então a cada intervalo total * fatia ações. Raramente são inteiros, e arredondar cada um pode perder ou acrescentar ações. O método do maior resto resolve: dê a cada intervalo a parte inteira e distribua as ações restantes, uma a cada, aos intervalos com as maiores partes fracionárias, de modo que o cronograma sempre some a ordem.

# From volumes to a profile, then to whole shares by the largest remainder method
import math

def volume_profile(volumes):
    total = sum(volumes)
    return [v / total for v in volumes]

def vwap_schedule(total, profile):
    exact = [total * share for share in profile]
    shares = [math.floor(value + 1e-9) for value in exact]
    leftover = total - sum(shares)
    for index in sorted(range(len(profile)), key=lambda i: (-(exact[i] - shares[i]), i))[:leftover]:
        shares[index] += 1
    return shares

profile = volume_profile([300, 100, 100, 200, 500, 800])       # a U-shape: busy at the open and the close
print([round(p, 3) for p in profile])                # [0.15, 0.05, 0.05, 0.1, 0.25, 0.4]
print(vwap_schedule(1003, profile))                  # [151, 50, 50, 100, 251, 401]   adds up to 1003
print(sum(vwap_schedule(1003, profile)))             # 1003

Limites de participação e acompanhamento da referência

Um cronograma é um plano; o mercado pode estar mais calmo do que o perfil previu. Um teto de participação limita sua negociação em cada intervalo a uma fração do volume real do mercado nele, digamos 10 %, para que você nunca seja a maior parte do fluxo. As ações que você não conseguiu negociar são transferidas para os intervalos seguintes, o que pode deixar algumas sem executar no fim; então você decide se assume mais risco, estende a janela ou para. Depois do dia, compare seu preço médio com o VWAP do mercado: a diferença, em pontos-base, é o erro de acompanhamento do algoritmo. Bater o VWAP negociando tarde num mercado em alta não é habilidade; julgue um algoritmo pelo slippage ao longo de muitos dias.

# A participation cap: never more than a fraction of the market's volume, carrying the rest forward
import math

def cap_participation(schedule, market_volumes, rate):
    trades, carry = [], 0
    for scheduled, volume in zip(schedule, market_volumes):
        wanted = scheduled + carry
        done = min(wanted, math.floor(rate * volume + 1e-9))
        trades.append(done)
        carry = wanted - done
    return trades, carry

print(cap_participation([100, 100, 100], [500, 1000, 1000], 0.1))      # ([50, 100, 100], 50)
print(cap_participation([100, 0, 0, 0], [500, 1000, 400, 800], 0.1))   # ([50, 50, 0, 0], 0)   the carry is traded when the market allows it
# Following the clock (TWAP) and following the volume (VWAP) give different average prices on the same day
prices = [100.0, 100.2, 100.1, 100.4, 100.3, 100.5]
volumes = [300, 100, 100, 200, 500, 800]               # busy at the open and the close

market_vwap = sum(p * v for p, v in zip(prices, volumes)) / sum(volumes)
twap_average = sum(prices) / len(prices)                # equal pieces at every time
print(round(market_vwap, 4), round(twap_average, 4))    # 100.33 100.25
print(round((twap_average - market_vwap) / market_vwap * 10000, 1))      # -8.0   a TWAP buy beat the VWAP here, by trading light when volume was heavy
O VWAP é uma referência, não um objetivoIgualar o VWAP diz que você negociou como o participante médio, o que pode ser um mau resultado se sua própria ordem empurrou o preço (seus negócios fazem parte do VWAP com que é comparado). Verifique o algoritmo também contra o preço de chegada, teste o perfil em dias em que não foi estimado e espere que perfis falhem em dias de notícias, meios pregões e rebalanceamentos de índice. Guarde um registro legível de cada ordem filha para análise posterior.
  • O VWAP é sum(price * volume) / sum(volume), a referência comum; um algoritmo VWAP negocia em proporção ao volume do mercado.
  • Estime um perfil de volume do histórico e divida a ordem por ele com o método do maior resto para que as ações inteiras somem exatamente.
  • Limite sua participação em cada intervalo e transfira o resto; julgue o algoritmo pelo erro de acompanhamento e pelo slippage ao longo de muitos dias.

A seguir: market making, cotar os dois lados e gerir o estoque resultante.

Lab: o que é avaliado

  • Calcular a referência com vwap25 pts
  • Dar forma ao dia com volume_profile25 pts
  • Repartir a ordem com vwap_schedule25 pts
  • Respeitar o mercado com cap_participation25 pts
Explorador · lab-134-1
▾ lab-134-1
…
bash · no navegador
learner@quantcraft:~/lab-134-1$
Python ainda não carregadoPythonLn 1, Col 1Spaces: 4UTF-8

Redefinir este tópico?

Tudo em lab-134-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