0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

📈そろそろ来るかも?株&投資信託の“兆し”を分析して自動ポストする仕組みを作った話 - その3(グランビルの法則)

Posted at

1.はじめに

どうも、趣味でデータ分析している猫背なエンジニアです。

今回は、だいぶ前に番外編で中途半端になっていたグランビルの法則を完成させましたので、兆しシリーズとして進めて記録したいと思います。

2. 全体ロジック

■ 概要
前回の記事ではデータ収集ロジックを強化しました。具体的には、ハンドコーディングで収集していた銘柄データをpythonロジック上で銘柄更新と銘柄データ収集するようにしました。

■ システム構成
例のごとくスクリーニング1号機内にグランビルの法則を付与したロジックを追加します。
ロジック的にはすごく簡単で、デッドクロス抽出と同じ方法のものを実装します。1番最初の記事から追っている人はもうお分かりかと思いますが、本スクリーニング1号機の位置付けとしては大きな石をはけるためのふるい部分になると思っても過言でないです。どれだけ、大きな石をはけることができるかが期待です。

3. グランビルの法則実装(スクリーニング1号機)

■ グランビルの法則
「グランビルの法則 (Granville’s Rule)」は、米国の投資アナリスト ジョセフ・E・グランビル が考案した、移動平均線と株価の関係から売買のタイミングを判断する手法です。
基本の考え方としては以下3つからなっています。
1.移動平均線(MA)は株価のトレンドを示す指標。
2.株価とMAの位置関係、そしてMAの傾きから売買シグナルを読み取る。
3.「上昇局面で買い」「下降局面で売り」を4パターンずつ、合計 8つのルール で整理。

■ コーディング
実際にグランビルの法則を実装しました。基本的には番外編で設計した際のソースコードを流用していますが、outputが一部変更になりました。
番外編の際のoutputとしては買いシグナルと売りシグナルをデータフレームに上書きし、データフレームをreturnとして返却していました。しかし、データフレーム自体は不要だったので、その場でスクリーニングして分別しました。
グランビルの法則には説明の通り、合計8パターンがあるのですが、購入フラグとして、「買い①:下から上抜け」と「買い②:押し目」を通過させるロジックにしました。

グランビルの法則
def screen_granville(df):
    df = df.copy()
    df['MA'] = df['Close'].rolling(window=25).mean()
    df['Granville_Signal'] = np.nan  # 新しい列に格納

    for i in range(1, len(df)):
        price = df['Close'].iloc[i]
        prev_price = df['Close'].iloc[i-1]
        ma = df['MA'].iloc[i]
        prev_ma = df['MA'].iloc[i-1]

        # --- 買いシグナル ---
        if prev_price < prev_ma and price > ma:
            #"買い①: 下から上抜け"
            df.at[i, 'Granville_Signal'] = True
        elif price > ma and prev_price > prev_ma and price < ma * 1.01:
            #"買い②: 押し目"
            df.at[i, 'Granville_Signal'] = True
        elif prev_ma < ma and price < ma:
            #"買い③: 一時的な割り込み"
            df.at[i, 'Granville_Signal'] = False
        elif price < ma * 0.95:
            #"買い④: 乖離しすぎ"
            df.at[i, 'Granville_Signal'] = False
        # --- 売りシグナル ---
        elif prev_price > prev_ma and price < ma:
            #"売り⑤: 上から下抜け"
            df.at[i, 'Granville_Signal'] = False
        elif price < ma and prev_price < prev_ma and price > ma * 0.99:
            #"売り⑥: 戻り売り"
            df.at[i, 'Granville_Signal'] = False
        elif prev_ma > ma and price > ma:
            #"売り⑦: 一時的な上抜け"
            df.at[i, 'Granville_Signal'] = False
        elif price > ma * 1.05:
            #"売り⑧: 乖離しすぎ"
            df.at[i, 'Granville_Signal'] = False

    # --- 買いフラグ管理 ---
    Granville_flag = False
    for idx, row in df.iterrows():
        if row['Granville_Signal'] == True:
            Granville_flag = True

    return Granville_flag

■ 実行結果
成功はしているもののデッドクロス抽出をした時とあまり変わらない量になっているような気もします。

実際のログも取ってみたので掲載します。デッドクロス抽出で多くはふるいにかけられているみたいですが、グランビルでも数銘柄はふるいにかけられていることがわかりました。

4.おわりに

今回は兆しシリーズのKK-FinancialEaterの1号機にグランビルの法則を追加しました。結果としては、微妙なところではありますが、一応デッドクロスで逃した銘柄をグランビルでキャッチしている感じという結果が出たので、一旦は成功かなと思います。
次回も1号機にロジックを追加していきたいと思っていますが、がっつりスクリーニングしてくれそうなロジックを見つけるには、まだまだ長そうですね....。

📈 兆しシリーズ

■ 原点(KK-Adam)

■ KK-FinancialEater
〇プロトタイプ編

〇収集器強化編

〇番外編

参考文献

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?