トヨタ・日立など日本製造業株でPython移動平均クロス戦略を検証してみた

Python実装・コード

トヨタや日立、パナソニックみたいな大型製造メーカー株って、アルゴトレーディングに向いてるのかな?とずっと思っていました。正直、「流動性は高そうだけど動きが鈍そう」というイメージがあったんです。でも先日、子供がお昼寝している間に実際にPythonでバックテストをやってみたら、意外と面白い結果が出たので報告します。

なぜ製造業大型株でアルゴを試したのか

僕が日本株の中心に製造メーカーを選んでいる理由は、業績が比較的読みやすく、決算も年4回のサイクルが安定しているからです。ただ、「動きが少ない大型株でアルゴが使えるのか」という疑問はずっとありました。今回検証した銘柄はトヨタ自動車(7203)と日立製作所(6501)です。どちらも日経平均の中でも流動性トップクラスの製造業代表銘柄です。

使用する戦略:移動平均ゴールデンクロス

今回は最もシンプルな「5日移動平均と25日移動平均のゴールデンクロス・デッドクロス」を使います。シンプルすぎると思うかもしれませんが、まずベースラインとして最も単純な戦略から始めて、徐々に改善していくのがおすすめです。

データ取得と移動平均の計算

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

def get_stock_data(ticker, period="3y"):
    # 東証のティッカーは末尾に.Tをつける
    stock = yf.Ticker(f"{ticker}.T")
    df = stock.history(period=period)
    df = df.dropna()
    return df

def add_moving_averages(df, short=5, long=25):
    df[f'SMA{short}'] = df['Close'].rolling(short).mean()
    df[f'SMA{long}'] = df['Close'].rolling(long).mean()
    return df

# トヨタ(7203)と日立(6501)のデータを取得
toyota_df = get_stock_data("7203")
hitachi_df = get_stock_data("6501")

toyota_df = add_moving_averages(toyota_df)
hitachi_df = add_moving_averages(hitachi_df)

バックテストの実装

def backtest_sma_cross(df, short=5, long=25):
    df = df.copy()

    # シグナル生成(shift(1)でルックアヘッドバイアス回避)
    df['signal'] = np.where(
        df[f'SMA{short}'] > df[f'SMA{long}'], 1, 0
    )
    df['signal'] = df['signal'].shift(1)

    # リターン計算(手数料0.1%を考慮)
    df['daily_return'] = df['Close'].pct_change()
    df['strategy_return'] = df['daily_return'] * df['signal']

    # 売買コスト(シグナルが変わるたびに0.1%)
    df['trade'] = df['signal'].diff().abs()
    df['cost'] = df['trade'] * 0.001
    df['strategy_return'] = df['strategy_return'] - df['cost']

    # 累積リターン
    df['cumulative_market'] = (1 + df['daily_return']).cumprod()
    df['cumulative_strategy'] = (1 + df['strategy_return']).cumprod()

    final_market = df['cumulative_market'].iloc[-1]
    final_strategy = df['cumulative_strategy'].iloc[-1]

    print(f"バイ&ホールド(市場): {(final_market - 1) * 100:.1f}%")
    print(f"SMAクロス戦略:         {(final_strategy - 1) * 100:.1f}%")
    return df

print("=== トヨタ(7203)===")
toyota_result = backtest_sma_cross(toyota_df)

print("\n=== 日立(6501)===")
hitachi_result = backtest_sma_cross(hitachi_df)

製造業株でアルゴを使う上での注意点

製造業大型株でアルゴをやる場合、いくつか注意したい点があります。①決算発表前後はシグナルが荒れやすい、②ドル円などの為替の影響を受けやすい輸出銘柄が多い、③出来高が急増するイベント時はスリッページが大きくなる、という3点です。特に①の決算前後は単純な移動平均戦略では対応しきれないケースが多いので、決算前日〜翌日はポジションを外すルールを加えるのも一つの手です。

import pandas as pd

# 決算発表日の前後1営業日を除外するフィルター例
kessan_dates = pd.to_datetime([
    "2025-11-07",  # トヨタ第2四半期
    "2026-02-05",  # トヨタ第3四半期
    "2026-05-08",  # トヨタ本決算
])

def filter_kessan(df, kessan_dates, buffer_days=1):
    mask = pd.Series(False, index=df.index)
    for d in kessan_dates:
        start = d - pd.Timedelta(days=buffer_days)
        end = d + pd.Timedelta(days=buffer_days)
        mask |= (df.index >= start) & (df.index <= end)
    df.loc[mask, 'signal'] = 0  # 決算前後はポジションゼロ
    return df

まとめ

トヨタ・日立を使った移動平均クロス戦略のバックテストを実施しました。結論として「流動性が高い大型製造メーカー株はアルゴと相性が悪くない」という印象を持ちました。ただし戦略のチューニングはまだまだ必要です。個人的には次回、決算イベント除外フィルターを加えたバージョンを試してみようと思います。製造メーカー株で投資している方は、ぜひ同じ検証をやってみてはいかがでしょうか。

関連サービス

この記事で紹介した手法を実際に試す際におすすめのサービスです。

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