σμ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.26·~45 minDébutant

Classes et objets

Position dans le parcoursModule 1 sur 11 · Sujet 26 sur 33
1.26 Classes et objets
—Score du lab— / 100XP total—Série—

Données et comportement réunis

Jusqu'ici, une position pouvait être un tuple ou un dictionnaire, avec des fonctions séparées qui travaillent dessus. Une classe regroupe les données et les fonctions qui leur appartiennent en un nouveau type. class Position: définit le plan ; l'appeler, Position("AAPL", 100, 180.0), construit un objet (aussi appelé instance) d'après ce plan. Chaque objet contient ses propres données, et les fonctions définies dans la classe, appelées méthodes, travaillent sur cet objet.

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__ et self

__init__ est le constructeur : Python l'exécute automatiquement quand on crée un objet, et il enregistre les valeurs de départ. Chaque méthode reçoit l'objet lui-même comme premier paramètre, appelé par convention self ; on ne le passe pas, Python s'en charge (apple.describe() appelle Position.describe(apple)). Tout ce qui est enregistré par self.nom = valeur est un attribut de cet objet et y reste entre les appels de méthode. __init__ prépare les choses et ne renvoie rien.

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

Des méthodes qui changent l'état ou répondent à des questions

Certaines méthodes répondent à une question sur l'objet sans le modifier (market_value(price)) ; elles doivent juste renvoyer un résultat et laisser les attributs tranquilles. D'autres modifient l'objet (apply_fill), mettent à jour des attributs et renvoient souvent quelque chose d'utile comme le gain réalisé. Une méthode peut en appeler une autre avec self.autre_methode(...), ce qui garde les règles à un seul endroit : si unrealized_pnl a besoin de la valeur de marché, elle demande self.market_value(price) plutôt que de répéter la formule.

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

Pièges et quand utiliser une classe

Oublier self. est l'étourderie classique : quantity = 5 dans une méthode crée une variable locale jetable, pas un attribut. Utilisez CapWords pour les noms de classes (Position) et minuscules avec tirets bas pour attributs et méthodes ; un tiret bas initial (_cache) indique un élément interne. N'utilisez jamais une valeur par défaut modifiable comme def __init__(self, fills=[]) : tous les objets partageraient cette unique liste ; utilisez fills=None et créez [] dedans. Créez une classe quand les données et les règles qui les concernent vont ensemble ; une simple fonction ou un dictionnaire est souvent plus simple.

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
Vérifiez que chaque objet garde son propre étatUne bonne habitude quand on écrit une classe : créer deux objets, en modifier un et afficher l'autre. Si le second a changé aussi, quelque chose est partagé qui ne devrait pas l'être. Les tests du lab font exactement cela, et vérifient aussi qu'une méthode censée seulement répondre à une question laisse les attributs inchangés.
  • class Nom: définit un type ; Nom(args) construit un objet et exécute __init__.
  • self.attr = valeur enregistre une donnée sur l'objet ; chaque méthode prend self en premier.
  • Les méthodes de requête renvoient des réponses ; celles de mise à jour modifient des attributs ; évitez les valeurs par défaut modifiables.

À suivre : les méthodes spéciales comme __repr__ et __eq__, qui font que vos objets s'affichent bien et se comparent comme prévu.

Lab : ce qui est noté

  • Construire une position avec __init__25 pts
  • Valoriser la position avec market_value25 pts
  • Mesurer le gain latent avec unrealized_pnl25 pts
  • Mettre à jour la position après une transaction avec apply_fill25 pts
Explorateur · lab-26-1
▾ lab-26-1
…
bash · dans le navigateur
learner@quantcraft:~/lab-26-1$
Python pas encore chargéPythonLn 1, Col 1Spaces: 4UTF-8

Réinitialiser ce sujet ?

Tout le contenu de lab-26-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