<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>株価予測 on Xainome Blog</title>
    <link>https://xainome-blog.pages.dev/tags/%E6%A0%AA%E4%BE%A1%E4%BA%88%E6%B8%AC/</link>
    <description>Recent content in 株価予測 on Xainome Blog</description>
    <generator>Hugo</generator>
    <language>ja-JP</language>
    <lastBuildDate>Wed, 24 Jul 2024 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://xainome-blog.pages.dev/tags/%E6%A0%AA%E4%BE%A1%E4%BA%88%E6%B8%AC/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>短期売買と分析力が向上しそうな株価予測をだらだらとやる part9</title>
      <link>https://xainome-blog.pages.dev/posts/2024/07/stock-price-prediction-part-9/</link>
      <pubDate>Wed, 24 Jul 2024 00:00:00 +0000</pubDate>
      <guid>https://xainome-blog.pages.dev/posts/2024/07/stock-price-prediction-part-9/</guid>
      <description>&lt;h2 id=&#34;前回のあらすじ&#34;&gt;前回のあらすじ&lt;/h2&gt;
&lt;p&gt;確率的勾配降下法を使って予測をしてみました。&lt;/p&gt;
&lt;p&gt;うまくいかなかったので、別の方法を試すことにしました。&lt;/p&gt;
&lt;h2 id=&#34;lstm&#34;&gt;LSTM&lt;/h2&gt;
&lt;p&gt;時系列分析の代表モデルと言えばLSTMだと思います。&lt;/p&gt;
&lt;p&gt;というわけで前回とはプログラムを分けて実装しました。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, LSTM, Input
import matplotlib.pyplot as plt

import glob
dm_fol = &amp;#39;./datamart/&amp;#39;
stock_list = glob.glob(dm_fol + &amp;#34;*.parquet&amp;#34;)

# データの読み込みと前処理
def preprocess_data(df, time_step=60):
    df[&amp;#39;Close&amp;#39;] = df[&amp;#39;Close&amp;#39;].astype(float)
    data = df[[&amp;#39;Close&amp;#39;]].values

    # データのスケーリング
    scaler = MinMaxScaler(feature_range=(0, 1))
    scaled_data = scaler.fit_transform(data)
    
    # LSTM用のデータセット作成
    X, Y = [], []
    for i in range(time_step, len(scaled_data)):
        X.append(scaled_data[i-time_step:i, 0])
        Y.append(scaled_data[i, 0])
    
    X, Y = np.array(X), np.array(Y)
    X = X.reshape(X.shape[0], X.shape[1], 1)
    
    return X, Y, scaler

# LSTMモデルの構築
def create_lstm_model(input_shape):
    model = Sequential()
    model.add(Input(shape=input_shape))  # Inputオブジェクトを使用して入力形状を指定
    model.add(LSTM(50, return_sequences=True))
    # model.add(LSTM(50, return_sequences=True, input_shape=input_shape))
    model.add(LSTM(50, return_sequences=False))
    model.add(Dense(25))
    model.add(Dense(1))
    model.compile(optimizer=&amp;#39;adam&amp;#39;, loss=&amp;#39;mean_squared_error&amp;#39;)
    return model

# モデルの評価とプロット
def evaluate_model(df, model, scaler, X_train, y_train, X_test, y_test, time_step, sticker_name):
    y_train_pred = model.predict(X_train)
    y_test_pred = model.predict(X_test)
    
    y_train_pred = scaler.inverse_transform(y_train_pred)
    y_test_pred = scaler.inverse_transform(y_test_pred)
    
    y_train = scaler.inverse_transform([y_train])
    y_test = scaler.inverse_transform([y_test])
    
    train_mse = np.mean((y_train_pred - y_train[0]) ** 2)
    test_mse = np.mean((y_test_pred - y_test[0]) ** 2)
    print(f&amp;#34;Train Mean Squared Error: {train_mse}&amp;#34;)
    print(f&amp;#34;Test Mean Squared Error: {test_mse}&amp;#34;)
    
    # プロット
    df.set_index(&amp;#39;Date&amp;#39;, inplace=True)
    train_dates = df.iloc[time_step:len(y_train[0])+time_step].index
    test_dates = df.iloc[len(y_train[0])+time_step-1:-1].index
    
    plt.figure(figsize=(14, 7))
    # plt.plot(train_dates, y_train[0], label=&amp;#39;Train Actual&amp;#39;, color=&amp;#39;black&amp;#39;)
    plt.plot(test_dates, y_test[0], label=&amp;#39;Test Actual&amp;#39;, color=&amp;#39;red&amp;#39;)
    plt.plot(test_dates, y_test_pred, label=&amp;#39;Test Predicted&amp;#39;, color=&amp;#39;blue&amp;#39;)
    plt.title(sticker_name+&amp;#39;: Actual vs Predicted Stock Prices&amp;#39;)
    plt.xlabel(&amp;#39;Date&amp;#39;)
    plt.ylabel(&amp;#39;Close&amp;#39;)
    plt.legend()
    plt.show()

# 次の日の予測
def predict_next_day(model, scaler, df, time_step=60):
    data = df[[&amp;#39;Close&amp;#39;]].values
    last_data = data[-time_step:]
    last_data_scaled = scaler.transform(last_data)
    X_input = last_data_scaled.reshape(1, time_step, 1)
    next_day_prediction = model.predict(X_input)
    next_day_prediction = scaler.inverse_transform(next_day_prediction)
    print(f&amp;#34;Next Day Prediction: {next_day_prediction[0][0]}&amp;#34;)

# データの読み込み
for count, stock_data in enumerate(stock_list):
  df = pd.read_parquet(stock_data)
  sticker_name = stock_data.split(&amp;#39;\\&amp;#39;)[1].replace(&amp;#39;.parquet&amp;#39;, &amp;#39;&amp;#39;)

  # データの前処理
  time_step = 60
  X, Y, scaler = preprocess_data(df, time_step)

  # データの分割
  train_size = int(len(X) * 0.8)
  X_train, X_test = X[:train_size], X[train_size:]
  y_train, y_test = Y[:train_size], Y[train_size:]

  # モデルの構築と訓練
  model = create_lstm_model((X_train.shape[1], 1))
  model.fit(X_train, y_train, batch_size=1, epochs=1)

  # モデルの評価
  evaluate_model(df, model, scaler, X_train, y_train, X_test, y_test, time_step, sticker_name)

  # 次の日の予測
  predict_next_day(model, scaler, df, time_step)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;コード確認&#34;&gt;コード確認&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;    # LSTM用のデータセット作成
    X, Y = [], []
    for i in range(time_step, len(scaled_data)):
        X.append(scaled_data[i-time_step:i, 0])
        Y.append(scaled_data[i, 0])
    
    X, Y = np.array(X), np.array(Y)
    X = X.reshape(X.shape[0], X.shape[1], 1)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;LSTM用のデータセットは60日分のデータを学習として使い、次の日を出力として使用するという特徴があります。&lt;/p&gt;</description>
    </item>
    <item>
      <title>短期売買と分析力が向上しそうな株価予測をだらだらとやる part8</title>
      <link>https://xainome-blog.pages.dev/posts/2024/07/stock-price-prediction-part-8/</link>
      <pubDate>Mon, 15 Jul 2024 00:00:00 +0000</pubDate>
      <guid>https://xainome-blog.pages.dev/posts/2024/07/stock-price-prediction-part-8/</guid>
      <description>&lt;h2 id=&#34;前回のあらすじ&#34;&gt;前回のあらすじ&lt;/h2&gt;
&lt;p&gt;株価予測を行うコードをいったん書いてみました。&lt;/p&gt;
&lt;p&gt;課題はまだ残ったままですが、今回はそこを解決しつつモデルを追加で学習するというやり方を試してみました。&lt;/p&gt;
&lt;h2 id=&#34;確率的勾配降下法&#34;&gt;確率的勾配降下法&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;def predict_next_day(model, scaler, df):
    last_row = df.drop(columns=[&amp;#39;Close&amp;#39;]).iloc[-1].values.reshape(1, -1)
    # last_row = df.iloc[-1, :-1].values.reshape(1, -1)
    df.drop(columns=[&amp;#39;Close&amp;#39;]).iloc[-1].to_csv(&amp;#34;test.csv&amp;#34;)
    last_row_scaled = scaler.transform(last_row)
    next_day_prediction = model.predict(last_row_scaled)
    print(f&amp;#34;Previous Day Prediction: {df.iloc[-1][&amp;#39;Close&amp;#39;]}&amp;#34;)
    print(f&amp;#34;Next Day Prediction: {next_day_prediction[0]}&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;前回の予測部分ですが予測するカラムが異なっていたので変な値が出ていました。&lt;/p&gt;
&lt;p&gt;修正したことによってだいぶまともな値に修正ができました。&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;0800.HK&#34; loading=&#34;lazy&#34; src=&#34;https://xainome-blog.pages.dev/posts/2024/07/stock-price-prediction-part-8/images/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2024-07-15-203700-1024x556.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;ただ、うまくいくときはきれいな形になっていますがそうでないことも多いです。&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;AOS&#34; loading=&#34;lazy&#34; src=&#34;https://xainome-blog.pages.dev/posts/2024/07/stock-price-prediction-part-8/images/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2024-07-15-203305-1-1024x555.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;ATNF&#34; loading=&#34;lazy&#34; src=&#34;https://xainome-blog.pages.dev/posts/2024/07/stock-price-prediction-part-8/images/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2024-07-15-203344-1-1024x541.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;EGHT&#34; loading=&#34;lazy&#34; src=&#34;https://xainome-blog.pages.dev/posts/2024/07/stock-price-prediction-part-8/images/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2024-07-15-203520-1-1024x538.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;波があるところはうまくできている方ですが、直線気味だとうまくいかないですね。&lt;/p&gt;
&lt;p&gt;毎回初期化しているのですが、ダメですね。使ってるモデルが確率的勾配降下法も要因としてあるかもしれないです。&lt;/p&gt;
&lt;p&gt;というわけで追加学習する形に変更しようと試してみました。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;def update_model(model, scaler, new_df):
    target = new_df[&amp;#39;Close&amp;#39;].shift(-1).dropna()
    features = new_df.drop(columns=[&amp;#39;Close&amp;#39;])
    features = features[:-1]
    
    # データのスケーリング
    X = scaler.transform(features.values)
    y = target.values
    
    model.partial_fit(X, y)

    # 新しいデータに対する予測と評価
    # X_new = scaler.transform(new_df.drop(columns=[&amp;#39;Close&amp;#39;]).values)
    X_new = scaler.transform(new_df.drop(columns=[&amp;#39;Close&amp;#39;]).iloc[:-1].values)
    y_new = new_df[&amp;#39;Close&amp;#39;].shift(-1).dropna().values
    y_new_pred = model.predict(X_new)
    mse_new = mean_squared_error(y_new, y_new_pred)
    print(f&amp;#34;New Data MSE: {mse_new}&amp;#34;)

for count, stock_data in enumerate(stock_list):
  ・
　・
　・
  if count == 0:
    model, scaler, X_train, X_test, y_train, y_test = train_model(df)

    # モデルの評価
    y_pred = evaluate_model(model, X_test, y_test)

  else:

    update_model(model, scaler, df)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img alt=&#34;AOS2&#34; loading=&#34;lazy&#34; src=&#34;https://xainome-blog.pages.dev/posts/2024/07/stock-price-prediction-part-8/images/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88-2024-07-15-205739-1-1024x549.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>短期売買と分析力が向上しそうな株価予測をだらだらとやる part7</title>
      <link>https://xainome-blog.pages.dev/posts/2024/07/stock-price-prediction-part-7/</link>
      <pubDate>Sat, 06 Jul 2024 00:00:00 +0000</pubDate>
      <guid>https://xainome-blog.pages.dev/posts/2024/07/stock-price-prediction-part-7/</guid>
      <description>&lt;h2 id=&#34;前回のあらすじ&#34;&gt;前回のあらすじ&lt;/h2&gt;
&lt;p&gt;オシレーター系指標の説明変数を追加するコードを書きました。&lt;/p&gt;
&lt;h2 id=&#34;株価予測_コード&#34;&gt;株価予測_コード&lt;/h2&gt;
&lt;p&gt;今回やることは株価の予測になります。&lt;/p&gt;
&lt;p&gt;今回は1ファイルずつ読み込んで実行しています。ティッカーリストがあればティッカーごとにダウンロードしてきて加工する方法もあったのでいずれやります。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import pandas as pd
import numpy as np
import yfinance as yf
from sklearn.linear_model import SGDRegressor
from sklearn.metrics import mean_squared_error
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

dm_fol = &amp;#39;./datamart/&amp;#39;

import glob
stock_list = glob.glob(dm_fol + &amp;#34;*.parquet&amp;#34;)

def preprocess_data(df):

    df.sort_values(&amp;#39;Date&amp;#39;, inplace=True)
    # 日付を特徴量に変換
    df[&amp;#39;Year&amp;#39;] = df[&amp;#39;Date&amp;#39;].dt.year
    df[&amp;#39;Month&amp;#39;] = df[&amp;#39;Date&amp;#39;].dt.month
    df[&amp;#39;Day&amp;#39;] = df[&amp;#39;Date&amp;#39;].dt.day
    df[&amp;#39;Weekday&amp;#39;] = df[&amp;#39;Date&amp;#39;].dt.weekday
    df[&amp;#39;Quarter&amp;#39;] = df[&amp;#39;Date&amp;#39;].dt.quarter

    # 周期成分のエンコーディング
    df[&amp;#39;Month_sin&amp;#39;] = np.sin(2 * np.pi * df[&amp;#39;Month&amp;#39;] / 12)
    df[&amp;#39;Month_cos&amp;#39;] = np.cos(2 * np.pi * df[&amp;#39;Month&amp;#39;] / 12)
    df[&amp;#39;Day_sin&amp;#39;] = np.sin(2 * np.pi * df[&amp;#39;Day&amp;#39;] / 31)
    df[&amp;#39;Day_cos&amp;#39;] = np.cos(2 * np.pi * df[&amp;#39;Day&amp;#39;] / 31)
    df[&amp;#39;Weekday_sin&amp;#39;] = np.sin(2 * np.pi * df[&amp;#39;Weekday&amp;#39;] / 7)
    df[&amp;#39;Weekday_cos&amp;#39;] = np.cos(2 * np.pi * df[&amp;#39;Weekday&amp;#39;] / 7)

    # 日付を削除
    df.drop(columns=[&amp;#39;symbol&amp;#39;,&amp;#39;Date&amp;#39;], inplace=True)
    # &amp;#34;symbol&amp;#34;以外のobject型カラムをワンホットエンコーディング
    df = pd.get_dummies(df, columns=[col for col in df.select_dtypes(include=[&amp;#39;object&amp;#39;]).columns])

    # 全ての値が欠損している列を削除
    df.dropna(axis=1, how=&amp;#39;all&amp;#39;, inplace=True)

    # 値が欠損している行を削除
    df.dropna(axis=0, how=&amp;#39;any&amp;#39;, inplace=True)
    return df

def train_model(df):
    target = df[&amp;#39;Close&amp;#39;].shift(-1).dropna()
    features = df.drop(columns=[&amp;#39;Close&amp;#39;])
    features = features[:-1]

    # データのスケーリング
    scaler = StandardScaler()
    X = scaler.fit_transform(features.values)
    y = target.values
    
    # データを7:3に分割
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, shuffle=False)
    
    model = SGDRegressor(max_iter=1000, tol=1e-3)
    model.fit(X_train, y_train)
    
    return model, scaler, X_test, y_test

def evaluate_model(model, scaler, X_test, y_test):
    y_pred = model.predict(X_test)
    mse = mean_squared_error(y_test, y_pred)
    print(f&amp;#34;Mean Squared Error: {mse}&amp;#34;)
    plt.figure(figsize=(14, 7))
    plt.plot(y_test, label=&amp;#39;Actual&amp;#39;, color=&amp;#39;black&amp;#39;)
    plt.plot(y_pred, label=&amp;#39;Predicted&amp;#39;, color=&amp;#39;blue&amp;#39;)
    plt.title(&amp;#39;Actual vs Predicted Stock Prices&amp;#39;)
    plt.xlabel(&amp;#39;Sample&amp;#39;)
    plt.ylabel(&amp;#39;Price&amp;#39;)
    plt.legend()
    plt.show()

def predict_next_day(model, scaler, df):
    last_row = df.iloc[-1, :-1].values.reshape(1, -1)
    df.iloc[-1, :-1].to_csv(&amp;#34;test.csv&amp;#34;)
    last_row_scaled = scaler.transform(last_row)
    next_day_prediction = model.predict(last_row_scaled)
    print(f&amp;#34;Next Day Prediction: {next_day_prediction[0]}&amp;#34;)

# 初回データロードとモデル学習
# start_date = &amp;#39;1990-04-01&amp;#39;
# end_date = &amp;#39;2024-07-03&amp;#39;
# symbols = [&amp;#39;AAPL&amp;#39;, &amp;#39;MSFT&amp;#39;, &amp;#39;GOOGL&amp;#39;]
for stock_data in stock_list:
  df = pd.read_parquet(stock_data)
  df = preprocess_data(df)
  model, scaler, X_test, y_test = train_model(df)

  # モデルの評価
  evaluate_model(model, scaler, X_test, y_test)

  # 次の日の予測
  predict_next_day(model, scaler, df)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;コードの内容&#34;&gt;コードの内容&lt;/h2&gt;
&lt;p&gt;やったこととしては日付を特徴量に変換しました。&lt;/p&gt;</description>
    </item>
    <item>
      <title>短期売買と分析力が向上しそうな株価予測をだらだらとやる part6</title>
      <link>https://xainome-blog.pages.dev/posts/2024/07/stock-price-prediction-part-6/</link>
      <pubDate>Tue, 02 Jul 2024 00:00:00 +0000</pubDate>
      <guid>https://xainome-blog.pages.dev/posts/2024/07/stock-price-prediction-part-6/</guid>
      <description>&lt;h2 id=&#34;前回のあらすじ&#34;&gt;前回のあらすじ&lt;/h2&gt;
&lt;p&gt;トレンド系指標の説明変数を追加したところで終わりました。&lt;/p&gt;
&lt;h2 id=&#34;オシレーター系指標&#34;&gt;オシレーター系指標&lt;/h2&gt;
&lt;p&gt;今回作成したのは&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;RSI&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;RCI&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;移動平均線乖離率&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;スローストキャスティクス&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;モメンタムとROC&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MFI&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CCI&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ギャップ&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ヒストリカル・ボラティリティ&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;def rsi(df):
  # RSIの計算
  window = 14

  # 終値の変化
  df[&amp;#39;Change&amp;#39;] = df[&amp;#39;Adj Close&amp;#39;].diff()

  # 上昇幅と下落幅の計算
  df[&amp;#39;Gain&amp;#39;] = np.where(df[&amp;#39;Change&amp;#39;] &amp;gt; 0, df[&amp;#39;Change&amp;#39;], 0)
  df[&amp;#39;Loss&amp;#39;] = np.where(df[&amp;#39;Change&amp;#39;] &amp;lt; 0, -df[&amp;#39;Change&amp;#39;], 0)

  # 平均上昇幅と平均下落幅の計算
  df[&amp;#39;Avg_Gain&amp;#39;] = df[&amp;#39;Gain&amp;#39;].rolling(window=window).mean()
  df[&amp;#39;Avg_Loss&amp;#39;] = df[&amp;#39;Loss&amp;#39;].rolling(window=window).mean()

  # 相対力（RS）の計算
  df[&amp;#39;RS&amp;#39;] = df[&amp;#39;Avg_Gain&amp;#39;] / df[&amp;#39;Avg_Loss&amp;#39;]

  # RSIの計算
  df[&amp;#39;RSI&amp;#39;] = 100 - (100 / (1 + df[&amp;#39;RS&amp;#39;]))

  # シグナルの判定
  df[&amp;#39;rsi_Signal&amp;#39;] = np.where(df[&amp;#39;RSI&amp;#39;] &amp;gt; 70, &amp;#39;Sell&amp;#39;, np.where(df[&amp;#39;RSI&amp;#39;] &amp;lt; 30, &amp;#39;Buy&amp;#39;, np.nan))

def calculate_rci(series):
    n = len(series)
    date_rank = np.arange(1, n + 1)
    price_rank = series.rank().values
    ssd = np.sum((date_rank - price_rank) ** 2)
    rci = 1 - (6 * ssd) / (n * (n ** 2 - 1))
    return rci

def rci(df):
  # RCIの計算
  window = 14

  df[&amp;#39;RCI&amp;#39;] = df[&amp;#39;Adj Close&amp;#39;].rolling(window=window).apply(calculate_rci, raw=False)

  # シグナルの判定（RSIと同様に70以上で売りシグナル、30以下で買いシグナル）
  df[&amp;#39;rci_Signal&amp;#39;] = np.where(df[&amp;#39;RCI&amp;#39;] &amp;gt; 70, &amp;#39;Sell&amp;#39;, np.where(df[&amp;#39;RCI&amp;#39;] &amp;lt; 30, &amp;#39;Buy&amp;#39;, np.nan))

def madp(df):
  # 乖離率の計算
  df[&amp;#39;madp&amp;#39;] = (df[&amp;#39;Adj Close&amp;#39;] - df[&amp;#39;SMA&amp;#39;]) / df[&amp;#39;SMA&amp;#39;] * 100

  # シグナルの判定
  df[&amp;#39;madp_Signal&amp;#39;] = np.nan
  threshold = 5  # 閾値の設定

  for i in range(1, len(df)):
      if df[&amp;#39;madp&amp;#39;].iloc[i-1] &amp;lt; -threshold and df[&amp;#39;madp&amp;#39;].iloc[i] &amp;gt; df[&amp;#39;madp&amp;#39;].iloc[i-1]:
          df.at[df.index[i], &amp;#39;madp_Signal&amp;#39;] = &amp;#39;Buy&amp;#39;
      elif df[&amp;#39;madp&amp;#39;].iloc[i-1] &amp;gt; threshold and df[&amp;#39;madp&amp;#39;].iloc[i] &amp;lt; df[&amp;#39;madp&amp;#39;].iloc[i-1]:
          df.at[df.index[i], &amp;#39;madp_Signal&amp;#39;] = &amp;#39;Sell&amp;#39;

def stochastic(df):
  # %Kの計算
  window = 14
  df[&amp;#39;14-High&amp;#39;] = df[&amp;#39;High&amp;#39;].rolling(window=window).max()
  df[&amp;#39;14-Low&amp;#39;] = df[&amp;#39;Low&amp;#39;].rolling(window=window).min()
  df[&amp;#39;%K&amp;#39;] = (df[&amp;#39;Adj Close&amp;#39;] - df[&amp;#39;14-Low&amp;#39;]) / (df[&amp;#39;14-High&amp;#39;] - df[&amp;#39;14-Low&amp;#39;]) * 100

  # スロー%Dの計算
  df[&amp;#39;slow%D&amp;#39;] = df[&amp;#39;%K&amp;#39;].rolling(window=3).mean()

  # シグナルの判定
  df[&amp;#39;sto_Signal&amp;#39;] = np.nan
  for i in range(1, len(df)):
      if df[&amp;#39;slow%D&amp;#39;].iloc[i-1] &amp;lt; 20 and df[&amp;#39;slow%D&amp;#39;].iloc[i] &amp;gt; df[&amp;#39;slow%D&amp;#39;].iloc[i-1]:
          df.at[df.index[i], &amp;#39;sto_Signal&amp;#39;] = &amp;#39;Buy&amp;#39;
      elif df[&amp;#39;slow%D&amp;#39;].iloc[i-1] &amp;gt; 80 and df[&amp;#39;slow%D&amp;#39;].iloc[i] &amp;lt; df[&amp;#39;slow%D&amp;#39;].iloc[i-1]:
          df.at[df.index[i], &amp;#39;sto_Signal&amp;#39;] = &amp;#39;Sell&amp;#39;

def momentum_roc(df):
  # モメンタムとROCの計算
  window = 14
  df[&amp;#39;Momentum&amp;#39;] = df[&amp;#39;Adj Close&amp;#39;] - df[&amp;#39;Adj Close&amp;#39;].shift(window)
  df[&amp;#39;ROC&amp;#39;] = ((df[&amp;#39;Adj Close&amp;#39;] - df[&amp;#39;Adj Close&amp;#39;].shift(window)) / df[&amp;#39;Adj Close&amp;#39;].shift(window)) * 100

  # トレンドの判定
  df[&amp;#39;Momentum_Trend&amp;#39;] = np.where(df[&amp;#39;Momentum&amp;#39;] &amp;gt; 0, &amp;#39;Uptrend&amp;#39;, np.where(df[&amp;#39;Momentum&amp;#39;] &amp;lt; 0, &amp;#39;Downtrend&amp;#39;, &amp;#39;Neutral&amp;#39;))
  df[&amp;#39;ROC_Trend&amp;#39;] = np.where(df[&amp;#39;ROC&amp;#39;] &amp;gt; 0, &amp;#39;Uptrend&amp;#39;, np.where(df[&amp;#39;ROC&amp;#39;] &amp;lt; 0, &amp;#39;Downtrend&amp;#39;, &amp;#39;Neutral&amp;#39;))

def mfi(df):
  # 典型価格（TP）の計算
  df[&amp;#39;TP&amp;#39;] = (df[&amp;#39;High&amp;#39;] + df[&amp;#39;Low&amp;#39;] + df[&amp;#39;Adj Close&amp;#39;]) / 3

  # マネーフロー（Raw Money Flow）の計算
  df[&amp;#39;Raw Money Flow&amp;#39;] = df[&amp;#39;TP&amp;#39;] * df[&amp;#39;Volume&amp;#39;]

  # ポジティブマネーフローとネガティブマネーフローの計算
  df[&amp;#39;Positive Money Flow&amp;#39;] = np.where(df[&amp;#39;TP&amp;#39;] &amp;gt; df[&amp;#39;TP&amp;#39;].shift(1), df[&amp;#39;Raw Money Flow&amp;#39;], 0)
  df[&amp;#39;Negative Money Flow&amp;#39;] = np.where(df[&amp;#39;TP&amp;#39;] &amp;lt; df[&amp;#39;TP&amp;#39;].shift(1), df[&amp;#39;Raw Money Flow&amp;#39;], 0)

  # 14期間の合計
  window = 14
  df[&amp;#39;Positive Money Flow Sum&amp;#39;] = df[&amp;#39;Positive Money Flow&amp;#39;].rolling(window=window).sum()
  df[&amp;#39;Negative Money Flow Sum&amp;#39;] = df[&amp;#39;Negative Money Flow&amp;#39;].rolling(window=window).sum()

  # MFIの計算
  df[&amp;#39;Money Flow Ratio&amp;#39;] = df[&amp;#39;Positive Money Flow Sum&amp;#39;] / df[&amp;#39;Negative Money Flow Sum&amp;#39;]
  df[&amp;#39;MFI&amp;#39;] = 100 - (100 / (1 + df[&amp;#39;Money Flow Ratio&amp;#39;]))

  # シグナルの判定
  df[&amp;#39;mfi_Signal&amp;#39;] = np.nan
  for i in range(1, len(df)):
      if df[&amp;#39;MFI&amp;#39;].iloc[i-1] &amp;lt; 20 and df[&amp;#39;MFI&amp;#39;].iloc[i] &amp;gt; df[&amp;#39;MFI&amp;#39;].iloc[i-1]:
          df.at[df.index[i], &amp;#39;mfi_Signal&amp;#39;] = &amp;#39;Buy&amp;#39;
      elif df[&amp;#39;MFI&amp;#39;].iloc[i-1] &amp;gt; 80 and df[&amp;#39;MFI&amp;#39;].iloc[i] &amp;lt; df[&amp;#39;MFI&amp;#39;].iloc[i-1]:
          df.at[df.index[i], &amp;#39;mfi_Signal&amp;#39;] = &amp;#39;Sell&amp;#39;

def cci(df):
  # 典型価格（TP）の計算
  df[&amp;#39;TP&amp;#39;] = (df[&amp;#39;High&amp;#39;] + df[&amp;#39;Low&amp;#39;] + df[&amp;#39;Adj Close&amp;#39;]) / 3

  # 単純移動平均（SMA）の計算
  window = 20
  df[&amp;#39;cci_SMA&amp;#39;] = df[&amp;#39;TP&amp;#39;].rolling(window=window).mean()

  # 偏差（Mean Deviation）の計算
  df[&amp;#39;Mean Deviation&amp;#39;] = df[&amp;#39;TP&amp;#39;].rolling(window=window).apply(lambda x: np.mean(np.abs(x - x.mean())), raw=True)

  # CCIの計算
  df[&amp;#39;CCI&amp;#39;] = (df[&amp;#39;TP&amp;#39;] - df[&amp;#39;cci_SMA&amp;#39;]) / (0.015 * df[&amp;#39;Mean Deviation&amp;#39;])

  # シグナルの判定
  df[&amp;#39;cci_Signal&amp;#39;] = np.nan
  for i in range(1, len(df)):
      if df[&amp;#39;CCI&amp;#39;].iloc[i-1] &amp;lt; -100 and df[&amp;#39;CCI&amp;#39;].iloc[i] &amp;gt; df[&amp;#39;CCI&amp;#39;].iloc[i-1]:
          df.at[df.index[i], &amp;#39;cci_Signal&amp;#39;] = &amp;#39;Buy&amp;#39;
      elif df[&amp;#39;CCI&amp;#39;].iloc[i-1] &amp;gt; 100 and df[&amp;#39;CCI&amp;#39;].iloc[i] &amp;lt; df[&amp;#39;CCI&amp;#39;].iloc[i-1]:
          df.at[df.index[i], &amp;#39;cci_Signal&amp;#39;] = &amp;#39;Sell&amp;#39;

def gap(df):
# ギャップアップとギャップダウンの計算
  df[&amp;#39;Previous Close&amp;#39;] = df[&amp;#39;Adj Close&amp;#39;].shift(1)
  df[&amp;#39;Gap&amp;#39;] = df[&amp;#39;Open&amp;#39;] - df[&amp;#39;Previous Close&amp;#39;]
  df[&amp;#39;Gap Type&amp;#39;] = np.where(df[&amp;#39;Gap&amp;#39;] &amp;gt; 0, &amp;#39;Gap Up&amp;#39;, np.where(df[&amp;#39;Gap&amp;#39;] &amp;lt; 0, &amp;#39;Gap Down&amp;#39;, &amp;#39;No Gap&amp;#39;))

def hv(df):
  # ヒストリカル・ボラティリティの計算
  window = 20

  # リターンの計算
  df[&amp;#39;Return&amp;#39;] = np.log(df[&amp;#39;Adj Close&amp;#39;] / df[&amp;#39;Adj Close&amp;#39;].shift(1))

  # 標準偏差の計算
  df[&amp;#39;HV&amp;#39;] = df[&amp;#39;Return&amp;#39;].rolling(window=window).std() * np.sqrt(252)

  # df[&amp;#39;RCI&amp;#39;] = df[&amp;#39;Adj Close&amp;#39;].rolling(window=window).apply(calculate_rci, raw=False)

  # シグナルの判定
  df[&amp;#39;hv_Signal&amp;#39;] = np.nan
  for i in range(1, len(df)):
      if df[&amp;#39;RCI&amp;#39;].iloc[i-1] &amp;lt; -80 and df[&amp;#39;RCI&amp;#39;].iloc[i] &amp;gt; df[&amp;#39;RCI&amp;#39;].iloc[i-1]:
          df.at[df.index[i], &amp;#39;hv_Signal&amp;#39;] = &amp;#39;Buy&amp;#39;
      elif df[&amp;#39;RCI&amp;#39;].iloc[i-1] &amp;gt; 80 and df[&amp;#39;RCI&amp;#39;].iloc[i] &amp;lt; df[&amp;#39;RCI&amp;#39;].iloc[i-1]:
          df.at[df.index[i], &amp;#39;hv_Signal&amp;#39;] = &amp;#39;Sell&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;次回は予測をしていこうと思います。&lt;/p&gt;</description>
    </item>
    <item>
      <title>短期売買と分析力が向上しそうな株価予測をだらだらとやる part5</title>
      <link>https://xainome-blog.pages.dev/posts/2024/06/stock-price-prediction-part-5/</link>
      <pubDate>Tue, 25 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://xainome-blog.pages.dev/posts/2024/06/stock-price-prediction-part-5/</guid>
      <description>&lt;h2 id=&#34;前回のあらすじ&#34;&gt;前回のあらすじ&lt;/h2&gt;
&lt;p&gt;オシレータ系指標とその他の指標について確認しました。&lt;/p&gt;
&lt;p&gt;今回は実際にコードに落とし込んで、グラフで見てみようと思います。&lt;/p&gt;
&lt;h2 id=&#34;作成したコード&#34;&gt;作成したコード&lt;/h2&gt;
&lt;p&gt;今回はとりあえずトレンド系指標の説明変数を見てみたいと思います。クラスかはまだやってないので、いずれやっておきます。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os

out_fol = &amp;#34;./stock_data/&amp;#34;
import glob
stock_list = glob.glob(out_fol + &amp;#34;*.csv&amp;#34;)

def moveing_average(df):
  # 単純移動平均線（SMA）の計算
  df[&amp;#39;SMA&amp;#39;] = df[&amp;#39;Adj Close&amp;#39;].rolling(window=20).mean()
  # 指数平滑移動平均線（EMA）の計算
  df[&amp;#39;EMA&amp;#39;] = df[&amp;#39;Adj Close&amp;#39;].ewm(span=20, adjust=False).mean()
  # グラフのプロット
  plt.figure(figsize=(14, 7))
  plt.plot(df[&amp;#39;Adj Close&amp;#39;], label=&amp;#39;Close Price&amp;#39;, color=&amp;#39;black&amp;#39;)
  plt.plot(df[&amp;#39;SMA&amp;#39;], label=&amp;#39;20-Day SMA&amp;#39;, color=&amp;#39;blue&amp;#39;)
  plt.plot(df[&amp;#39;EMA&amp;#39;], label=&amp;#39;20-Day EMA&amp;#39;, color=&amp;#39;red&amp;#39;)

  plt.title(&amp;#39;Stock Price with 20-Day SMA and 20-Day EMA&amp;#39;)
  plt.xlabel(&amp;#39;Date&amp;#39;)
  plt.ylabel(&amp;#39;Price&amp;#39;)
  plt.legend()
  plt.grid(True)
  plt.show()

def macd(df):
  # 短期EMA（12日）の計算
  short_ema = df[&amp;#39;Adj Close&amp;#39;].ewm(span=12, adjust=False).mean()

  # 長期EMA（26日）の計算
  long_ema = df[&amp;#39;Adj Close&amp;#39;].ewm(span=26, adjust=False).mean()

  # MACDラインの計算
  df[&amp;#39;MACD&amp;#39;] = short_ema - long_ema

  # シグナルラインの計算（9日間のMACDのEMA）
  df[&amp;#39;Signal_Line&amp;#39;] = df[&amp;#39;MACD&amp;#39;].ewm(span=9, adjust=False).mean()

  # MACDヒストグラムの計算
  df[&amp;#39;MACD_Histogram&amp;#39;] = df[&amp;#39;MACD&amp;#39;] - df[&amp;#39;Signal_Line&amp;#39;]
  # グラフのプロット
  plt.figure(figsize=(14, 7))
  # 終値のプロット
  plt.subplot(2, 1, 1)
  plt.plot(df[&amp;#39;Close&amp;#39;], label=&amp;#39;Close Price&amp;#39;, color=&amp;#39;black&amp;#39;)
  plt.title(&amp;#39;Stock Price and MACD&amp;#39;)
  plt.xlabel(&amp;#39;Date&amp;#39;)
  plt.ylabel(&amp;#39;Price&amp;#39;)
  plt.legend()

  # MACDとシグナルラインのプロット
  plt.subplot(2, 1, 2)
  plt.plot(df[&amp;#39;MACD&amp;#39;], label=&amp;#39;MACD&amp;#39;, color=&amp;#39;blue&amp;#39;)
  plt.plot(df[&amp;#39;Signal_Line&amp;#39;], label=&amp;#39;Signal Line&amp;#39;, color=&amp;#39;red&amp;#39;)
  plt.bar(df.index, df[&amp;#39;MACD_Histogram&amp;#39;], label=&amp;#39;MACD Histogram&amp;#39;, color=&amp;#39;gray&amp;#39;)
  plt.xlabel(&amp;#39;Date&amp;#39;)
  plt.ylabel(&amp;#39;Value&amp;#39;)
  plt.legend()

  plt.tight_layout()
  plt.show()

def bollinger_bands(df):
  # 中央バンド（20日間の単純移動平均線）の計算
  df[&amp;#39;Middle_Band&amp;#39;] = df[&amp;#39;Adj Close&amp;#39;].rolling(window=20).mean()

  # 標準偏差の計算
  df[&amp;#39;STD&amp;#39;] = df[&amp;#39;Adj Close&amp;#39;].rolling(window=20).std()

  # 上部バンドの計算
  df[&amp;#39;Upper_Band&amp;#39;] = df[&amp;#39;Middle_Band&amp;#39;] + (2 * df[&amp;#39;STD&amp;#39;])

  # 下部バンドの計算
  df[&amp;#39;Lower_Band&amp;#39;] = df[&amp;#39;Middle_Band&amp;#39;] - (2 * df[&amp;#39;STD&amp;#39;])

  # 過熱感の判断
  df[&amp;#39;bands_buy_flg&amp;#39;] = df[&amp;#39;Adj Close&amp;#39;] &amp;gt; df[&amp;#39;Lower_Band&amp;#39;]
  df[&amp;#39;bands_sell_flg&amp;#39;] = df[&amp;#39;Adj Close&amp;#39;] &amp;lt; df[&amp;#39;Upper_Band&amp;#39;]
  # グラフのプロット
  plt.figure(figsize=(14, 7))
  plt.plot(df[&amp;#39;Adj Close&amp;#39;], label=&amp;#39;Close Price&amp;#39;, color=&amp;#39;black&amp;#39;)
  plt.plot(df[&amp;#39;Middle_Band&amp;#39;], label=&amp;#39;Middle Band (SMA 20)&amp;#39;, color=&amp;#39;blue&amp;#39;)
  plt.plot(df[&amp;#39;Upper_Band&amp;#39;], label=&amp;#39;Upper Band (Middle + 2*STD)&amp;#39;, color=&amp;#39;red&amp;#39;)
  plt.plot(df[&amp;#39;Lower_Band&amp;#39;], label=&amp;#39;Lower Band (Middle - 2*STD)&amp;#39;, color=&amp;#39;green&amp;#39;)

  plt.fill_between(df.index, df[&amp;#39;Upper_Band&amp;#39;], df[&amp;#39;Lower_Band&amp;#39;], color=&amp;#39;grey&amp;#39;, alpha=0.1)
  plt.scatter(df.index[df[&amp;#39;bands_buy_flg&amp;#39;]], df[&amp;#39;Adj Close&amp;#39;][df[&amp;#39;bands_buy_flg&amp;#39;]], label=&amp;#39;bands_buy_flg&amp;#39;, color=&amp;#39;red&amp;#39;, marker=&amp;#39;o&amp;#39;)
  plt.scatter(df.index[df[&amp;#39;bands_sell_flg&amp;#39;]], df[&amp;#39;Adj Close&amp;#39;][df[&amp;#39;bands_sell_flg&amp;#39;]], label=&amp;#39;bands_sell_flg&amp;#39;, color=&amp;#39;green&amp;#39;, marker=&amp;#39;o&amp;#39;)

  plt.title(&amp;#39;Bollinger Bands with bands_buy_flg and bands_sell_flg Signals&amp;#39;)
  plt.xlabel(&amp;#39;Date&amp;#39;)
  plt.ylabel(&amp;#39;Price&amp;#39;)
  plt.legend()
  plt.grid(True)
  plt.show()

def ichimoku_kinko_hyo(df):
  # 転換線（過去9日間の最高値と最安値の平均値）
  df[&amp;#39;Tenkan_sen&amp;#39;] = (df[&amp;#39;High&amp;#39;].rolling(window=9).max() + df[&amp;#39;Low&amp;#39;].rolling(window=9).min()) / 2

  # 基準線（過去26日間の最高値と最安値の平均値）
  df[&amp;#39;Kijun_sen&amp;#39;] = (df[&amp;#39;High&amp;#39;].rolling(window=26).max() + df[&amp;#39;Low&amp;#39;].rolling(window=26).min()) / 2

  # 先行スパン1（転換線と基準線の平均値を26日先にプロット）
  df[&amp;#39;Senkou_Span_A&amp;#39;] = ((df[&amp;#39;Tenkan_sen&amp;#39;] + df[&amp;#39;Kijun_sen&amp;#39;]) / 2).shift(26)

  # 先行スパン2（過去52日間の最高値と最安値の平均値を26日先にプロット）
  df[&amp;#39;Senkou_Span_B&amp;#39;] = ((df[&amp;#39;High&amp;#39;].rolling(window=52).max() + df[&amp;#39;Low&amp;#39;].rolling(window=52).min()) / 2).shift(26)

  # 遅行スパン（現在の終値を26日遅らせてプロット）
  df[&amp;#39;Chikou_Span&amp;#39;] = df[&amp;#39;Adj Close&amp;#39;].shift(-26)

  # 雲の上・下の判定とシグナル
  df[&amp;#39;Signal&amp;#39;] = np.where(df[&amp;#39;Tenkan_sen&amp;#39;] &amp;gt; df[&amp;#39;Kijun_sen&amp;#39;], &amp;#39;Buy&amp;#39;, &amp;#39;Sell&amp;#39;)
  df[&amp;#39;Trend&amp;#39;] = np.where(df[&amp;#39;Adj Close&amp;#39;] &amp;gt; df[[&amp;#39;Senkou_Span_A&amp;#39;, &amp;#39;Senkou_Span_B&amp;#39;]].max(axis=1), &amp;#39;Uptrend&amp;#39;,
                        np.where(df[&amp;#39;Adj Close&amp;#39;] &amp;lt; df[[&amp;#39;Senkou_Span_A&amp;#39;, &amp;#39;Senkou_Span_B&amp;#39;]].min(axis=1), &amp;#39;Downtrend&amp;#39;, &amp;#39;Neutral&amp;#39;))
  # グラフのプロット
  plt.figure(figsize=(14, 7))
  plt.plot(df[&amp;#39;Adj Close&amp;#39;], label=&amp;#39;Close Price&amp;#39;, color=&amp;#39;black&amp;#39;)
  plt.plot(df[&amp;#39;Tenkan_sen&amp;#39;], label=&amp;#39;Tenkan-sen (Conversion Line)&amp;#39;, color=&amp;#39;blue&amp;#39;)
  plt.plot(df[&amp;#39;Kijun_sen&amp;#39;], label=&amp;#39;Kijun-sen (Base Line)&amp;#39;, color=&amp;#39;red&amp;#39;)
  plt.plot(df[&amp;#39;Senkou_Span_A&amp;#39;], label=&amp;#39;Senkou Span A (Leading Span 1)&amp;#39;, color=&amp;#39;green&amp;#39;)
  plt.plot(df[&amp;#39;Senkou_Span_B&amp;#39;], label=&amp;#39;Senkou Span B (Leading Span 2)&amp;#39;, color=&amp;#39;orange&amp;#39;)
  plt.plot(df[&amp;#39;Chikou_Span&amp;#39;], label=&amp;#39;Chikou Span (Lagging Span)&amp;#39;, color=&amp;#39;purple&amp;#39;)

  # 先行スパンの領域を塗りつぶす
  plt.fill_between(df.index, df[&amp;#39;Senkou_Span_A&amp;#39;], df[&amp;#39;Senkou_Span_B&amp;#39;], where=df[&amp;#39;Senkou_Span_A&amp;#39;] &amp;gt;= df[&amp;#39;Senkou_Span_B&amp;#39;], color=&amp;#39;lightgreen&amp;#39;, alpha=0.5)
  plt.fill_between(df.index, df[&amp;#39;Senkou_Span_A&amp;#39;], df[&amp;#39;Senkou_Span_B&amp;#39;], where=df[&amp;#39;Senkou_Span_A&amp;#39;] &amp;lt; df[&amp;#39;Senkou_Span_B&amp;#39;], color=&amp;#39;lightcoral&amp;#39;, alpha=0.5)

  plt.title(&amp;#39;Ichimoku Kinko Hyo (Ichimoku Cloud)&amp;#39;)
  plt.xlabel(&amp;#39;Date&amp;#39;)
  plt.ylabel(&amp;#39;Price&amp;#39;)
  plt.legend()
  plt.grid(True)
  plt.show()

  # シグナルとトレンドの表示
  print(df[[&amp;#39;Adj Close&amp;#39;, &amp;#39;Tenkan_sen&amp;#39;, &amp;#39;Kijun_sen&amp;#39;, &amp;#39;Signal&amp;#39;, &amp;#39;Trend&amp;#39;]].tail(30))

def directional_movement_index(df):
  # True Range（TR）の計算
  df[&amp;#39;TR&amp;#39;] = df[[&amp;#39;High&amp;#39;, &amp;#39;Low&amp;#39;, &amp;#39;Adj Close&amp;#39;]].apply(lambda x: max(x[&amp;#39;High&amp;#39;] - x[&amp;#39;Low&amp;#39;], abs(x[&amp;#39;High&amp;#39;] - x[&amp;#39;Adj Close&amp;#39;]), abs(x[&amp;#39;Low&amp;#39;] - x[&amp;#39;Adj Close&amp;#39;])), axis=1)

  # +DMと-DMの計算
  df[&amp;#39;+DM&amp;#39;] = df[&amp;#39;High&amp;#39;].diff().apply(lambda x: x if x &amp;gt; 0 else 0)
  df[&amp;#39;-DM&amp;#39;] = df[&amp;#39;Low&amp;#39;].diff().apply(lambda x: -x if x &amp;lt; 0 else 0)

  # 14期間のTR、+DM、-DMの合計
  df[&amp;#39;TR14&amp;#39;] = df[&amp;#39;TR&amp;#39;].rolling(window=14).sum()
  df[&amp;#39;+DM14&amp;#39;] = df[&amp;#39;+DM&amp;#39;].rolling(window=14).sum()
  df[&amp;#39;-DM14&amp;#39;] = df[&amp;#39;-DM&amp;#39;].rolling(window=14).sum()

  # +DIと-DIの計算
  df[&amp;#39;+DI14&amp;#39;] = 100 * (df[&amp;#39;+DM14&amp;#39;] / df[&amp;#39;TR14&amp;#39;])
  df[&amp;#39;-DI14&amp;#39;] = 100 * (df[&amp;#39;-DM14&amp;#39;] / df[&amp;#39;TR14&amp;#39;])

  # DXの計算
  df[&amp;#39;DX&amp;#39;] = 100 * (abs(df[&amp;#39;+DI14&amp;#39;] - df[&amp;#39;-DI14&amp;#39;]) / (df[&amp;#39;+DI14&amp;#39;] + df[&amp;#39;-DI14&amp;#39;]))

  # ADXの計算
  df[&amp;#39;ADX&amp;#39;] = df[&amp;#39;DX&amp;#39;].rolling(window=14).mean()

  # シグナルとトレンド強度の判定
  df[&amp;#39;Signal&amp;#39;] = np.where(df[&amp;#39;+DI14&amp;#39;] &amp;gt; df[&amp;#39;-DI14&amp;#39;], &amp;#39;Buy&amp;#39;, &amp;#39;Sell&amp;#39;)
  df[&amp;#39;Trend_Strength&amp;#39;] = np.where(df[&amp;#39;ADX&amp;#39;] &amp;gt;= 25, &amp;#39;Strong&amp;#39;, &amp;#39;Weak&amp;#39;)

  # ADXのトレンド（前日と比べて上昇または下降を判定）
  df[&amp;#39;ADX_Trend&amp;#39;] = df[&amp;#39;ADX&amp;#39;].diff().apply(lambda x: &amp;#39;Uptrend&amp;#39; if x &amp;gt; 0 else &amp;#39;Downtrend&amp;#39; if x &amp;lt; 0 else &amp;#39;No Change&amp;#39;)
  # グラフのプロット
  plt.figure(figsize=(14, 7))

  plt.plot(df[&amp;#39;+DI14&amp;#39;], label=&amp;#39;+DI (Positive Directional Indicator)&amp;#39;, color=&amp;#39;green&amp;#39;)
  plt.plot(df[&amp;#39;-DI14&amp;#39;], label=&amp;#39;-DI (Negative Directional Indicator)&amp;#39;, color=&amp;#39;red&amp;#39;)
  plt.plot(df[&amp;#39;ADX&amp;#39;], label=&amp;#39;ADX (Average Directional Index)&amp;#39;, color=&amp;#39;blue&amp;#39;)

  plt.title(&amp;#39;DMI (Directional Movement Index)&amp;#39;)
  plt.xlabel(&amp;#39;Date&amp;#39;)
  plt.ylabel(&amp;#39;Value&amp;#39;)
  plt.legend()
  plt.grid(True)
  plt.show()

  # 結果の表示
  print(df[[&amp;#39;+DI14&amp;#39;, &amp;#39;-DI14&amp;#39;, &amp;#39;ADX&amp;#39;, &amp;#39;Signal&amp;#39;, &amp;#39;Trend_Strength&amp;#39;]].tail(30))

def parabolic(df):
  # パラボリックSARの計算
  df[&amp;#39;SAR&amp;#39;] = np.nan
  df[&amp;#39;EP&amp;#39;] = np.nan
  df[&amp;#39;AF&amp;#39;] = np.nan

  # 初期値設定
  initial_trend = &amp;#39;up&amp;#39; if df[&amp;#39;Adj Close&amp;#39;].iloc[1] &amp;gt; df[&amp;#39;Adj Close&amp;#39;].iloc[0] else &amp;#39;down&amp;#39;
  initial_AF = 0.02
  max_AF = 0.2

  # 初期SAR、EP、AFの設定
  df.at[df.index[1], &amp;#39;SAR&amp;#39;] = df[&amp;#39;Low&amp;#39;].iloc[0] if initial_trend == &amp;#39;up&amp;#39; else df[&amp;#39;High&amp;#39;].iloc[0]
  df.at[df.index[1], &amp;#39;EP&amp;#39;] = df[&amp;#39;High&amp;#39;].iloc[1] if initial_trend == &amp;#39;up&amp;#39; else df[&amp;#39;Low&amp;#39;].iloc[1]
  df.at[df.index[1], &amp;#39;AF&amp;#39;] = initial_AF

  # パラボリックSARの計算ループ
  for i in range(2, len(df)):
      prev_SAR = df[&amp;#39;SAR&amp;#39;].iloc[i-1]
      prev_AF = df[&amp;#39;AF&amp;#39;].iloc[i-1]
      prev_EP = df[&amp;#39;EP&amp;#39;].iloc[i-1]
      trend = &amp;#39;up&amp;#39; if df[&amp;#39;Adj Close&amp;#39;].iloc[i-1] &amp;gt; prev_SAR else &amp;#39;down&amp;#39;
      
      if trend == &amp;#39;up&amp;#39;:
          SAR = prev_SAR + prev_AF * (prev_EP - prev_SAR)
          EP = max(prev_EP, df[&amp;#39;High&amp;#39;].iloc[i])
          AF = min(prev_AF + 0.02, max_AF) if df[&amp;#39;High&amp;#39;].iloc[i] &amp;gt; prev_EP else prev_AF
      else:
          SAR = prev_SAR - prev_AF * (prev_SAR - prev_EP)
          EP = min(prev_EP, df[&amp;#39;Low&amp;#39;].iloc[i])
          AF = min(prev_AF + 0.02, max_AF) if df[&amp;#39;Low&amp;#39;].iloc[i] &amp;lt; prev_EP else prev_AF
      
      # トレンドの反転
      if trend == &amp;#39;up&amp;#39; and df[&amp;#39;Low&amp;#39;].iloc[i] &amp;lt; SAR:
          SAR = prev_EP
          EP = df[&amp;#39;Low&amp;#39;].iloc[i]
          AF = initial_AF
          trend = &amp;#39;down&amp;#39;
      elif trend == &amp;#39;down&amp;#39; and df[&amp;#39;High&amp;#39;].iloc[i] &amp;gt; SAR:
          SAR = prev_EP
          EP = df[&amp;#39;High&amp;#39;].iloc[i]
          AF = initial_AF
          trend = &amp;#39;up&amp;#39;
      
      df.at[df.index[i], &amp;#39;SAR&amp;#39;] = SAR
      df.at[df.index[i], &amp;#39;EP&amp;#39;] = EP
      df.at[df.index[i], &amp;#39;AF&amp;#39;] = AF

  # シグナルの判定
  df[&amp;#39;Signal&amp;#39;] = np.where((df[&amp;#39;Adj Close&amp;#39;].shift(1) &amp;lt; df[&amp;#39;SAR&amp;#39;].shift(1)) &amp;amp; (df[&amp;#39;Adj Close&amp;#39;] &amp;gt; df[&amp;#39;SAR&amp;#39;]), &amp;#39;Sell&amp;#39;,
                          np.where((df[&amp;#39;Adj Close&amp;#39;].shift(1) &amp;gt; df[&amp;#39;SAR&amp;#39;].shift(1)) &amp;amp; (df[&amp;#39;Adj Close&amp;#39;] &amp;lt; df[&amp;#39;SAR&amp;#39;]), &amp;#39;Buy&amp;#39;, np.nan))

  # グラフのプロット
  plt.figure(figsize=(14, 7))
  plt.plot(df[&amp;#39;Adj Close&amp;#39;], label=&amp;#39;Close Price&amp;#39;, color=&amp;#39;black&amp;#39;)
  plt.plot(df[&amp;#39;SAR&amp;#39;], label=&amp;#39;Parabolic SAR&amp;#39;, linestyle=&amp;#39;dashed&amp;#39;, color=&amp;#39;blue&amp;#39;)
  plt.scatter(df[df[&amp;#39;Signal&amp;#39;] == &amp;#39;Buy&amp;#39;].index, df[df[&amp;#39;Signal&amp;#39;] == &amp;#39;Buy&amp;#39;][&amp;#39;Adj Close&amp;#39;], marker=&amp;#39;^&amp;#39;, color=&amp;#39;green&amp;#39;, label=&amp;#39;Buy Signal&amp;#39;, s=100)
  plt.scatter(df[df[&amp;#39;Signal&amp;#39;] == &amp;#39;Sell&amp;#39;].index, df[df[&amp;#39;Signal&amp;#39;] == &amp;#39;Sell&amp;#39;][&amp;#39;Adj Close&amp;#39;], marker=&amp;#39;v&amp;#39;, color=&amp;#39;red&amp;#39;, label=&amp;#39;Sell Signal&amp;#39;, s=100)

  plt.title(&amp;#39;Parabolic SAR with Buy and Sell Signals&amp;#39;)
  plt.xlabel(&amp;#39;Date&amp;#39;)
  plt.ylabel(&amp;#39;Price&amp;#39;)
  plt.legend()
  plt.grid(True)
  plt.show()

  # 結果の表示
  print(df[[&amp;#39;Adj Close&amp;#39;, &amp;#39;SAR&amp;#39;, &amp;#39;EP&amp;#39;, &amp;#39;AF&amp;#39;, &amp;#39;Signal&amp;#39;]].tail(30))

def Envelope(df):
  # エンベロープの計算
  percentage = 0.02  # 2% のエンベロープ
  df[&amp;#39;Upper Envelope&amp;#39;] = df[&amp;#39;SMA&amp;#39;] * (1 + percentage)
  df[&amp;#39;Lower Envelope&amp;#39;] = df[&amp;#39;SMA&amp;#39;] * (1 - percentage)
  # シグナルの判定
  df[&amp;#39;Signal&amp;#39;] = np.where(df[&amp;#39;Adj Close&amp;#39;] &amp;gt; df[&amp;#39;Upper Envelope&amp;#39;], &amp;#39;Sell&amp;#39;,
                          np.where(df[&amp;#39;Adj Close&amp;#39;] &amp;lt; df[&amp;#39;Lower Envelope&amp;#39;], &amp;#39;Buy&amp;#39;, np.nan))
  # グラフのプロット
  plt.figure(figsize=(14, 7))
  plt.plot(df[&amp;#39;Adj Close&amp;#39;], label=&amp;#39;Close Price&amp;#39;, color=&amp;#39;black&amp;#39;)
  plt.plot(df[&amp;#39;SMA&amp;#39;], label=&amp;#39;20-Day SMA&amp;#39;, color=&amp;#39;blue&amp;#39;)
  plt.plot(df[&amp;#39;Upper Envelope&amp;#39;], label=&amp;#39;Upper Envelope (SMA + 2%)&amp;#39;, color=&amp;#39;green&amp;#39;)
  plt.plot(df[&amp;#39;Lower Envelope&amp;#39;], label=&amp;#39;Lower Envelope (SMA - 2%)&amp;#39;, color=&amp;#39;red&amp;#39;)
  plt.scatter(df[df[&amp;#39;Signal&amp;#39;] == &amp;#39;Buy&amp;#39;].index, df[df[&amp;#39;Signal&amp;#39;] == &amp;#39;Buy&amp;#39;][&amp;#39;Adj Close&amp;#39;], marker=&amp;#39;^&amp;#39;, color=&amp;#39;green&amp;#39;, label=&amp;#39;Buy Signal&amp;#39;, s=100)
  plt.scatter(df[df[&amp;#39;Signal&amp;#39;] == &amp;#39;Sell&amp;#39;].index, df[df[&amp;#39;Signal&amp;#39;] == &amp;#39;Sell&amp;#39;][&amp;#39;Adj Close&amp;#39;], marker=&amp;#39;v&amp;#39;, color=&amp;#39;red&amp;#39;, label=&amp;#39;Sell Signal&amp;#39;, s=100)

  plt.title(&amp;#39;Envelopes with Buy and Sell Signals&amp;#39;)
  plt.xlabel(&amp;#39;Date&amp;#39;)
  plt.ylabel(&amp;#39;Price&amp;#39;)
  plt.legend()
  plt.grid(True)
  plt.show()

  # 結果の表示
  print(df[[&amp;#39;Adj Close&amp;#39;, &amp;#39;SMA&amp;#39;, &amp;#39;Upper Envelope&amp;#39;, &amp;#39;Lower Envelope&amp;#39;, &amp;#39;Signal&amp;#39;]].tail(30))

for stock_data in stock_list:
  # データフレームの作成
  df = pd.read_csv(stock_data)
  df[&amp;#39;Date&amp;#39;] = pd.to_datetime(df[&amp;#39;Date&amp;#39;])
  df.set_index(&amp;#39;Date&amp;#39;, inplace=True)

  moveing_average(df)
  macd(df)
  bollinger_bands(df)
  ichimoku_kinko_hyo(df)
  directional_movement_index(df)
  parabolic(df)
  Envelope(df)
  os.system(&amp;#34;pause&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;実行結果の確認&#34;&gt;実行結果の確認&lt;/h2&gt;
&lt;p&gt;コードの作成が完了したので実行してグラフを見てみます。実行したデータは&lt;strong&gt;Appleの20年分&lt;/strong&gt;と&lt;strong&gt;McDonald&amp;rsquo;sの1年分&lt;/strong&gt;になります。比較してみてみようと思います。&lt;/p&gt;</description>
    </item>
    <item>
      <title>短期売買と分析力が向上しそうな株価予測をだらだらとやる part4</title>
      <link>https://xainome-blog.pages.dev/posts/2024/06/stock-price-prediction-part-4/</link>
      <pubDate>Sat, 22 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://xainome-blog.pages.dev/posts/2024/06/stock-price-prediction-part-4/</guid>
      <description>&lt;h2 id=&#34;前回までのあらすじ&#34;&gt;前回までのあらすじ&lt;/h2&gt;
&lt;p&gt;株価の基本情報とトレント系指標について見てみました。&lt;/p&gt;
&lt;p&gt;今回はオシレーター系指標とその他について見ていこうと思います。&lt;/p&gt;
&lt;h2 id=&#34;技術分析データ&#34;&gt;技術分析データ&lt;/h2&gt;
&lt;h3 id=&#34;オシレーター系指標&#34;&gt;オシレーター系指標&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;RSI（相対力指数）&lt;/strong&gt;: 株価の過熱感を示す指標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;サイコロジカルライン&lt;/strong&gt;：一定期間の中で株価が上昇した日数の割合を示す。市場の投資家心理を測る指標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;RCI&lt;/strong&gt;：日付の順位と価格の順位の相関関係を示し、トレンドの強さを判断する指標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;移動平均線乖離率&lt;/strong&gt;：現在の株価と移動平均線との乖離を示しす。価格が移動平均線からどれだけ離れているかを判断する指標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;スローストキャスティクス&lt;/strong&gt;：ストキャスティクスの変動を滑らかにする。買われ過ぎや売られ過ぎの状態をより安定して示す指標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;モメンタムとROC&lt;/strong&gt;：モメンタムは価格の変化のスピードを示す。ROCは一定期間の価格変動率を示す指標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MFI&lt;/strong&gt;：出来高を加味したRSIに似た指標。買われ過ぎや売られ過ぎを判断するための指標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CCI&lt;/strong&gt;：価格と移動平均線の乖離を基に、トレンドの強さと異常値を判断する指標。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;その他&#34;&gt;&lt;strong&gt;その他&lt;/strong&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ヒストリカル・ボラティリティ&lt;/strong&gt;：過去の一定期間の価格変動の大きさを測定した指標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ギャップ（ギャップアップ、ギャップダウン）&lt;/strong&gt;：前日の終値と当日の始値の差で市場の初期のトレンド。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;レジスタンスライン&lt;/strong&gt;：株価が上昇する際に止まりやすい価格帯のこと。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;サポートライン&lt;/strong&gt;：株価が下落する際に止まりやすい価格帯のこと。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;軽く調べただけでこれくらいあるんですね。ローソク足を使ったりチャートの動きを使う指標もありましたが、今回は割愛します。他にも使いたいデータはありますので。&lt;/p&gt;
&lt;h2 id=&#34;技術分析データ_補足説明&#34;&gt;技術分析データ_補足説明&lt;/h2&gt;
&lt;h4 id=&#34;rsi-relative-strength-index-相対力指数&#34;&gt;RSI (Relative Strength Index, 相対力指数)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;株価の過熱感を示すオシレータータイプの指標で0~100の範囲で表す。14日間のデータを使用するのが一般的。
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;70以上&lt;/strong&gt;: 買われ過ぎ（Overbought）を示し、価格の反転を予想。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;30以下&lt;/strong&gt;: 売られ過ぎ（Oversold）を示し、価格の上昇を予想&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;rcirank-correlation-index&#34;&gt;RCI（Rank Correlation Index）&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;株価の日付順位と価格順位の相関を示す指標。トレンドの強さと方向を判断するために使用される。
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;各日付に順位を付ける（最新の日を1位とする）。各価格にも順位を付ける（高い価格を1位とする）。日付順位と価格順位の差を二乗して合計。RCIを計算。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;RCI=1 − 6∑(日付順位−価格順位)^2 / n(n^2−1)&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;移動平均線乖離率moving-average-convergence-divergence-macd&#34;&gt;移動平均線乖離率（Moving Average Convergence Divergence, MACD）&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;現在の株価と移動平均線との乖離を示す。価格が移動平均線からどれだけ離れているかを判断する指標。
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;移動平均線（通常は25日移動平均線）を計算。現在の株価と移動平均線の差を求める。その差を移動平均線で割り、百分率で表示する。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;乖離率=(現在の株価 − 移動平均線) / 移動平均線 ×100&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;乖離率が大きくマイナスに乖離した後に反転したら買いシグナル。乖離率が大きくプラスに乖離した後に反転したら売りシグナル&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;スローストキャスティクスslow-stochastic-oscillator&#34;&gt;スローストキャスティクス（Slow Stochastic Oscillator）&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ストキャスティクスの変動を滑らかにする。買われ過ぎや売られ過ぎの状態をより安定して示す指標&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ストキャスティクス&lt;/strong&gt;とは価格が特定の期間内でどれだけ高値と安値の間にあるかを示す指標。スロー以外にもファストがあるがここでは割愛。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;過去N日間（通常は14日間）の最高値と最安値を求める。現在の終値から最安値を引き、最高値と最安値の差で割る。この値に100を掛ける。%Kの値が出る。過去3日間の%Kラインの平均を求める。%Dの値が出る。％Dの単純移動平均を求める。Slow%Dの値が出る。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;スロー%Dが20以下から上昇し始めたら買いシグナル、スロー%Dが80以上から下落し始めたら売りシグナル。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;モメンタムmomentum&#34;&gt;モメンタム（Momentum）&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;一定期間内の価格変動の速度や勢いを示す指標。トレンドの強さや反転の可能性を判断する。プラスの値は上昇トレンドを、マイナスの値は下降トレンドを示す。
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;momentum = 現在の株価 - N期間前の株価&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;rocrate-of-change&#34;&gt;ROC（Rate of Change）&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;モメンタムを百分率で表したもので、トレンドの強さを評価する。プラスの値は上昇トレンドを、マイナスの値は下降トレンドを示す.。
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ROC = ((現在の株価 - N期間前の株価) / N期間前の株価) * 100&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;mfimoney-flow-index&#34;&gt;MFI（Money Flow Index）&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;出来高を加味したRSIに似た指標で、市場の過熱感を判断するために使用される。MFIが80以上で下落し始めたら売りシグナル、20以下で上昇し始めたら買いシグナル。
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;TP = H + L + C / 3 (TP: その日の取引価格の中央値、H: 最高値、L: 最安値、C: 終値)&lt;/strong&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>短期売買と分析力が向上しそうな株価予測をだらだらとやる part3</title>
      <link>https://xainome-blog.pages.dev/posts/2024/06/stock-price-prediction-part-3/</link>
      <pubDate>Wed, 19 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://xainome-blog.pages.dev/posts/2024/06/stock-price-prediction-part-3/</guid>
      <description>&lt;h2 id=&#34;株価予測_前回のおさらい&#34;&gt;株価予測_前回のおさらい&lt;/h2&gt;
&lt;p&gt;前回はティッカー一覧を取得できたので、株価を取得する方法を書きました。株価取得のコードはpart1とそこまで大きな差はないですが…&lt;/p&gt;
&lt;h2 id=&#34;株価予測_今回やること&#34;&gt;株価予測_今回やること&lt;/h2&gt;
&lt;p&gt;今回は予測の前に使用する変数について記載していきます。&lt;/p&gt;
&lt;p&gt;株価で取得した値は6つになります。&lt;/p&gt;
&lt;p&gt;ただし、トレーダーの一部の人は組み合わせて説明変数を作って使っていると思います。&lt;/p&gt;
&lt;p&gt;なのでChat-GPTに質問を投げた後、&lt;strong&gt;説明変数&lt;/strong&gt;を見ていこうと思います。&lt;/p&gt;
&lt;h2 id=&#34;株価とは&#34;&gt;&lt;strong&gt;株価とは&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;特定の時間における株式の市場価格を示します。この値は技術分析で使用される「移動平均線、RSI、MACD」などで使用されます。株価の情報は以下のデータが存在します。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;変数名&lt;/th&gt;
					&lt;th&gt;説明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Open（始値）&lt;/td&gt;
					&lt;td&gt;引日の最初の取引価格。ギャップを分析できる。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;High（高値）&lt;/td&gt;
					&lt;td&gt;取引日の中で最も高い取引価格。レジスタンラインの形成にも使用する。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Low（安値）&lt;/td&gt;
					&lt;td&gt;取引日の中で最も低い取引価格。サポート来の形成にも使用する。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Close（終値）&lt;/td&gt;
					&lt;td&gt;取引日の最後の取引価格。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Adj Close（調整後終値）&lt;/td&gt;
					&lt;td&gt;分割や配当を調整した後の終値。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Volume（出来高）&lt;/td&gt;
					&lt;td&gt;取引日の中で売買された株式の総数。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;出来高についての補足&#34;&gt;出来高についての補足&lt;/h3&gt;
&lt;p&gt;特定の期間に取引された株式の数量を示します。出来高の増減は市場の関心度やトレンドの強さを示します。また、高い出来高を伴う価格変動は信頼性が高く、トレンドが続く可能性がある。&lt;/p&gt;
&lt;h2 id=&#34;技術分析データについて&#34;&gt;技術分析データについて&lt;/h2&gt;
&lt;p&gt;株価からわかる基本的な情報はこれで以上になります。この情報を組み合わせて変数を作り、そのデータを株価予測に使用していきます。次は技術分析についてです。&lt;/p&gt;
&lt;p&gt;技術分析はザックリ分けると以下の2タイプに分かれます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;トレンド系指標（順張り系指標）&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;オシレーター系指標（逆張り系指標）&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この2つを組み合わせることで&lt;strong&gt;だまし&lt;/strong&gt;に合わず有効活用できると言われています。※だまし(理論通りの動きとならず反対の動きをすること)&lt;/p&gt;
&lt;p&gt;まずは&lt;strong&gt;トレンド系指標&lt;/strong&gt;から見ていこうと思います。他にも指標はありますが文量が多くなるので次回に回します。&lt;/p&gt;
&lt;h3 id=&#34;トレンド系指標&#34;&gt;&lt;strong&gt;トレンド系指標&lt;/strong&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;移動平均線&lt;/strong&gt;: 一定期間の平均株価。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MACD（移動平均収束拡散法）&lt;/strong&gt;: 短期と長期の移動平均線の差。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ボリンジャーバンド&lt;/strong&gt;: 株価の変動範囲を示す指標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;一目均衡表&lt;/strong&gt;：市場のトレンド、サポート・レジスタンス、買い・売りのシグナルを同時に把握できる総合的なテクニカル指標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;DMI&lt;/strong&gt;：上昇トレンドと下降トレンドの強さを示し、相場の方向性を判断するための指標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;パラボリック&lt;/strong&gt;：トレンドの転換点を示し、上昇トレンドでは株価の下、下降トレンドでは株価の上に点を描く指標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;エンベロープ&lt;/strong&gt;：一定期間の移動平均線に対して上下に一定割合だけ離れたバンドを描き、過熱感を判断する指標。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;技術分析データ_補足説明&#34;&gt;技術分析データ_補足説明&lt;/h2&gt;
&lt;h4 id=&#34;移動平均線-moving-average-ma&#34;&gt;移動平均線 (Moving Average, MA)&lt;/h4&gt;
&lt;p&gt;一定期間の平均株価を計算し、その期間が過ぎると新しいデータで更新される指標。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;単純移動平均線 (Simple Moving Average, SMA)：指定された期間の株価の平均値を計算。例：5日移動平均線、25日移動平均線、75日移動平均線&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;指数平滑移動平均線 (Exponential Moving Average, EMA)：最近のデータに重みを置いて計算する移動平均線。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;macd-moving-average-convergence-divergence-移動平均収束拡散法&#34;&gt;MACD (Moving Average Convergence Divergence, 移動平均収束拡散法)&lt;/h4&gt;
&lt;p&gt;短期のEMAと長期のEMAの差を基にした指標。3つの要素で構成され、MACDラインがシグナルラインを上抜けると買いシグナル、下抜けると売りシグナルとされる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MACDライン&lt;/strong&gt;: 12日EMAと26日EMAの差&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;シグナルライン&lt;/strong&gt;: 9日EMA（MACDラインのEMA）&lt;/p&gt;</description>
    </item>
    <item>
      <title>短期売買と分析力が向上しそうな株価予測をだらだらとやる part1</title>
      <link>https://xainome-blog.pages.dev/posts/2024/06/stock-price-prediction-part-1/</link>
      <pubDate>Mon, 10 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://xainome-blog.pages.dev/posts/2024/06/stock-price-prediction-part-1/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://xainome-blog.pages.dev/posts/2024/05/build-rag-app-part-10/&#34;&gt;前回&lt;/a&gt;RAGシステムを作ってみてある程度できました。次に、何を作ろうかということで表題になります。&lt;/p&gt;
&lt;p&gt;前回と違って完成形は全く思い浮かんでません。とりあえずやってれば何かできるかということで作っていきます。&lt;/p&gt;
&lt;h2 id=&#34;ティッカー取得&#34;&gt;ティッカー取得&lt;/h2&gt;
&lt;p&gt;まずは株価の取得が必要なのですが今回は&lt;strong&gt;yahoo! finance&lt;/strong&gt;のAPIを使って取得しようと思います。取得する際のコードは以下。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;import pandas_datareader.data as web
df = web.get_data_yahoo(&amp;#39;1304&amp;#39;, &amp;#39;1980-01-01&amp;#39;, &amp;#39;2024-06-10&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;pandas_datareaderにyahoo用の株価取得ライブラリがあるのでそれを利用します。ティッカー(銘柄)と株価取得の時間を設定します。&lt;/p&gt;
&lt;p&gt;株価の取得は簡単なのですが、ティッカーをいちいち手入力するのは面倒ですね。時間は変数で設定できますので問題ないです。&lt;/p&gt;
&lt;p&gt;というわけでティッカーを取得するプログラムを作ります。&lt;/p&gt;
&lt;p&gt;ティッカーを取得するには東京証券取引所、名古屋証券取引所、福岡証券取引所、札幌証券取引所、各国別SBI証券ティッカー一覧から取れると思いますが、今回はSBI証券から取得しようと思います。&lt;/p&gt;
&lt;p&gt;昔やろうとしたことがあったのでそれを流用しようと思います。対象となるサイトは&lt;a href=&#34;https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_usequity_list.html&#34;&gt;こちら&lt;/a&gt;です。&lt;/p&gt;
&lt;h3 id=&#34;ティッカー取得プログラム&#34;&gt;ティッカー取得プログラム&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# SBI証券から海外のティッカーまたはコードと銘柄を取得
from bs4 import BeautifulSoup
import re, sys, time
import requests
import pandas as pd

sbi_foreign_stock_list = [
  {&amp;#34;america&amp;#34;:   {&amp;#34;url&amp;#34;: &amp;#34;https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_usequity_list.html&amp;#34;, &amp;#34;tag&amp;#34;: &amp;#34;table&amp;#34;, &amp;#34;c_cd&amp;#34;:&amp;#34;&amp;#34;, &amp;#34;class&amp;#34;: &amp;#34;md-l-table-01 md-l-utl-mt10&amp;#34;}},
  {&amp;#34;china&amp;#34;:     {&amp;#34;url&amp;#34;: &amp;#34;https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_hk_list.html&amp;#34;,       &amp;#34;tag&amp;#34;: &amp;#34;div&amp;#34;,   &amp;#34;c_cd&amp;#34;:&amp;#34;HK&amp;#34;, &amp;#34;class&amp;#34;: &amp;#34;accTbl01&amp;#34;}},
  {&amp;#34;korea&amp;#34;:     {&amp;#34;url&amp;#34;: &amp;#34;https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_kr_list.html&amp;#34;,       &amp;#34;tag&amp;#34;: &amp;#34;div&amp;#34;,   &amp;#34;c_cd&amp;#34;:&amp;#34;KS&amp;#34;, &amp;#34;class&amp;#34;: &amp;#34;accTbl01&amp;#34;}},
  {&amp;#34;russia&amp;#34;:    {&amp;#34;url&amp;#34;: &amp;#34;https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_ru_list.html&amp;#34;,       &amp;#34;tag&amp;#34;: &amp;#34;div&amp;#34;,   &amp;#34;c_cd&amp;#34;:&amp;#34;ME&amp;#34;, &amp;#34;class&amp;#34;: &amp;#34;accTbl01&amp;#34;}},
  {&amp;#34;vietnam&amp;#34;:   {&amp;#34;url&amp;#34;: &amp;#34;https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_vn_list.html&amp;#34;,       &amp;#34;tag&amp;#34;: &amp;#34;div&amp;#34;,   &amp;#34;c_cd&amp;#34;:&amp;#34;VN&amp;#34;, &amp;#34;class&amp;#34;: &amp;#34;accTbl01&amp;#34;}},
  {&amp;#34;Indonesia&amp;#34;: {&amp;#34;url&amp;#34;: &amp;#34;https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_id_list.html&amp;#34;,       &amp;#34;tag&amp;#34;: &amp;#34;div&amp;#34;,   &amp;#34;c_cd&amp;#34;:&amp;#34;JK&amp;#34;, &amp;#34;class&amp;#34;: &amp;#34;accTbl01&amp;#34;}},
  {&amp;#34;Singapore&amp;#34;: {&amp;#34;url&amp;#34;: &amp;#34;https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_sg_list.html&amp;#34;,       &amp;#34;tag&amp;#34;: &amp;#34;div&amp;#34;,   &amp;#34;c_cd&amp;#34;:&amp;#34;SI&amp;#34;, &amp;#34;class&amp;#34;: &amp;#34;accTbl01&amp;#34;}}, # SBIとyahooのティカーが一致しない件
  {&amp;#34;thailand&amp;#34;:  {&amp;#34;url&amp;#34;: &amp;#34;https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_th_list.html&amp;#34;,       &amp;#34;tag&amp;#34;: &amp;#34;div&amp;#34;,   &amp;#34;c_cd&amp;#34;:&amp;#34;BK&amp;#34;, &amp;#34;class&amp;#34;: &amp;#34;accTbl01&amp;#34;}},
  {&amp;#34;malaysia&amp;#34;:  {&amp;#34;url&amp;#34;: &amp;#34;https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_my_list.html&amp;#34;,       &amp;#34;tag&amp;#34;: &amp;#34;div&amp;#34;,   &amp;#34;c_cd&amp;#34;:&amp;#34;KL&amp;#34;, &amp;#34;class&amp;#34;: &amp;#34;accTbl01&amp;#34;}} # SBIとyahooのティカーが一致しない件
]

for foreign_dict in sbi_foreign_stock_list:
  for country, values in foreign_dict.items():
    country_url = values[&amp;#34;url&amp;#34;]
    country_tag = values[&amp;#34;tag&amp;#34;]
    country_code = values[&amp;#34;c_cd&amp;#34;]
    country_class = values[&amp;#34;class&amp;#34;]
    html = requests.get(country_url)
    soup = BeautifulSoup(html.content, &amp;#34;html.parser&amp;#34;)
    for table_soup in soup.find_all(country_tag, class_=country_class):
      stock_data = []
      rows = table_soup.find_all(&amp;#34;tr&amp;#34;)
      for row in rows[1:]:
        ticker = row.find_all(&amp;#34;th&amp;#34;)[0].text.strip()
        cols = row.find_all(&amp;#34;td&amp;#34;)
        name = cols[0].text.strip()
        stock_data.append((ticker, name))
      continue

    df_foreign_stock = pd.DataFrame(stock_data, columns=[&amp;#34;コード&amp;#34;, &amp;#34;銘柄名&amp;#34;])
    df_foreign_stock[&amp;#34;コード&amp;#34;] = df_foreign_stock[&amp;#34;コード&amp;#34;].astype(str) + country_code
    df_foreign_stock.to_csv(out_oth_fol + country + &amp;#34;_stock_list.csv&amp;#34;)
    time.sleep(2)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;これを流用すれば取得できますが、今のサイトではできません。少し前のサイトが&lt;a href=&#34;https://megalodon.jp/2021-1117-0941-36/https://search.sbisec.co.jp:443/v2/popwin/info/stock/pop6040_usequity_list.html&#34;&gt;こちら&lt;/a&gt;です。こちらであれば取得できますが、最新のティッカー情報が取れないので修正します。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
