σμ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.21·~40 分初級

パッケージとプロジェクト構成

ロードマップ上の位置モジュール 1/11 · トピック 21/33
1.21 パッケージとプロジェクト構成
—ラボスコア— / 100合計XP—連続日数—

1つのファイルからモジュールのフォルダーへ

プロジェクトが大きくなると、1つのファイルでは足りなくなります。パッケージは、Python がひとまとまりとしてインポートできるモジュールのフォルダーです。フォルダーに __init__.py というファイル(空でかまいません)を置くと、中の .py ファイルがパッケージのモジュールになり、ドットで指定します。quant/pricing.py は quant.pricing、quant/data/loaders.py は quant.data.loaders です。パッケージ内のフォルダーはサブパッケージで、それぞれに __init__.py が必要です。

# A small project on disk
#
# quant-tools/
#   pyproject.toml
#   README.md
#   quant/
#     __init__.py
#     pricing.py
#     data/
#       __init__.py
#       loaders.py
#   tests/
#     test_pricing.py

# quant/pricing.py
def mid(bid, ask):
    return (bid + ask) / 2

# anywhere else in the project
from quant.pricing import mid
import quant.data.loaders

print(mid(184.0, 185.0))  # 184.5

拡張しやすい構成

インポートするコードはプロジェクト名のパッケージフォルダーに入れ、それ以外はその中ではなく隣に置きます。テストは tests/、プロジェクトを説明する README.md、名前と依存関係を書く pyproject.toml、データやノートブックはそれぞれ専用のフォルダーです。テストファイルは pytest などのツールが見つけられるよう test_*.py と名付けます。長い utils.py 1つより、pricing.py や loaders.py のように名前が明確で役割の絞られた小さなモジュールのほうが、テストも再利用も簡単です。

# pyproject.toml (names the project and its dependencies)
#
# [project]
# name = "quant-tools"
# version = "0.1.0"
# requires-python = ">=3.11"
# dependencies = ["numpy"]

# tests/test_pricing.py: found automatically because of the name
from quant.pricing import mid

def test_mid():
    assert mid(184.0, 185.0) == 184.5

パッケージ内でのインポート

パッケージ内では、最上位からの完全なパス(from quant.pricing import mid、絶対インポート)か、現在のモジュールからの相対(from .pricing import mid、同じパッケージならドット1つ、親ならドット2つ、相対インポート)でインポートできます。通常は絶対インポートのほうが分かりやすくなります。__init__.py はパッケージの最初のインポート時に実行されるので、利用者に必要な名前を再エクスポート(from .pricing import mid)でき、import quant; quant.mid(...) が使えます。パッケージのコードは python quant/data/loaders.py ではなく python -m quant.data.loaders で実行し、ドット付きの名前が解決されるようにします。

# quant/__init__.py: runs on the first "import quant"
from .pricing import mid          # relative: same package

__all__ = ["mid"]                 # what "from quant import *" would give

# quant/data/loaders.py
from quant.pricing import mid     # absolute: always starts at the top
from .. import pricing            # relative: two dots = the parent package

# In a terminal, from the project folder:
#   python -m quant.data.loaders   (runs the module as part of the package)
#   pytest -q                      (finds tests/test_*.py)
# A file path and its module name are two spellings of one thing
path = "quant/data/loaders.py"
name = path[:-3].replace("/", ".")
print(name)                          # quant.data.loaders
print(name.split(".")[0])            # quant  (the top-level package)

# __init__.py stands for its folder
print("quant/__init__.py"[:-3].replace("/", "."))  # quant.__init__ -> the package is "quant"
__init__.py の抜けは気づきにくい落とし穴Python は __init__.py のないフォルダーを(「名前空間パッケージ」として)インポートできることもありますが、ツール、テストランナー、インストーラーの挙動が一定せず、自分のPCで動いたインポートが他の環境で失敗します。パッケージのフォルダーにはすべて __init__.py を置きましょう。ラボでは、コードがあるのに __init__.py がないフォルダーを見つけます。
  • パッケージは __init__.py のあるフォルダー。quant/data/loaders.py はモジュール quant.data.loaders
  • コードはパッケージの中、テスト・README・pyproject.toml・データはその隣に置く
  • 絶対インポートを優先し、パッケージのコードは python -m package.module で実行する

次は仮想環境と pipです。プロジェクトごとに必要なライブラリだけを用意する方法を学びます。

ラボ:採点される内容

  • module_name でファイルパスをモジュール名に変換する25点
  • find_modules でプロジェクトのインポート可能なモジュールを列挙する25点
  • missing_init で __init__.py のないフォルダーを見つける25点
  • import_line でモジュールの import 文を作る25点
エクスプローラー · lab-21-1
▾ lab-21-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-21-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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