σμ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 AcademyRutas
Ctrl K
AO
+1,2 k estudiantes
Iniciar sesiónUnirse ↗
Rutas
AO
+1,2 k estudiantes
Iniciar sesión
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Ruta de Python›Módulo 10 · Ingeniería Python de alto rendimiento›Tema 10.2·~45 minAvanzado

Anotaciones de tipo y verificación estática

Posición en la rutaMódulo 10 de 11 · Tema 2 de 13
10.2 Anotaciones de tipo y verificación estática
—Puntuación del lab— / 100XP total—Racha—

Las anotaciones son documentación que una herramienta puede comprobar

Python es de tipado dinámico: una variable puede contener cualquier cosa, y un tipo equivocado solo aparece cuando se ejecuta la línea, quizá en plena sesión. Las anotaciones de tipo permiten escribir lo que una función espera y devuelve: def mid_price(bid: float, ask: float) -> float. Python las ignora al ejecutar. Su valor es que un editor y un verificador estático como mypy o pyright las leen y avisan de una llamada errónea antes de ejecutar, y que documentan la función mejor que un comentario que se queda viejo.

# Hints describe the function; Python does not enforce them when it runs
def mid_price(bid: float, ask: float) -> float:
    return (bid + ask) / 2

print(mid_price(100.0, 100.5))                      # 100.25
print(mid_price.__annotations__)                    # {'bid': <class 'float'>, 'ask': <class 'float'>, 'return': <class 'float'>}
print(mid_price(10, 12))                            # 11.0   an int is accepted where float is hinted
try:
    mid_price("a", "b")                             # a checker flags this line before the code runs
except TypeError as error:
    print("only fails when it runs:", error)       # only fails when it runs: unsupported operand type(s) for /

Contenedores, None y uniones

Los contenedores incorporados llevan el tipo de sus elementos entre corchetes: list[float], dict[str, float], tuple[str, float] (un tipo por posición). Un valor que puede faltar es float | None, lo que obliga al llamador a manejar None; el verificador se queja si usa el resultado como número sin comprobarlo. Dentro de la función, un if x is None: return acota el tipo y el resto sabe que es un float. Para argumentos que solo se leen, prefiere un tipo general como Sequence[float] (listas, tuplas) en lugar de list[float], para que encajen más llamadores; devuelve un tipo concreto, como list[float].

# Containers, an optional result, and narrowing with an is None check
def best_quote(quotes: list[tuple[str, float]]) -> tuple[str, float] | None:
    if not quotes:
        return None
    return min(quotes, key=lambda quote: quote[1])

def describe(quotes: list[tuple[str, float]]) -> str:
    best = best_quote(quotes)
    if best is None:                                 # after this check the checker knows best is a tuple
        return "no quotes"
    venue, price = best
    return f"{venue} at {price:.2f}"

print(describe([("XNAS", 100.02), ("ARCX", 100.01)]))     # ARCX at 100.01
print(describe([]))                                       # no quotes

Formas de datos y el verificador en acción

Un diccionario de claves fijas, como una orden, está mejor descrito que dejado como dict. Un TypedDict o una dataclass nombra cada campo y su tipo, de modo que una errata como order["quantiy"] es un error en el editor y no un KeyError a las 15:59. El verificador se ejecuta desde la línea de comandos (mypy main.py); imprime cada lugar donde el código contradice sus anotaciones y sale con código distinto de cero, así encaja en las comprobaciones automáticas que verás más adelante. Las anotaciones se pueden añadir poco a poco: Any desactiva la comprobación de un valor y el código sin tipos simplemente se omite. Las anotaciones también son datos que las herramientas leen en ejecución con typing.get_type_hints, justo como las comprueba este laboratorio.

# A TypedDict names the fields of an order; the checker would flag order["quantiy"]
from typing import TypedDict

class Order(TypedDict):
    symbol: str
    quantity: int
    price: float

def notional(order: Order) -> float:
    return order["quantity"] * order["price"]

order: Order = {"symbol": "AAPL", "quantity": 100, "price": 184.5}
print(notional(order))                              # 18450.0
print(Order.__annotations__)                        # {'symbol': <class 'str'>, 'quantity': <class 'int'>, 'price': <class 'float'>}
# The hints can be read at run time, which is how tools (and this lab) inspect a function
import typing

def apply_fee(prices: typing.Sequence[float], fee_rate: float = 0.001) -> list[float]:
    return [price * (1 + fee_rate) for price in prices]

hints = typing.get_type_hints(apply_fee)
print(hints["fee_rate"], hints["return"])           # <class 'float'> list[float]
print(typing.get_origin(hints["prices"]).__name__)  # Sequence
print(apply_fee((100.0, 200.0)))                    # a tuple is accepted: [100.1, 200.2]
Las anotaciones no son validaciónUna anotación no detiene un valor erróneo en ejecución: los datos que llegan de un archivo, una API o un websocket siguen siendo lo que son. Comprueba los datos externos de forma explícita (o con una biblioteca que construya objetos a partir de las anotaciones) y usa las anotaciones para cazar errores en tus propias llamadas entre funciones. Un verificador en verde significa que las anotaciones concuerdan entre sí, no que los números sean correctos; de eso siguen encargándose las pruebas.
  • Las anotaciones (bid: float, -> float) documentan una función y se ignoran al ejecutar; un verificador como mypy las lee.
  • Los contenedores llevan tipos de elementos (list[tuple[str, float]]); un valor ausente es float | None; los argumentos de solo lectura pueden ser un Sequence[float] general.
  • Usa TypedDict o dataclass para registros, ejecuta el verificador en tus comprobaciones automáticas, y sigue validando los datos externos y probando los números.

A continuación: pruebas con pytest, fixtures, casos parametrizados y las comprobaciones que mantienen honesta una estrategia.

Lab: qué se califica

  • Anotar números con mid_price25 pts
  • Tipar un contenedor con best_quote25 pts
  • Admitir un valor ausente en safe_ratio25 pts
  • Aceptar cualquier secuencia en apply_fee25 pts
Explorador · lab-118-1
▾ lab-118-1
…
bash · en el navegador
learner@quantcraft:~/lab-118-1$
Python aún no cargadoPythonLn 1, Col 1Spaces: 4UTF-8

¿Restablecer este tema?

Todo lo que hay en lab-118-1 vuelve a los archivos iniciales y se limpia el terminal. Tu solución actual se perderá: no se puede deshacer.

Se restablecerá
  • main.py → código inicial
  • Historial del terminal y salida de pruebas
  • Cambios sin enviar
Se conservará
  • Mejor puntuación del lab
  • Tu XP y tu racha
  • Progreso de la lección y notas

Inicia sesión para ejecutar tu código.

Todas las clases se pueden leer gratis. Crea una cuenta o inicia sesión para ejecutar código, lanzar las pruebas y enviar este lab.

  • IDE en el navegador con terminal bash — sin instalar nada
  • Corrección instantánea, XP y tu lugar en la ruta
Crear una cuentaIniciar sesión
O
Continuar con GitHub