Pythonで株分析を学ぶ本3選|レベル別の選び方と実装コード

株×Pythonを学ぶおすすめ書籍 基礎知識・戦略

※本記事には広告・アフィリエイトリンクが含まれます。掲載内容は筆者の調査・検証に基づき、読者の判断を助ける目的で作成しています。投資は自己責任です。

先に結論です。Pythonで株・金融データ分析を本で学ぶなら、最初から「自動売買の本」を買わないでください。多くの人がそこで止まります。本に載っているコードは動いても、日本株の手数料・権利落ち・lookahead biasを自分で足せないと、バックテストの数字は机上の空論のままです。

検索すると「おすすめ10冊」が並びますが、全部読む必要はありません。実務で使う知識は3層しかありません。(1) リターンとリスクを数える、(2) pandasで時系列を壊さず扱う、(3) コスト込みで戦略を検証する。この3層に対応する本は、日本語で手に入る定番がすでにあります。

本記事では、オライリーから出ている3冊に絞り、各本が教える技術を「今すぐ動く最小コード」で先に見せます。本を買う前に、自分のレベルと「何が足りないか」が分かります。書籍レビューだけ読んで終わり、にはしません。

📘 外部参考『Pythonによるファイナンス 第2版』(オライリー・ジャパン公式)『Pythonによるデータ分析入門 第3版』(公式)『Pythonからはじめるアルゴリズムトレード』(公式)

結論:最初の1冊は状況で決める

「全部買ってから読む」は最悪のルートです。金融の本は厚い。途中で環境構築にハマり、コードを写経しただけで満足してしまう。最初の1冊は、今の弱点に合わせて1冊だけ選んでください。

あなたの状況最初の1冊読んだ直後にできるようになること
Pythonも投資もこれから。リターン・ボラ・シャープレシオの意味が曖昧①『Pythonによるファイナンス 第2版』価格系列から対数リターン・年率ボラ・最大DDを自分で計算できる
Pythonの文法は分かるが、株価CSVをいじるとインデックスが壊れる②『Pythonによるデータ分析入門 第3版』営業日インデックス、リサンプル、欠損、結合を壊さず扱える
指標の計算はできる。バックテストの勝率が信用できない③『Pythonからはじめるアルゴリズムトレード』ベクトル化バックテストと、イベント駆動バックテストの違いが分かる

3冊とも「Python×金融」ですが、役割が違います。①は金融の言葉をコードにする本、②はデータの扱いそのものの本、③は売買ロジックを検証する本です。②は金融専用ではありません。だからこそ、日本株のCSV・J-Quants・yfinanceのどれを使っても応用が効きます。

3冊の比較(版・著者・向き不向き)

旧記事では③を『Pythonで学ぶアルゴリズムトレード』と書いていました。日本語で実際に流通しているのは、同じ著者Yves Hilpischの『Pythonからはじめるアルゴリズムトレード』(2022年、オライリー)です。原書は Python for Algorithmic Trading。こちらに合わせて選びます。

書籍著者 / 版ISBNページ本体価格目安金融特化コード量
Pythonによるファイナンス 第2版Yves Hilpisch / 2019978-4-87311-890-1約6564,950円高い(理論+実装)多い
Pythonによるデータ分析入門 第3版Wes McKinney / 2023978-4-8144-0019-5約6124,400円前後低い(汎用データ処理)非常に多い
PythonからはじめるアルゴリズムトレードYves Hilpisch / 2022978-4-87311-979-3約3683,960円高い(売買特化)多い

価格は出版社公式の表記です。書店・電子版で前後します。①は厚いので「最初の1冊」にするなら、第1〜3部(Python基礎・NumPy/pandas・時系列)だけ先に消化し、デリバティブ評価は後回しで構いません。個人の現物・信用でまず必要なのはリターンとリスクの計算です。

① ファイナンスの言葉をPythonにする本

『Pythonによるファイナンス 第2版 ―データ駆動型アプローチに向けて』は、金融工学の入門からアルゴリズム取引、デリバティブ分析までを1冊に詰め込んだ本です。著者はYves Hilpisch。訳は黒川利明、技術監修は中妻照雄。公式の位置づけは「データ駆動型アプローチ」と「AIファーストファイナンス」です。

初心者がこの本で得る最大の価値は、チャートの印象ではなく対数リターン・ボラティリティ・ドローダウンで成績を語れるようになることです。「勝率70%の戦略」より「年率ボラ18%、最大DD22%、コスト後シャープ0.4」の方が、運用の判断に使えます。

この本を読んだあとに書くべき最小コード

トヨタ(7203.T)の日次終値から、対数リターン・年率ボラティリティ・最大ドローダウンを出します。ここができないうちに移動平均クロスの本へ進むと、バックテストの数字の意味が分かりません。

import numpy as np
import pandas as pd
import yfinance as yf

def load_close(ticker: str, start: str = "2018-01-01") -> pd.Series:
    df = yf.download(ticker, start=start, auto_adjust=True, progress=False)
    close = df["Close"]
    if isinstance(close, pd.DataFrame):
        close = close.iloc[:, 0]
    return close.dropna()

def perf_stats(close: pd.Series, trading_days: int = 245) -> dict:
    """日本株は大まかに245営業日。米国株なら252を使う。"""
    log_ret = np.log(close / close.shift(1)).dropna()
    ann_ret = float(log_ret.mean() * trading_days)
    ann_vol = float(log_ret.std(ddof=1) * np.sqrt(trading_days))
    equity = (1 + log_ret).cumprod()  # 近似。厳密には exp(cumsum)
    equity = np.exp(log_ret.cumsum())
    peak = equity.cummax()
    dd = equity / peak - 1.0
    sharpe = ann_ret / ann_vol if ann_vol else float("nan")
    return {
        "ann_return": round(ann_ret, 4),
        "ann_vol": round(ann_vol, 4),
        "max_dd": round(float(dd.min()), 4),
        "sharpe": round(sharpe, 3),
        "n_days": int(log_ret.shape[0]),
    }

close = load_close("7203.T")
print(perf_stats(close))

ポイントは3つです。終値はauto_adjust=Trueで配当・分割を調整した系列を使う。リターンは単純リターンではなく対数リターン(期間の加算がしやすい)。最大DDは「ピークからの下落率」であり、含み損の見た目とは別物です。含み損の話は最大ドローダウンをPythonで計算する記事でも扱っています。

この本の落とし穴(日本の個人が先に知っておくこと)

  • 原書・訳書とも、取引所接続の例にFXCMが出てきます。日本の個人がそのまま口座を開けて株を自動発注する前提ではありません。
  • 数式とNumPyの説明が厚い。Python文法ゼロだと第2部で止まります。文法だけ先に1週間で済ませる方が速い。
  • デリバティブ評価(BSMなど)は面白いですが、現物の移動平均戦略を回す段階では優先度が低い。

▼ Amazon・楽天で現物を確認する(アフィリエイトリンク)

② pandasを壊さず使う本(金融専用ではないのが強み)

『Pythonによるデータ分析入門 第3版 ―pandas、NumPy、Jupyterを使ったデータ処理』は、pandasの作者Wes McKinney自身が書いた本です。2023年8月刊、pandas 2.0 / Python 3.10対応。訳は瀬戸山雅人・小林儀匡。

金融の本ではありません。だからこそ重要です。株価分析で事故るポイントの大半は戦略ではなく、インデックス・欠損・タイムゾーン・結合です。ドル円と日本株を同じグラフに載せたら日付がズレる、というのは典型で、タイムゾーン地獄の記事でも繰り返されています。

株価で必ず使う3操作:営業日・リサンプル・ラグ

McKinney本の「時系列」「データの結合」を、日本株に寄せて最小実装に落とします。lookahead(未来参照)を防ぐため、シグナルは必ずshift(1)します。

import pandas as pd
import yfinance as yf

def make_business_frame(ticker: str, start: str = "2020-01-01") -> pd.DataFrame:
    raw = yf.download(ticker, start=start, auto_adjust=True, progress=False)
    if isinstance(raw.columns, pd.MultiIndex):
        raw.columns = raw.columns.get_level_values(0)
    df = raw[["Open", "High", "Low", "Close", "Volume"]].copy()
    df.index = pd.to_datetime(df.index).tz_localize(None)
    # 日本の株式は週末が空く。無理に埋めない。穴は NaN のまま残す
    return df.sort_index()

def add_features(df: pd.DataFrame, fast: int = 5, slow: int = 25) -> pd.DataFrame:
    out = df.copy()
    out["sma_fast"] = out["Close"].rolling(fast, min_periods=fast).mean()
    out["sma_slow"] = out["Close"].rolling(slow, min_periods=slow).mean()
    # 当日終値で計算したクロスは、翌営業日にしか使えない
    out["raw_signal"] = (out["sma_fast"] > out["sma_slow"]).astype(int)
    out["signal"] = out["raw_signal"].shift(1)
    out["ret"] = out["Close"].pct_change()
    out["st_ret"] = out["signal"] * out["ret"]
    return out

df = add_features(make_business_frame("7203.T"))
print(df[["Close", "sma_fast", "sma_slow", "signal"]].tail(8))
print("cost-free CAGR approx:", (1 + df["st_ret"].dropna()).prod() ** (245 / df["st_ret"].dropna().shape[0]) - 1)

shift(1)を忘れると、当日終値で「クロスした」と判定し、同じ足のリターンまで取れてしまいます。本に載っている例はきれいなCSVが多く、このバグが目立たない。日本株で日次クロスを検証するなら、ここが最初の関門です。

週次リサンプルでノイズを落とす

日次でパラメータをいじると過学習しやすい。週次の終値だけで傾向を見る癖を、pandasのresampleで先に付けます。

weekly = df.resample("W-FRI").agg(
    {"Open": "first", "High": "max", "Low": "min", "Close": "last", "Volume": "sum"}
).dropna()
weekly["ret"] = weekly["Close"].pct_change()
print(weekly.tail())

データ取得そのものはyfinanceで日本株を取る記事環境構築ガイドと組み合わせてください。本は「ライブラリの地図」、サイト記事は「日本株の現場」です。

▼ pandas本を確認する

③ バックテストの「ベクトル化」と「イベント駆動」を分ける本

『Pythonからはじめるアルゴリズムトレード』は、同じHilpischが自動売買に絞って書いた本です。環境、データ、ベクトル化バックテスト、機械学習予測、イベントベースのクラス、リアルタイム、OANDA/FXCMといった構成。個人が今すぐ日本株APIに接続する本ではありません。価値は検証の型にあります。

ベクトル化は速いが、注文のタイミングを雑に扱いやすい。イベント駆動は遅いが、「シグナルが出た次のバーで成行」を正確に書ける。この区別がつかないままbacktesting.pyvectorbtを回すと、ライブラリのデフォルトに思考を奪われます。

コストを入れたベクトル化バックテスト(日次・日本株)

東証の現物は、売買代金に対して証券会社の手数料が乗ります。ここでは往復0.2%(片道0.1%)を仮置きします。実際の料率は口座によるので、自分の手数料表に置き換えてください。

import numpy as np
import pandas as pd

def vector_backtest(df: pd.DataFrame, fee_one_way: float = 0.001) -> pd.DataFrame:
    """signal は 0/1。前日終値で決めたポジションを当日リターンに掛ける前提。"""
    out = df.copy()
    pos = out["signal"].fillna(0)
    turnover = pos.diff().abs().fillna(pos.abs())
    # ポジション変更があった日だけ片道手数料
    cost = turnover * fee_one_way
    out["gross"] = pos * out["ret"]
    out["net"] = out["gross"] - cost
    out["equity_gross"] = (1 + out["gross"].fillna(0)).cumprod()
    out["equity_net"] = (1 + out["net"].fillna(0)).cumprod()
    return out

def summarize(bt: pd.DataFrame) -> dict:
    net = bt["net"].dropna()
    eq = bt["equity_net"].replace(0, np.nan).dropna()
    peak = eq.cummax()
    dd = eq / peak - 1
    n = net.shape[0]
    return {
        "net_total": round(float(eq.iloc[-1] - 1), 4),
        "ann_vol": round(float(net.std() * np.sqrt(245)), 4),
        "max_dd": round(float(dd.min()), 4),
        "trades": int((bt["signal"].diff().abs() > 0).sum()),
        "days": int(n),
    }

# add_features() の続き
bt = vector_backtest(df)
print("NO COST", round(float(bt["equity_gross"].iloc[-1] - 1), 4))
print("WITH COST", summarize(bt))

移動平均クロスは売買回数が多い。コスト前は綺麗でも、往復0.2%を入れるとシャープが消えることがよくあります。フレームワーク側の例はBacktesting.py入門vectorbtガイドにあります。本で型を学び、ライブラリで速度を買う、という順番が安全です。

イベント駆動の骨格(「次バー始値で約定」を明示する)

ベクトル化では見えにくい約定ルールを、ループで固定します。遅いので全銘柄走査には向きません。ロジックの仕様書として先に書いておく価値があります。

def event_backtest(df: pd.DataFrame, fee: float = 0.001) -> pd.DataFrame:
    cash, pos = 1.0, 0
    records = []
    rows = df.dropna(subset=["sma_fast", "sma_slow", "Open", "Close"])
    idx = rows.index
    for i in range(1, len(idx)):
        prev, today = rows.loc[idx[i - 1]], rows.loc[idx[i]]
        want = 1 if prev["sma_fast"] > prev["sma_slow"] else 0
        # 前日終値で判定し、当日始値で約定
        if want != pos:
            fill = float(today["Open"])
            cash *= (1 - fee)
            pos = want
            px = fill
        else:
            px = float(today["Close"])
        mtm = cash if pos == 0 else cash * (float(today["Close"]) / px)
        records.append({"date": idx[i], "pos": pos, "equity": mtm})
    return pd.DataFrame(records).set_index("date")

このコードは教育用です。分割・信用金利・税金は入れていません。それでも「終値判定・終値約定」よりマシです。本の第4章(ベクトル化)と第6章(イベントクラス)を対比しながら読むと、ライブラリの中身が見えてきます。

▼ アルゴ本を確認する

本に書いていない、日本で詰まる4点

3冊は優秀です。ただし日本の個人がそのまま本番に持っていくと、次で止まります。ここを先に知っていると、本の「海外ブローカー前提」に引きずられません。

詰まる点本の前提日本の個人で起きること先にやること
データきれいなCSV / 海外ベンダーyfinanceの欠損、休日、調整済み/未調整の混在1銘柄で調整有無を目視比較する
発注APIOANDA / FXCM の例株はkabuステーションAPI等。規約・審査があるペーパーで約定ルールを固定してからAPIを見る
コスト手数料ゼロの例が多い現物手数料+税金+スリッページ自分の口座の料率を定数にして再計算
過学習1期間の綺麗なグラフパラメータを動かすと成績が跳ねるウォークフォワードか、期間を2分割する

kabuステーションに進む場合は最小構成BOTの記事を、環境を24時間動かす段階ならVPS比較(サイト内の準備カテゴリ)を読んでください。本→サイト記事→証券API、の順です。逆にすると、動かないコードのデバッグに時間を吸われます。

4週間の読み方(写経で終わらせない)

目安は「1冊を完璧に」ではなく「毎週、検証可能な成果物を1つ残す」です。ノートに感想を書いても運用は変わりません。

  1. 1週目:リターンを数える。①の時系列・統計の章だけ。上のperf_statsを、7203.T / 6758.T / 9984.Tの3銘柄で回し、年率ボラと最大DDを表にする。
  2. 2週目:データを壊さない。②の時系列章。shiftresample・欠損。SBIの約定CSVをpandasで読む作業はCSV読み込み記事と併用。
  3. 3週目:コスト込みクロス。③のベクトル化章。上のvector_backtestで手数料0 / 0.1% / 0.2%の3ケースを出す。勝率ではなくネットの最大DDを見る。
  4. 4週目:仕様を文章にする。「判定足」「約定足」「手数料」「撤退(最大DD何%で止める)」を10行で書く。コードより先に文章。長期運用の考え方は自作アルゴの長期運用ロードマップが近いです。

機械学習の章は4週目以降で十分です。予測精度の話は別記事(サイト内のAI×自動売買カテゴリ)に任せ、まずはコスト後も残る単純ルールがあるかを確認してください。

よくある質問

Python未経験でも①からでよいか

文法の変数・リスト・関数が怪しいなら、先に公式チュートリアルを3日で一周した方が速いです。①は「金融の概念をコードに落とす本」であり、if文の教科書ではありません。公式はPythonチュートリアル(日本語)です。

③だけ読めば自動売買できるか

できません。③は検証とインフラの本です。日本株の発注、信用建玉、夜間、メンテナンスは証券会社のドキュメント側です。本のOANDA例をコピーして株に当てはめないでください。

電子版と紙、どちらがよいか

コードを写すなら電子+公式サンプル(GitHub / 出版社ダウンロード)です。数式を追うなら紙の方が楽な人もいます。①は656ページあるので、最初から通読せず章を飛ばす前提で買ってください。

無料のWeb記事だけで足りるか

データ取得と指標計算なら足りることが多いです。足りないのは「なぜその指標を年率化するのか」「なぜベクトル化とイベント駆動を分けるのか」という型です。本は型、Webは日本株の差分、と割り切ると無駄買いが減ります。

写経したコードを日本株で壊すチェックリスト

本のサンプルが動いたあと、次の5個を自分の環境で試してください。1つでも落ちるなら、本のコードを本番に持っていく段階ではありません。

  1. 調整済みと未調整を並べる。同じ銘柄でauto_adjust=True/Falseを切り替え、分割があった日のリターンが跳ねていないかを見る。跳ねていれば未調整を戦略に使っている。
  2. 祝日を跨いだpct_change大晦日から年始明けのリターンが「2日分」になっていないか。営業日インデックスなら通常は問題にならないが、カレンダーを自分で埋めた瞬間に壊れます。
  3. 複数銘柄の列名。yfinanceは銘柄を複数渡すとMultiIndexになります。本のdf["Close"]がDataFrameのまま平均を取ると、静かにズレます。
  4. 手数料ゼロのグラフを捨てる。コスト前の資産曲線は見せない。少なくとも片道0.1%を入れた曲線だけを残す。
  5. パラメータを±20%ずらす。SMA 5/25が良いなら 4/20 と 6/30 も出す。1点だけ突出するなら過学習です。
def split_robustness(close: pd.Series, fast=5, slow=25) -> pd.DataFrame:
    """前後半で同じクロスを回し、成績が片側に偏っていないか見る。"""
    mid = close.index[len(close) // 2]
    rows = []
    for name, sl in [("first_half", close.loc[:mid]), ("second_half", close.loc[mid:])]:
        sma_f = sl.rolling(fast).mean()
        sma_s = sl.rolling(slow).mean()
        sig = (sma_f > sma_s).astype(int).shift(1)
        ret = sl.pct_change() * sig
        rows.append({
            "period": name,
            "start": str(sl.index.min().date()),
            "end": str(sl.index.max().date()),
            "net": round(float((1 + ret.dropna()).prod() - 1), 4),
            "vol": round(float(ret.std() * (245 ** 0.5)), 4),
        })
    return pd.DataFrame(rows)

print(split_robustness(close))

前後半で符号が逆なら、そのクロスは「その期間の相場」に依存しています。本の第5章(機械学習予測)に進む前に、この分割だけは必ずやってください。予測モデルは、単純クロスより過学習しやすいです。

章立てと実務タスクの対応

実務でやりたいこと①ファイナンス②データ分析入門③アルゴトレード
リターン・ボラ・DDを出す時系列・統計の章集計の基礎ベクトル化の前段
CSV/APIの汚れを取る入出力の章本命(欠損・結合・reshape)データ取得の章
クロス戦略を検証する取引戦略の概要rolling/shift本命(第4・6章)
予測モデルを試す機械学習の導入関係なし第5章(市場予測)
リアルタイム配信自動取引の概要関係なしソケット・ブローカー例

「予測したい」気持ちは分かりますが、表の上3行ができない状態で第5章に入ると、精度の数字だけ見て Strat を信じます。精度の疑いは別記事のテーマなので、ここでは単純ルールがコスト後に残るかを合格ラインにします。

次に手を動かす記事

まとめ:買うのは1冊、検証はコスト込みで

おすすめは「人気順の10冊」ではなく、役割の違う3冊です。金融の言葉は①、データの手は②、売買の検証は③。最初の1冊は今の弱点に合わせ、4週間でperf_statsとコスト込みクロスの数字を残してください。

本のサンプルが海外ブローカー前提でも問題ありません。日本で必要な差分は、調整済み価格、営業日、手数料、翌バー約定の4点にほぼ集約されます。そこを自分のコードに埋め込めたとき、初めて「本を読んだ」ことになります。


※Amazonのアソシエイトとして、当サイトは適格販売により収入を得ることがあります。
※掲載のコードは学習・検証目的です。手数料・税金・流動性は口座と市場で変わります。投資判断はご自身の責任で行ってください。

タイトルとURLをコピーしました