σμ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 ロードマップ›モジュール 11 · 本番システムと最先端モデル›トピック 11.1·~1 時間エキスパート

Pythonライブラリのパッケージング

ロードマップ上の位置モジュール 11/11 · トピック 1/13
11.1 Pythonライブラリのパッケージング
—ラボスコア— / 100合計XP—連続日数—

スクリプトのフォルダからインストール可能なライブラリへ

スクリプトのフォルダに置かれたコードは、他の誰かがそれを必要とするか、別の環境で必要になる日まで、1台のマシンで1人のために動くだけです。パッケージングは、コードを名前、バージョン、宣言された依存関係を持つライブラリにし、誰でも pip install でインストールできるようにします。チームがファイルをコピーせずに評価ライブラリを共有でき、リサーチ用ノートブックと本番ジョブがまったく同じコードを実行でき、バグ修正が新しいバージョン番号で全員に届きます。

# Versions are numbers, not text: compare them as tuples
def parse_version(text):
    parts = [int(part) for part in text.split(".")]
    return tuple(parts + [0] * (3 - len(parts)))

print("1.10" > "1.9")                                # False  as text, "1" < "9" decides it: wrong
print(parse_version("1.10") > parse_version("1.9"))  # True   as numbers (1, 10, 0) is newer than (1, 9, 0)
print(parse_version("2"))                            # (2, 0, 0)

構成、pyproject.toml、ビルド

一般的な構成では、コードを src/yourlib/(__init__.py 付き)、テストを tests/、そしてルートに pyproject.toml を置きます。この1つのファイルが、ビルドツール([build-system] テーブル)を指定し、プロジェクトの name、version、説明、対応する Python のバージョン、dependencies を記述します。開発中は pip install -e . でフォルダを編集可能モードでインストールすると、変更がすぐ反映されます。python -m build は dist/ に wheel(.whl、すぐインストール可能)と sdist(ソースアーカイブ)を作ります。バージョンは1か所だけに置き、必要なら yourlib.__version__ として公開します。

# A minimal pyproject.toml, generated and then read back with tomllib to prove it is valid
import tomllib

def pyproject_toml(name, version, dependencies):
    lines = ["[build-system]", 'requires = ["setuptools>=68"]', 'build-backend = "setuptools.build_meta"', "",
             "[project]", f'name = "{name}"', f'version = "{version}"']
    if dependencies:
        lines += ["dependencies = ["] + [f'    "{d}",' for d in dependencies] + ["]"]
    else:
        lines.append("dependencies = []")
    return "\n".join(lines) + "\n"

text = pyproject_toml("qcpricing", "0.3.0", ["numpy>=1.26", "pandas>=2"])
data = tomllib.loads(text)
print(data["project"]["name"], data["project"]["version"])      # qcpricing 0.3.0
print(data["project"]["dependencies"])                          # ['numpy>=1.26', 'pandas>=2']

バージョンとバージョン指定子

ほとんどのライブラリはセマンティックバージョニング MAJOR.MINOR.PATCH に従います。バグ修正はパッチを上げ(1.4.2 → 1.4.3)、後方互換の機能追加はマイナーを上げてパッチを0に戻し(1.5.0)、互換性を壊す変更はメジャーを上げます(2.0.0)。依存関係は指定子で宣言します。numpy>=1.26,<3 は 1.26 以上 3 未満の NumPy を受け入れます。誠実に許される範囲でゆるくしましょう。下限はテストした最も古いバージョン、上限は自分を壊すと分かっているメジャーバージョンに対してだけ付けます。バージョンの厳密な固定(==)は、他の人がインストールするライブラリではなく、アプリケーションのロックファイルに置くものです。

# Bumping a version and checking a requirement, with versions compared as tuples
import operator

def parse_version(text):
    parts = [int(part) for part in text.split(".")]
    return tuple(parts + [0] * (3 - len(parts)))

def bump_version(version, part):
    major, minor, patch = parse_version(version)
    return {"major": f"{major + 1}.0.0", "minor": f"{major}.{minor + 1}.0", "patch": f"{major}.{minor}.{patch + 1}"}[part]

OPS = {">=": operator.ge, "<": operator.lt, "==": operator.eq}

def satisfies(version, specifier):
    for clause in specifier.split(","):
        symbol = next(op for op in (">=", "==", "<") if clause.startswith(op))
        if not OPS[symbol](parse_version(version), parse_version(clause[len(symbol):])):
            return False
    return True

print(bump_version("1.4.2", "minor"))                # 1.5.0
print(satisfies("1.26.4", ">=1.26,<3"), satisfies("3.0.0", ">=1.26,<3"))      # True False
# One place for the version: read it from the source instead of repeating it in several files
import re

init_py = """__version__ = "0.3.0"
from .pricing import price
"""
match = re.search(r'^__version__ = "([^"]+)"', init_py, re.MULTILINE)
version = match.group(1)
print(version)                                       # 0.3.0
print(tuple(int(part) for part in version.split(".")))      # (0, 3, 0)
公開は慎重にリリースは約束です。誰かが明日、まさにそのバージョンに依存するので、公開したバージョンは決して変えてはいけません。誤りは新しいバージョンを出して直し、変更点を書いた変更履歴を保ちます。対応すると主張する最も古い Python・依存関係と最新のものでテストを走らせましょう。独自の戦略コードには非公開インデックスを使い、鍵、パスワード、データファイルをパッケージに入れてはいけません。
  • パッケージングはコードに名前、バージョン、宣言された依存関係を与え、pip install で入れられるようにする。開発は pip install -e .、ビルドは python -m build
  • pyproject.toml はビルドシステムと [project] のメタデータを持つ。バージョンは文字列でなく数値のタプルで比べる
  • セマンティックバージョニング(MAJOR.MINOR.PATCH)とゆるい指定子(numpy>=1.26,<3)を使う。公開したバージョンは変えず、秘密情報はパッケージに入れない

次はクオンツコードの CI/CD です。変更のたびにチェックを自動実行します。

ラボ:採点される内容

  • parse_version でバージョンを数値として比べる25点
  • bump_version で次のバージョンを出す25点
  • satisfies で依存条件を確かめる25点
  • pyproject_toml でパッケージを記述する25点
エクスプローラー · lab-130-1
▾ lab-130-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-130-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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