σμ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.2·~1 時間エキスパート

クオンツコードのためのCI/CD

ロードマップ上の位置モジュール 11/11 · トピック 2/13
11.2 クオンツコードのためのCI/CD
—ラボスコア— / 100合計XP—連続日数—

自動で走るチェック

テストは、あなたの記憶ではない何かによって毎回実行されて初めて、あなたを守ります。継続的インテグレーション(CI)は、push やプルリクエストのたびにクリーンな環境でコードをチェックアウトし、定義したチェックを実行するサーバーです。lint、型チェック、テスト、小さなバックテストなどです。何かが失敗すれば、その変更はブロックされます。継続的デリバリー/デプロイ(CD)はさらに進み、メインブランチでチェックが通ると新しいバージョンが自動的にビルド・公開されます。クオンツの仕事では、リスクは具体的です。価格を静かに1ベーシスポイントずらすリファクタリングは、ポートフォリオに届く前に機械が捕まえるべきです。

# A test matrix: every operating system with every Python version, minus the combinations you skip
from itertools import product

os_list = ["linux", "macos", "windows"]
py_versions = ["3.11", "3.12"]
exclude = {("windows", "3.11")}

jobs = [(os_name, version) for os_name, version in product(os_list, py_versions) if (os_name, version) not in exclude]
print(len(jobs))                                     # 5
print(jobs[0], jobs[-1])                             # ('linux', '3.11') ('windows', '3.12')

クオンツのパイプラインが確認すること

典型的パイプラインには、早く失敗する段階があります。lint(スタイルと明らかな誤り)と型チェックは数秒で終わり、次に単体テスト、そして保存済みの結果と比べる小さな回帰バックテストのような遅いチェックが続きます。チェックは決定的にします。乱数シードを固定し、ネットワークを使わず、今日の日付に依存せず、ライブのフィードではなくコミット済みの小さなスナップショットのデータを使います。サポートすると主張する Python のバージョンと OS のマトリクスで実行します。フィードバックを速くするには、変更が影響しうるテストだけを実行し(テスト選択)、判断できないときは安全のためスイート全体に戻ります。

# Test selection: run only the tests a change can affect; an unknown file means "run everything"
def select_tests(changed_files, mapping):
    chosen = set()
    for path in changed_files:
        matches = [tests for prefix, tests in mapping.items() if path.startswith(prefix)]
        if not matches:
            return sorted({test for tests in mapping.values() for test in tests})
        for tests in matches:
            chosen.update(tests)
    return sorted(chosen)

mapping = {"src/pricing/": ["tests/test_bs.py", "tests/test_greeks.py"], "src/risk/": ["tests/test_var.py"]}
print(select_tests(["src/risk/var.py"], mapping))                    # ['tests/test_var.py']
print(select_tests(["src/risk/var.py", "setup.cfg"], mapping))       # all three tests: setup.cfg could affect anything

ゲート、シークレット、ワークフローファイル

パイプラインはリポジトリ内のファイルに記述します。たとえば GitHub Actions なら .github/workflows/ci.yml で、実行タイミング(on:)、ジョブ、マトリクス、ステップを書き、各ステップは用意済みのアクションを uses: するか、コマンドを run: します。このファイルもコードとして扱い、他と同様にレビューします。デプロイゲートを設けます。デプロイするのは main ブランチだけで、必須のジョブがすべて成功したときだけです(スキップされたり存在しないジョブは成功ではありません)。チェックを通らないとマージできないようにブランチを保護します。API キーやパスワードは CI システムのシークレットに置き、決してリポジトリには置かず、各ジョブには必要な権限だけを与えます。まずペーパートレードやステージング環境にリリースします。

# The deploy gate: main branch only, and every required job must have succeeded
def can_deploy(results, required, branch):
    return branch == "main" and all(results.get(job) == "success" for job in required)

print(can_deploy({"lint": "success", "tests": "success"}, ["lint", "tests"], "main"))     # True
print(can_deploy({"lint": "success", "tests": "skipped"}, ["lint", "tests"], "main"))     # False  skipped is not success
print(can_deploy({"lint": "success"}, ["lint", "tests"], "main"))                         # False  a missing job is not success
print(can_deploy({"lint": "success", "tests": "success"}, ["lint", "tests"], "dev"))      # False  only main deploys
# The workflow file is plain text, so it can be generated and checked like any other output
def workflow_yaml(name, python_versions, command):
    versions = ", ".join(f'"{version}"' for version in python_versions)
    lines = [f"name: {name}", "on: [push, pull_request]", "jobs:", "  test:", "    runs-on: ubuntu-latest",
             "    strategy:", "      matrix:", f"        python-version: [{versions}]", "    steps:",
             "      - uses: actions/checkout@v4", "      - uses: actions/setup-python@v5", "        with:",
             "          python-version: ${{ matrix.python-version }}", "      - run: pip install -e .[test]",
             f"      - run: {command}"]
    return "\n".join(lines) + "\n"

text = workflow_yaml("ci", ["3.11", "3.12"], "pytest -q")
print(text.splitlines()[7])                          #         python-version: ["3.11", "3.12"]
print(text.splitlines()[-1])                         #       - run: pytest -q
パイプラインが緑でも、テストの質以上のものは保証しないCI が証明するのはチェックが通ることであって、戦略が良いことではありません。スイートは、実行してもらえるよう速く保ちましょう。不安定なテストは直すか削除します(ランダムに落ちるテストは、赤を無視することを全員に教えてしまいます)。ビルドの失敗はチームの最優先事項として扱います。CI で使うツールのバージョンを固定し、同じチェックを自分のマシンでも正確に実行できる手段を残して、「手元では動く」と「CI で失敗する」が謎にならないようにしましょう。
  • CI は push のたびにクリーンな環境で lint・型チェック・テストを走らせ、CD は main で通ったときだけ自動でリリースする
  • チェックは決定的に(シード、スナップショット、ネットワークなし)。バージョンと OS のマトリクスで実行し、変更内容に応じてテストを選ぶ
  • パイプラインはレビューされるワークフローファイルに記述し、デプロイは main と必須ジョブでゲートし、シークレットは CI システムに置き、不安定なテストは直す

次はスケジュール実行されるパイプラインです。データ処理やトレーディングのジョブを適切な時刻に適切な順序で実行します。

ラボ:採点される内容

  • matrix_jobs でテストマトリクスを展開する25点
  • select_tests で必要なテストだけ実行する25点
  • can_deploy でリリースを守る25点
  • workflow_yaml でワークフローを生成する25点
エクスプローラー · lab-131-1
▾ lab-131-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-131-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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