σμ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 Academyロードマップ
Ctrl K
AO
+1.2k 人の学習者
ログイン参加する ↗
ロードマップ
AO
+1.2k 人の学習者
ログイン
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Python ロードマップ›モジュール 1 · クオンツのためのPython基礎›トピック 1.14·~40 分初級

辞書

ロードマップ上の位置モジュール 1/11 · トピック 14/33
1.14 辞書
—ラボスコア— / 100合計XP—連続日数—

名前で値を引く

辞書(dict)はキーと値を対応づけます:{"AAPL": 184.5, "MSFT": 410.2}。リストが位置で要素を見つけるのに対し、辞書はキーで見つけ、エントリ数が増えても検索は速いままです。prices["AAPL"] で値を読み、prices["TSLA"] = 251.0 で新しいエントリを追加するか既存のものを置き換え、"AAPL" in prices でキーがあるかを調べます。存在しないキーを角かっこで読むと KeyError になります。

prices = {"AAPL": 184.5, "MSFT": 410.2}

# Read, add and replace
print(prices["AAPL"])       # 184.5
prices["TSLA"] = 251.0
prices["AAPL"] = 185.0
print(prices)               # {'AAPL': 185.0, 'MSFT': 410.2, 'TSLA': 251.0}

# in tests the keys; a missing key raises KeyError
print("MSFT" in prices, "GOOG" in prices)  # True False
try:
    prices["GOOG"]
except KeyError as error:
    print("no such key:", error)

get:キーがなくてもエラーではない

prices.get("GOOG", 0.0) は値を返し、キーがなければ指定した既定値(指定しなければ None)を返し、エラーにはなりません。これでカウンターが簡単に作れます。counts[symbol] = counts.get(symbol, 0) + 1 は新しいシンボルなら 0 から始め、出てくるたびに1を足します。キーがないことがバグで、それに気づきたいときは []、ないのが普通なら get を使います。

# get() with a default never raises
prices = {"AAPL": 184.5}
print(prices.get("AAPL", 0.0))   # 184.5
print(prices.get("GOOG", 0.0))   # 0.0
print(prices.get("GOOG"))        # None

# Counting with get
counts = {}
for symbol in ["AAPL", "MSFT", "AAPL", "AAPL"]:
    counts[symbol] = counts.get(symbol, 0) + 1
print(counts)                    # {'AAPL': 3, 'MSFT': 1}

辞書をたどる

単純な for key in prices はキーを順にたどります。値は prices.values()、(キー, 値) のペアは prices.items() で得られ、ループ内でアンパックします:for symbol, price in prices.items()。辞書はキーが追加された順序を覚えています。同じ辞書をループしている間にキーを追加・削除してはいけません。コピーをたどるか、新しい辞書を作りましょう。

# keys(), values() and items()
positions = {"AAPL": 200, "MSFT": 50, "GOOG": 0}
prices = {"AAPL": 184.5, "MSFT": 410.2}

for symbol in positions:
    print(symbol, end=" ")      # AAPL MSFT GOOG
print()

total = 0.0
for symbol, quantity in positions.items():
    total += quantity * prices.get(symbol, 0.0)
print(round(total, 2))          # 57410.0

削除・結合・コピー

prices.pop("AAPL", None) はキーを削除してその値を返し(なければ既定値)、del prices["AAPL"] は削除し、なければ KeyError になります。a.update(b) は b のエントリを a にコピーして a を変更し、{**a, **b} や a | b は共通のキーで b が優先される新しい辞書を作ります。リストと同じく copy = prices は名前が増えるだけなので、本当のコピーには dict(prices) か prices.copy() を使います。

# Removing and merging
book = {"AAPL": 200, "MSFT": 50}
sold = book.pop("MSFT", 0)
print(sold, book)                 # 50 {'AAPL': 200}

# {**a, **b} builds a new dict; b wins on shared keys
defaults = {"fee": 0.001, "currency": "USD"}
custom = {"fee": 0.0005}
settings = {**defaults, **custom}
print(settings)                   # {'fee': 0.0005, 'currency': 'USD'}
print(defaults)                   # unchanged: {'fee': 0.001, 'currency': 'USD'}

キーにできるもの

キーはハッシュ可能でなければならず、実際には変更できないものという意味です。文字列、数値、それらのタプルは使えますが、リストや辞書は使えません。タプルは (symbol, venue) のような複合キーに向いています。値には別のリストや辞書を含め何でも入れられます。同じキーは1つしか存在できないので、もう一度代入すると古い値が置き換わります。

# A tuple as a compound key, a list as a value
best = {("AAPL", "NYSE"): 184.6, ("AAPL", "ARCA"): 184.5}
print(best[("AAPL", "ARCA")])        # 184.5

fills = {"AAPL": [100, 250], "MSFT": [75]}
fills["AAPL"].append(40)
print(fills)                         # {'AAPL': [100, 250, 40], 'MSFT': [75]}

# A list cannot be a key
try:
    {["AAPL"]: 1}
except TypeError as error:
    print("not hashable:", error)
[] と get は意図して使い分けるprices[symbol] は「このキーは必ずある」という意味で、なければ大きく失敗します。prices.get(symbol, default) は「なくてもよい」という意味です。本物のバグを既定値で隠すのも、普通のケースで落ちるのと同じくらい悪いので、どちらの意図かを決めましょう。ラボでは、渡した辞書が変更されていないことも確認します。
  • d[key]、d[key] = value、key in d:読む・書く・キーを調べる
  • d.get(key, default):安全な検索。d.items():ループ用のペア
  • d.pop(key, default)、del d[key]、d.update(other)、{**a, **b}:削除と結合

次は集合です。重複のない値のコレクションで、所属判定が速く、集合演算も簡潔に書けます。

ラボ:採点される内容

  • latest_prices でシンボルごとの最新価格を保持する25点
  • count_symbols で各シンボルの出現回数を数える25点
  • portfolio_value で2つの辞書からポートフォリオの価値を求める25点
  • merge_positions で2つのポジション帳を統合する25点
エクスプローラー · lab-14-1
▾ lab-14-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-14-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

このトピックをリセットしますか?

lab-14-1 の内容はすべてスターターファイルに戻り、ターミナルも消去されます。現在の解答は失われ、元に戻せません。

リセットされるもの
  • main.py → スターターコード
  • ターミナル履歴とテスト出力
  • 未提出の変更
保持されるもの
  • ラボの最高スコア
  • XPと連続日数
  • 講義の進捗とメモ

コードを実行するにはログインしてください。

レクチャーはすべて無料で読めます。コードの実行、テスト、ラボの提出にはアカウントの作成かログインが必要です。

  • ブラウザ内IDEとbashターミナル。インストール不要
  • 即時採点、XP、ロードマップでの現在地
アカウントを作成ログイン
または
GitHubで続ける