σμ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.17·~35 minBeginner

CSV files

Skill positionModule 1 of 11 · Topic 17 of 33
1.17 CSV files
—Lab score— / 100Total XP—Streak—

Tables as text

A CSV (comma-separated values) file stores a table as text: one row per line, cells separated by commas, usually with a header row naming the columns. Price histories, trade blotters and exports from almost any tool come this way. It looks easy to parse with line.split(","), but a cell may itself contain a comma, in which case it is wrapped in quotes: AAPL,"Q3, adjusted". Splitting by hand breaks on that, so use the standard csv module, and open the file with newline="" so it handles line breaks inside cells correctly.

import csv

# Write a small table with csv.writer
with open("prices.csv", "w", newline="", encoding="utf-8") as file:
    writer = csv.writer(file)
    writer.writerow(["date", "symbol", "close", "note"])
    writer.writerow(["2025-01-02", "AAPL", 184.25, "Q3, adjusted"])
    writer.writerow(["2025-01-03", "AAPL", 185.5, ""])

# The comma inside the note is quoted for us
with open("prices.csv", encoding="utf-8") as file:
    print(file.read().splitlines()[1])  # 2025-01-02,AAPL,184.25,"Q3, adjusted"

Reading rows

csv.reader(file) yields each row as a list of strings. csv.DictReader(file) reads the header first and then yields each row as a dictionary keyed by column name, which is easier to read and survives columns being reordered. Either way every cell is text: convert with float(...) or int(...) before doing arithmetic. Pass delimiter=";" (or "\t") for files that use another separator.

import csv

# DictReader gives each row as a dict; cells are strings
closes = []
with open("prices.csv", newline="", encoding="utf-8") as file:
    for row in csv.DictReader(file):
        closes.append(float(row["close"]))
print(closes)  # [184.25, 185.5]

# csv.reader gives plain lists, header included
with open("prices.csv", newline="", encoding="utf-8") as file:
    rows = list(csv.reader(file))
print(rows[0])  # ['date', 'symbol', 'close', 'note']
print(rows[1])  # ['2025-01-02', 'AAPL', '184.25', 'Q3, adjusted']

Writing rows

csv.writer(file).writerow(values) writes one row and quotes cells when needed; numbers are converted to text for you. csv.DictWriter(file, fieldnames=[...]) writes dictionaries, and writeheader() writes the column names first. Open the file with "w" and newline=""; without newline="" Windows can end up with blank lines between rows.

import csv

# DictWriter: header first, then one dict per row
trades = [{"symbol": "AAPL", "quantity": 200}, {"symbol": "MSFT", "quantity": 50}]
with open("trades.csv", "w", newline="", encoding="utf-8") as file:
    writer = csv.DictWriter(file, fieldnames=["symbol", "quantity"])
    writer.writeheader()
    writer.writerows(trades)

with open("trades.csv", encoding="utf-8") as file:
    print(file.read().splitlines())  # ['symbol,quantity', 'AAPL,200', 'MSFT,50']
import csv

# Cells are text until you convert them
with open("prices.csv", newline="", encoding="utf-8") as file:
    row = next(csv.DictReader(file))
print(repr(row["close"]), row["close"] * 2)   # '184.25' 184.25184.25
print(float(row["close"]) * 2)                # 368.5

# Another separator: semicolons
with open("euro.csv", "w", newline="", encoding="utf-8") as file:
    csv.writer(file, delimiter=";").writerow(["AAPL", "184,25"])
with open("euro.csv", newline="", encoding="utf-8") as file:
    print(next(csv.reader(file, delimiter=";")))  # ['AAPL', '184,25']
Everything comes back as textA CSV file has no types: 184.25, 200 and AAPL are all just characters until you convert them. Forgetting that gives "184.25" * 200 (the text repeated 200 times) instead of an error. Convert each column once, right where you read it, and check the header names rather than assuming positions.
  • Open with newline=""; do not split or join CSV lines by hand.
  • csv.DictReader reads rows as dicts; every cell is a string.
  • csv.writer / csv.DictWriter write rows and quote cells for you.

Next up: JSON data, for nested records that do not fit a flat table.

Lab · what's graded

  • Group closing prices by symbol with read_closes25 pts
  • Save trades as a CSV file with write_trades25 pts
  • Total the traded value per symbol with total_by_symbol25 pts
  • Copy one symbol's rows to a new file with filter_rows25 pts
Explorer · lab-17-1
▾ lab-17-1
…
bash · in-browser
learner@quantcraft:~/lab-17-1$
Python not loaded yetPythonLn 1, Col 1Spaces: 4UTF-8

Reset this topic?

Everything in lab-17-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