σμ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 AcademyParcours
Ctrl K
AO
+1,2 k apprenants
ConnexionRejoindre ↗
Parcours
AO
+1,2 k apprenants
Connexion
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Parcours Python›Module 1 · Les bases de Python pour les quants›Sujet 1.31·~40 minDébutant

Vecteurs et produits scalaires

Position dans le parcoursModule 1 sur 11 · Sujet 31 sur 33
1.31 Vecteurs et produits scalaires
—Score du lab— / 100XP total—Série—

Un vecteur est une liste de nombres avec des règles

Un vecteur est une liste ordonnée de nombres de longueur fixe, comme les poids d'un portefeuille [0.5, 0.3, 0.2] ou les rendements d'un jour pour trois actifs [0.02, -0.01, 0.03]. En Python, une liste de flottants fait l'affaire. On peut additionner, mettre à l'échelle et combiner des vecteurs position par position, ce qui explique pourquoi une grande part de la finance quantitative s'écrit dans leur langage. Deux vecteurs ne se combinent que s'ils ont la même longueur ; mélanger les longueurs est un bogue dont il faut être averti bruyamment.

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]

Le produit scalaire

Le produit scalaire multiplie deux vecteurs position par position et additionne les résultats : a1*b1 + a2*b2 + ... + an*bn. Il renvoie un seul nombre. C'est le rendement du portefeuille quand a contient les poids et b les rendements : 0.5*0.02 + 0.3*(-0.01) + 0.2*0.03 = 0.013. C'est aussi la valeur d'une liste de positions (quantités scalaire prix) et la brique d'une régression. En Python : sum(x * y for x, y in zip(a, b)), après avoir vérifié que len(a) == len(b), car zip s'arrête silencieusement à la liste la plus courte.

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

Longueur, direction et similarité

Un vecteur multiplié scalairement par lui-même donne sa longueur au carré, donc la norme (longueur) vaut math.sqrt(dot(a, a)) : pour [3, 4] c'est 5.0. Diviser un vecteur par sa norme donne un vecteur unitaire de longueur 1 qui ne garde que la direction (mais un vecteur nul n'a pas de direction, refusez-le avec ValueError). La similarité cosinus dot(a, b) / (norm(a) * norm(b)) mesure l'alignement de deux vecteurs, de -1 (opposés) à 0 (sans lien, à angle droit) jusqu'à 1 (même direction, quelle que soit l'échelle). Appliquée à des séries de rendements centrées, c'est la corrélation, une grandeur centrale du risque de portefeuille.

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 masque les écarts de longueur ; les flottants masquent l'égalité exacteVérifiez toujours les longueurs avant d'utiliser zip, sinon vous perdrez des données en silence. Et ne testez jamais des résultats flottants avec == : le cosinus de deux directions identiques peut donner 0.9999999999999999. Comparez avec math.isclose(...), comme le font les tests du lab. En pratique, vous utiliserez bientôt NumPy dont np.dot et np.linalg.norm font tout cela rapidement ; savoir ce qu'ils calculent permet de les vérifier.
  • Produit scalaire : multiplier position par position et additionner ; vérifier d'abord les longueurs.
  • Norme sqrt(dot(a, a)) ; vecteur unitaire a / norm(a) (refuser le vecteur nul).
  • Similarité cosinus dot(a, b) / (norm(a) * norm(b)) de -1 à 1 ; comparez les flottants avec isclose.

À suivre : matrices et systèmes linéaires, des tableaux de nombres qui agissent sur des vecteurs et résolvent plusieurs équations à la fois.

Lab : ce qui est noté

  • Combiner poids et rendements avec dot25 pts
  • Mesurer la longueur d'un vecteur avec norm25 pts
  • Comparer des directions avec cosine_similarity25 pts
  • Ramener un vecteur à la longueur 1 avec normalize25 pts
Explorateur · lab-31-1
▾ lab-31-1
…
bash · dans le navigateur
learner@quantcraft:~/lab-31-1$
Python pas encore chargéPythonLn 1, Col 1Spaces: 4UTF-8

Réinitialiser ce sujet ?

Tout le contenu de lab-31-1 revient aux fichiers de départ et le terminal est vidé. Votre solution actuelle sera perdue : cette action est irréversible.

Sera réinitialisé
  • main.py → code de départ
  • Historique du terminal et sortie des tests
  • Modifications non soumises
Sera conservé
  • Meilleur score du lab
  • Votre XP et votre série
  • Progression du cours et notes

Connectez-vous pour exécuter votre code.

Tous les cours sont gratuits à lire. Créez un compte ou connectez-vous pour exécuter du code, lancer les tests et soumettre ce lab.

  • IDE dans le navigateur avec terminal bash — rien à installer
  • Correction instantanée, XP et votre place dans le parcours
Créer un compteSe connecter
OU
Continuer avec GitHub