σμ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 1 · Fundamentos de Python para quants›Tema 1.31·~40 minPrincipiante

Vectores y productos escalares

Posición en la rutaMódulo 1 de 11 · Tema 31 de 33
1.31 Vectores y productos escalares
—Puntuación del lab— / 100XP total—Racha—

Un vector es una lista de números con reglas

Un vector es una lista ordenada de números de longitud fija, como los pesos de una cartera [0.5, 0.3, 0.2] o los rendimientos de un día de tres activos [0.02, -0.01, 0.03]. En Python sirve una lista de floats. Los vectores se pueden sumar, escalar y combinar posición a posición, por eso gran parte de las finanzas cuantitativas se escribe en su lenguaje. Dos vectores solo se combinan si tienen la misma longitud; mezclar longitudes es un error del que quieres enterarte con claridad.

weights = [0.5, 0.3, 0.2]
returns = [0.02, -0.01, 0.03]

# Position by position: zip pairs the elements
products = [w * r for w, r in zip(weights, returns)]
print([round(p, 4) for p in products])   # [0.01, -0.003, 0.006]

# Scaling and adding vectors
print([2 * w for w in weights])          # [1.0, 0.6, 0.4]
print([a + b for a, b in zip(weights, returns)])  # [0.52, 0.29, 0.23]

El producto escalar

El producto escalar multiplica dos vectores posición a posición y suma los resultados: a1*b1 + a2*b2 + ... + an*bn. Devuelve un único número. Es el rendimiento de la cartera cuando a contiene los pesos y b los rendimientos: 0.5*0.02 + 0.3*(-0.01) + 0.2*0.03 = 0.013. También es el valor de una lista de posiciones (cantidades por precios) y la pieza básica de una regresión. En Python: sum(x * y for x, y in zip(a, b)), tras comprobar que len(a) == len(b), porque zip se detiene en silencio en la lista más corta.

def dot(a, b):
    if len(a) != len(b):
        raise ValueError("vectors must have the same length")
    return sum(x * y for x, y in zip(a, b))

print(dot([1, 2, 3], [4, 5, 6]))                       # 32
print(round(dot([0.5, 0.3, 0.2], [0.02, -0.01, 0.03]), 6))  # 0.013  (portfolio return)

try:
    dot([1, 2], [1, 2, 3])
except ValueError as error:
    print(error)                                       # vectors must have the same length

Longitud, dirección y similitud

Un vector con producto escalar consigo mismo da su longitud al cuadrado, así que la norma (longitud) es math.sqrt(dot(a, a)): para [3, 4] es 5.0. Dividir un vector por su norma da un vector unitario de longitud 1 que conserva solo la dirección (pero un vector nulo no tiene dirección, recházalo con ValueError). La similitud coseno dot(a, b) / (norm(a) * norm(b)) mide cuán alineados están dos vectores, de -1 (opuestos) pasando por 0 (sin relación, en ángulo recto) hasta 1 (misma dirección, sea cual sea la escala). Aplicada a series de rendimientos centradas es la correlación, una magnitud central del riesgo de cartera.

import math

def dot(a, b):
    return sum(x * y for x, y in zip(a, b))

def norm(a):
    return math.sqrt(dot(a, a))

print(norm([3, 4]))                                    # 5.0

def normalize(a):
    length = norm(a)
    if length == 0:
        raise ValueError("a zero vector has no direction")
    return [x / length for x in a]

print(normalize([3, 4]))                               # [0.6, 0.8]

def cosine_similarity(a, b):
    return dot(a, b) / (norm(a) * norm(b))

print(round(cosine_similarity([1, 2], [2, 4]), 6))     # 1.0   (same direction)
print(cosine_similarity([1, 0], [0, 1]))               # 0.0   (perpendicular)
print(round(cosine_similarity([1, 2], [-1, -2]), 6))   # -1.0  (opposite)
import math

def dot(a, b):
    return sum(x * y for x, y in zip(a, b))

def mean(values):
    return sum(values) / len(values)

# Correlation is the cosine of the demeaned series
a = [0.01, 0.02, -0.01, 0.03]
b = [0.02, 0.04, -0.02, 0.06]       # always twice a
da = [x - mean(a) for x in a]
db = [x - mean(b) for x in b]
corr = dot(da, db) / math.sqrt(dot(da, da) * dot(db, db))
print(round(corr, 6))               # 1.0

# Value of a book: quantities dot prices
quantities = [100, -50, 20]
prices = [184.0, 410.0, 171.0]
print(dot(quantities, prices))      # 1320.0
zip oculta diferencias de longitud; los floats ocultan la igualdad exactaComprueba siempre las longitudes antes de usar zip, o perderás datos en silencio. Y nunca compruebes resultados float con ==: el coseno de dos direcciones idénticas puede salir 0.9999999999999999. Compara con math.isclose(...), como hacen las pruebas del lab. En la práctica pronto usarás NumPy, cuyos np.dot y np.linalg.norm hacen todo esto rápido; saber qué calculan te permite comprobarlos.
  • Producto escalar: multiplica posición a posición y suma; comprueba antes las longitudes.
  • Norma sqrt(dot(a, a)); vector unitario a / norm(a) (rechaza el vector nulo).
  • Similitud coseno dot(a, b) / (norm(a) * norm(b)) de -1 a 1; compara floats con isclose.

A continuación: matrices y sistemas lineales, tablas de números que actúan sobre vectores y resuelven muchas ecuaciones a la vez.

Lab: qué se califica

  • Combinar pesos y rendimientos con dot25 pts
  • Medir la longitud de un vector con norm25 pts
  • Comparar direcciones con cosine_similarity25 pts
  • Llevar un vector a longitud 1 con normalize25 pts
Explorador · lab-31-1
▾ lab-31-1
…
bash · en el navegador
learner@quantcraft:~/lab-31-1$
Python aún no cargadoPythonLn 1, Col 1Spaces: 4UTF-8

¿Restablecer este tema?

Todo lo que hay en lab-31-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