σμ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 ロードマップ›モジュール 2 · 市場データのためのNumPyとpandas›トピック 2.12·~40 分中級

DatetimeIndexと時間によるインデックス

ロードマップ上の位置モジュール 2/11 · トピック 12/20
2.12 DatetimeIndexと時間によるインデックス
—ラボスコア— / 100合計XP—連続日数—

日付は文字列ではない

価格の系列は時系列です。大切なのは各価格がいつ起きたかです。ファイルから読んだ日付はただの文字列で、3月が2月の後であることも、月曜日が日曜日の次であることも知りません。pd.to_datetime で変換し、その結果をインデックスにしましょう。DatetimeIndex は本物のタイムスタンプを持ち、pandas が並べ替え・スライス・比較・分解をできます。最も古い観測が先頭に来るよう、必ず sort_index() で並べ替えます。

import pandas as pd

raw_dates = ["2026-03-04", "2026-03-02", "2026-03-03"]      # strings, in a messy order
closes = [102.0, 100.0, 101.0]

series = pd.Series(closes, index=pd.to_datetime(raw_dates), name="close").sort_index()
print(series)
# 2026-03-02    100.0
# 2026-03-03    101.0
# 2026-03-04    102.0
# Name: close, dtype: float64

print(isinstance(series.index, pd.DatetimeIndex))   # True

カレンダーを作る

誰も用意してくれない日付が必要になることがよくあります。比較用の目盛りや、バックテストの日々などです。pd.date_range(start, periods=n, freq="D") は連続する暦日を n 個作り、pd.bdate_range は週末を飛ばして営業日を作ります(祝日は考慮しません)。freq で間隔を指定します。"D" は1日、"B" は営業日、"h" は1時間です。

# Four calendar days, then six business days (the weekend is skipped)
print(pd.date_range("2026-03-01", periods=4, freq="D").strftime("%a %d %b").tolist())
# ['Sun 01 Mar', 'Mon 02 Mar', 'Tue 03 Mar', 'Wed 04 Mar']

days = pd.bdate_range("2026-02-26", periods=6)
print(days.strftime("%a %d %b").tolist())
# ['Thu 26 Feb', 'Fri 27 Feb', 'Mon 02 Mar', 'Tue 03 Mar', 'Wed 04 Mar', 'Thu 05 Mar']

日付で選ぶ

ソートされた DatetimeIndex では、.loc が文字列の日付を理解します。"2026-03" のような部分文字列は1か月全体、"2026" は1年全体、"2026-03-04" は1日を選びます。スライス .loc["2026-03-04":"2026-03-06"] は範囲を選び、位置のスライスと違って両端を含みます。端の日付がデータにある必要はありません。週末の日付は何にも一致しないだけで、「月初から全部」と頼むときにはそれが望む動作です。

prices = pd.Series(
    [float(i) for i in range(20)],
    index=pd.bdate_range("2026-02-23", periods=20),   # Mon 23 Feb ... Fri 20 Mar
)

print(len(prices.loc["2026-03"]))      # 15   the business days of March in the data
print(prices.loc["2026-03-04"])        # 7.0  a single day

print(prices.loc["2026-03-04":"2026-03-06"])
# 2026-03-04    7.0
# 2026-03-05    8.0
# 2026-03-06    9.0
# Freq: B, dtype: float64

print(prices.loc["2026-03-01":"2026-03-03"].tolist())   # [5.0, 6.0]   Sunday the 1st matches nothing

日付の構成要素

DatetimeIndex は各日付の構成要素を属性として持ちます。year、month、day、dayofweek(月曜が0、日曜が6)です。それぞれ行ごとに1つの値を持つ配列なので、マスクやグループのキーとして使えます。「各曜日に何件の観測があるか」「月曜日には何が起きるか」をループなしで調べられます。先にインデックスをソートするのを忘れずに。順序の乱れた DatetimeIndex をスライスすると、意外な結果やエラーになることがあります。

# The parts of the dates, one entry per row
print(prices.index.dayofweek[:7].tolist())   # [0, 1, 2, 3, 4, 0, 1]   Monday is 0
print(prices.index.month[:7].tolist())       # [2, 2, 2, 2, 2, 3, 3]

# How many observations fall on each weekday?
print(prices.groupby(prices.index.dayofweek).size().to_dict())   # {0: 4, 1: 4, 2: 4, 3: 4, 4: 4}

# What do the Mondays look like?
print(prices[prices.index.dayofweek == 0].tolist())   # [0.0, 5.0, 10.0, 15.0]
範囲の終わりに注意時刻のない日付文字列は真夜中を意味します。日次データなら .loc["2026-03-04":"2026-03-06"] は6日を含みますが、日中のデータでは6日の 00:00 で終わり、その日全体を失います。データが1日より細かいときは、結果の最後のタイムスタンプを確認しましょう。
  • pd.to_datetime(文字列) で DatetimeIndex を作り、sort_index() で古い順に並べ、date_range と bdate_range でカレンダーを作る
  • .loc["2026-03"] は1か月、.loc["2026-03-04":"2026-03-06"] は両端を含む範囲を選ぶ
  • index.year・index.month・index.dayofweek は各日付の構成要素を返し、ループなしで絞り込みや集計ができる

次はリサンプリングです。日次の価格を週次・月次、あるいはより細かい足に変換します。

ラボ:採点される内容

  • parse_prices で日付付きの価格系列を作る25点
  • prices_in_month で1か月分を選ぶ25点
  • prices_between で日付の範囲を選ぶ25点
  • count_by_weekday で曜日ごとの観測数を数える25点
エクスプローラー · lab-45-1
▾ lab-45-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-45-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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