σμ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 AcademySkills
Ctrl K
AO
+1.2k Learners
LoginJoin ↗
Skills
AO
+1.2k Learners
Login
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Python skill›Module 1 · Python foundations for quants›Topic 1.19·~45 minBeginner

Exceptions and error handling

Skill positionModule 1 of 11 · Topic 19 of 33
1.19 Exceptions and error handling
—Lab score— / 100Total XP—Streak—

When something goes wrong

When Python cannot do what you asked, it raises an exception: float("abc") raises ValueError, {}["x"] raises KeyError, 1 / 0 raises ZeroDivisionError, opening a missing file raises FileNotFoundError. If nothing handles it, the program stops and prints a traceback, the chain of calls that led there, read from the bottom up. That is the right outcome for a real bug. For problems you can expect, such as a bad price typed by a user, you handle the exception with try and except.

# Handle an expected problem
def to_price(text):
    try:
        return float(text)
    except ValueError:
        return None

print(to_price("184.25"))  # 184.25
print(to_price("abc"))     # None

# An unhandled one stops the program with a traceback
# print(int("abc"))        # ValueError: invalid literal for int()...

Catch only what you expect

Name the exception type: except ValueError:. A bare except: or except Exception: also swallows bugs you never meant to hide, such as a TypeError caused by passing None, and the program carries on with wrong data. Several types can share a handler, except (ValueError, KeyError):, or have separate ones. Python tries the handlers in order and runs the first that matches. You can keep the error with except ValueError as error: and look at error.

# Specific handlers, tried in order
def read_quantity(text):
    try:
        return int(text)
    except ValueError as error:
        print("not a whole number:", error)
        return 0
    except TypeError:
        print("expected text, got something else")
        return 0

print(read_quantity("200"))  # 200
print(read_quantity("2.5"))  # prints the message, then 0
print(read_quantity(None))   # prints the message, then 0

else and finally

Two optional parts complete the statement. else: runs only when the try block raised nothing, which keeps the risky line short and the follow-up code outside the protection. finally: runs always, whether there was an error or not, even after a return: use it for clean-up. Often a with block already does the clean-up for you, as with files.

# else runs on success, finally runs always
def describe(text):
    try:
        price = float(text)
    except ValueError:
        print("bad price")
    else:
        print("price is", price)
    finally:
        print("done with", repr(text))

describe("184.25")
# price is 184.25
# done with '184.25'
describe("abc")
# bad price
# done with 'abc'

Raising your own errors

A function that is given a value it cannot accept should refuse loudly with raise, not quietly return something wrong: raise ValueError("price must be positive"). Choose the built-in type that fits (ValueError for a right type but a bad value, TypeError for a wrong type) and write a message that says what was wrong. The caller then decides whether to catch it. Inside an except block, a bare raise re-raises the error you just caught, handy when you only wanted to log it.

# Refuse bad input, let the caller decide
def parse_price(text):
    price = float(text)           # may raise ValueError itself
    if not price > 0:
        raise ValueError("price must be positive")
    return price

for text in ["184.25", "-5", "abc"]:
    try:
        print(parse_price(text))
    except ValueError as error:
        print("rejected:", error)
# 184.25
# rejected: price must be positive
# rejected: could not convert string to float: 'abc'
Do not hide errors you cannot fixAn except that does nothing (except: pass) turns a crash you could have debugged into silently wrong numbers, which is far worse in trading code. Catch an error only where you know a sensible response: use a default, skip the item, retry, or report it and stop. Otherwise let it propagate to a place that does know.
  • try / except SpecificError: handle the problems you expect, nothing more.
  • else runs when nothing was raised; finally always runs.
  • raise ValueError("message") refuses bad input clearly.

Next up: modules and imports, how to reuse code from the standard library and from your own files.

Lab · what's graded

  • Convert text without crashing with safe_float25 pts
  • Refuse a bad price with parse_price25 pts
  • Skip bad entries with first_valid_price25 pts
  • Handle a missing or damaged file with read_quantity25 pts
Explorer · lab-19-1
▾ lab-19-1
…
bash · in-browser
learner@quantcraft:~/lab-19-1$
Python not loaded yetPythonLn 1, Col 1Spaces: 4UTF-8

Reset this topic?

Everything in lab-19-1 goes back to the starter files and the terminal is cleared. Your current solution will be lost — this can't be undone.

Will be reset
  • main.py → starter code
  • Terminal history and test output
  • Unsubmitted changes
Will be kept
  • Best lab score
  • Your XP and streak
  • Lecture progress and notes

Log in to run your code.

Every lecture is free to read. Create an account or log in to run code, run tests and submit this lab.

  • In-browser IDE with a bash terminal — nothing to install
  • Instant grading, XP and your place on the skill
Create an accountLog in
OR
Continue with GitHub