以前以下の記事でテクニカル分析を行ってみましたが,毎回ChatGPTに生成してもらうのは面倒なので、自動でテクニカル指標の計算から評価結果の出力まで行うスクリプトを生成してもらうことにします。
otama-playground.hatenablog.com
スクリプトを生成する手順
以下のような流れでスクリプトの生成をします。ここで2~4の間に手動フェーズを挟んでいる理由は2つあります。1つ目は出力が長くなると精度が悪化する場合があるため、2つ目は途中で出力結果の妥当性チェックを行うためです。
- まず、テクニカル分析に使用する指標を選ぶ
- 今回は下記のリンク先から選びました。
- info.monex.co.jp
- 指標を計算するコードをChatGPTに作成してもらう
- 2のコードを一度手元で実行して値を求めるとともに、エラーが出ないかなど確認。
- 3の結果をChatGPTに渡して買いか売りかを判断するスクリプトを書いてもらう
- 2と4のコードを統合して一つのpythonスクリプトにする。
- ChatGPTに任せてもよいです
- pythonを書ける方であれば手動で行った方が安心かもしれません
実行結果
2. 指標を計算するコードをChatGPTに作成してもらう
以下の指標を計算するpythonコードを生成してください。 指標を計算する部分は関数として分離してください。 * 移動平均線 * ボリンジャーバンド * 一目均衡表 * MACD * RSI * ストキャスティクス * RCI
>生成されたスクリプト
import yfinance as yf import pandas as pd import numpy as np def calculate_moving_average(df, window): df[f'MA_{window}'] = df['Close'].rolling(window=window).mean() return df def calculate_bollinger_bands(df, window, num_std_dev): df['MA'] = df['Close'].rolling(window=window).mean() df['BB_Upper'] = df['MA'] + num_std_dev * df['Close'].rolling(window=window).std() df['BB_Lower'] = df['MA'] - num_std_dev * df['Close'].rolling(window=window).std() return df def calculate_ichimoku_cloud(df): high_9 = df['High'].rolling(window=9).max() low_9 = df['Low'].rolling(window=9).min() df['Tenkan-sen'] = (high_9 + low_9) / 2 high_26 = df['High'].rolling(window=26).max() low_26 = df['Low'].rolling(window=26).min() df['Kijun-sen'] = (high_26 + low_26) / 2 df['Senkou_span_A'] = ((df['Tenkan-sen'] + df['Kijun-sen']) / 2).shift(26) high_52 = df['High'].rolling(window=52).max() low_52 = df['Low'].rolling(window=52).min() df['Senkou_span_B'] = ((high_52 + low_52) / 2).shift(26) df['Chikou_span'] = df['Close'].shift(-26) return df def calculate_macd(df, short_window, long_window, signal_window): df['EMA_short'] = df['Close'].ewm(span=short_window, adjust=False).mean() df['EMA_long'] = df['Close'].ewm(span=long_window, adjust=False).mean() df['MACD'] = df['EMA_short'] - df['EMA_long'] df['MACD_signal'] = df['MACD'].ewm(span=signal_window, adjust=False).mean() return df def calculate_rsi(df, window): delta = df['Close'].diff() gain = (delta.where(delta > 0, 0)).rolling(window=window).mean() loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean() rs = gain / loss df['RSI'] = 100 - (100 / (1 + rs)) return df def calculate_stochastic_oscillator(df, k_window, d_window): df['L14'] = df['Low'].rolling(window=k_window).min() df['H14'] = df['High'].rolling(window=k_window).max() df['%K'] = (df['Close'] - df['L14']) * 100 / (df['H14'] - df['L14']) df['%D'] = df['%K'].rolling(window=d_window).mean() return df def calculate_rci(df, window): def compute_rci(series): n = len(series) rank_diff = series.rank() - pd.Series(range(1, n + 1)) rci = 1 - 6 * (rank_diff ** 2).sum() / (n * (n**2 - 1)) return rci * 100 df['RCI'] = df['Close'].rolling(window=window).apply(compute_rci, raw=False) return df def main(): # Fetch stock data using yfinance ticker = 'AAPL' df = yf.download(ticker, start='2020-01-01', end='2023-01-01') # Calculate indicators df = calculate_moving_average(df, window=20) df = calculate_bollinger_bands(df, window=20, num_std_dev=2) df = calculate_ichimoku_cloud(df) df = calculate_macd(df, short_window=12, long_window=26, signal_window=9) df = calculate_rsi(df, window=14) df = calculate_stochastic_oscillator(df, k_window=14, d_window=3) df = calculate_rci(df, window=9) # Save the result to a new CSV file df.to_csv('/path/to/your/outputfile.csv') if __name__ == '__main__': main()
3. コードを一度手元で実行して値を求めるとともに、エラーが出ないかなど確認。
移動平均のレンジが20のみだったため、手動で25と75に修正しました。
そして、実行するとoutput.csvが生成されます。全ての指標がデータフレーム内に入り乱れており何が何やら状態ですが、ChatGPTなら理解してくれると信じてそのまま進めます。
>修正後のスクリプト
import datetime import pandas as pd import numpy as np import yfinance as yf def calculate_moving_average(df, window): df[f'MA_{window}'] = df['Close'].rolling(window=window).mean() return df def calculate_bollinger_bands(df, window, num_std_dev): df['MA'] = df['Close'].rolling(window=window).mean() df['BB_Upper'] = df['MA'] + num_std_dev * df['Close'].rolling(window=window).std() df['BB_Lower'] = df['MA'] - num_std_dev * df['Close'].rolling(window=window).std() return df def calculate_ichimoku_cloud(df): high_9 = df['High'].rolling(window=9).max() low_9 = df['Low'].rolling(window=9).min() df['Tenkan-sen'] = (high_9 + low_9) / 2 high_26 = df['High'].rolling(window=26).max() low_26 = df['Low'].rolling(window=26).min() df['Kijun-sen'] = (high_26 + low_26) / 2 df['Senkou_span_A'] = ((df['Tenkan-sen'] + df['Kijun-sen']) / 2).shift(26) high_52 = df['High'].rolling(window=52).max() low_52 = df['Low'].rolling(window=52).min() df['Senkou_span_B'] = ((high_52 + low_52) / 2).shift(26) df['Chikou_span'] = df['Close'].shift(-26) return df def calculate_macd(df, short_window, long_window, signal_window): df['EMA_short'] = df['Close'].ewm(span=short_window, adjust=False).mean() df['EMA_long'] = df['Close'].ewm(span=long_window, adjust=False).mean() df['MACD'] = df['EMA_short'] - df['EMA_long'] df['MACD_signal'] = df['MACD'].ewm(span=signal_window, adjust=False).mean() return df def calculate_rsi(df, window): delta = df['Close'].diff() gain = (delta.where(delta > 0, 0)).rolling(window=window).mean() loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean() rs = gain / loss df['RSI'] = 100 - (100 / (1 + rs)) return df def calculate_stochastic_oscillator(df, k_window, d_window): df['L14'] = df['Low'].rolling(window=k_window).min() df['H14'] = df['High'].rolling(window=k_window).max() df['%K'] = (df['Close'] - df['L14']) * 100 / (df['H14'] - df['L14']) df['%D'] = df['%K'].rolling(window=d_window).mean() return df def calculate_rci(df, window): def compute_rci(series): n = len(series) rank_diff = series.rank() - pd.Series(range(1, n + 1)) rci = 1 - 6 * (rank_diff ** 2).sum() / (n * (n**2 - 1)) return rci * 100 df['RCI'] = df['Close'].rolling(window=window).apply(compute_rci, raw=False) return df def main(): # Fetch stock data using yfinance ticker = 'TM' start_date = datetime.date.today() - datetime.timedelta(days=365) end_date = datetime.date.today() df = yf.download(ticker, start=start_date, end=end_date) # Calculate indicators df = calculate_moving_average(df, window=25) df = calculate_moving_average(df, window=75) df = calculate_bollinger_bands(df, window=20, num_std_dev=2) df = calculate_ichimoku_cloud(df) df = calculate_macd(df, short_window=12, long_window=26, signal_window=9) df = calculate_rsi(df, window=14) df = calculate_stochastic_oscillator(df, k_window=14, d_window=3) df = calculate_rci(df, window=9) # Save the result to a new CSV file df.to_csv('./output.csv') if __name__ == '__main__': main()
4. 買いか売りかを判断するスクリプトを書いてもらう
テクニカル分析を行いました。 以下の指標を計算した結果が含まれているため、それぞれについて最新の日付を参照し,強い売り、売 り、中立、買い、強い買いの5段階評価するスクリプトを書いてください。 * MA25 * MA75 * ボリンジャーバンド * 一目均衡表 * MACD * RSI * ストキャスティクス * RCI 最後にそれぞれの指標について評価した結果を表としてまとめること。表のカラム は,指標、指標の値、評価、理由の4列にしてください。まとめた結果を俯瞰し、強い売り、売り、中立、買い、強い買いの5段階評価を行ってくださ い。そう評価した理由も教えてください
3で得られたCSVをChatGPTに渡して評価スクリプトを作成してもらいます。ここで評価結果も出力してもらい、出力に妥当性があるかを確認します。出力に妥当性がなかった場合や望んだ出力がでなかった場合はスクリプトを手動で修正、もしくは対話しながら修正してもらいます。
>生成されたスクリプト
# Extract the latest data row latest_data = data.iloc[-1] # Extracting the necessary indicators indicators = { 'MA25': latest_data['MA_20'], 'MA75': latest_data['MA'], 'BB_Upper': latest_data['BB_Upper'], 'BB_Lower': latest_data['BB_Lower'], 'Tenkan-sen': latest_data['Tenkan-sen'], 'Kijun-sen': latest_data['Kijun-sen'], 'Senkou_span_A': latest_data['Senkou_span_A'], 'Senkou_span_B': latest_data['Senkou_span_B'], 'Chikou_span': latest_data['Chikou_span'], 'MACD': latest_data['MACD'], 'MACD_signal': latest_data['MACD_signal'], 'RSI': latest_data['RSI'], '%K': latest_data['%K'], '%D': latest_data['%D'], 'RCI': latest_data['RCI'] } # Initialize a dictionary to store the evaluation results evaluation = [] # Function to evaluate the indicators def evaluate_indicators(latest_data): close_price = latest_data['Close'] # MA25 and MA75 if latest_data['MA_25'] > latest_data['MA_75']: evaluation.append(['MA', str(latest_data['MA_25']) + "/" + str(latest_data['MA_75']), '買い', 'MA25がMA75を上回っているため']) elif latest_data['MA_25'] < latest_data['MA_75']: evaluation.append(['MA', str(latest_data['MA_25']) + "/" + str(latest_data['MA_75']), '売り', 'MA25がMA75を下回っているため']) else: evaluation.append(['MA', str(latest_data['MA_25']) + "/" + str(latest_data['MA_75']), '中立', 'MA25とMA75が交差しているため']) # Bollinger Bands if close_price < latest_data['BB_Lower']: evaluation.append(['ボリンジャーバンド', close_price, '強い買い', '価格がボリンジャーバンドの下限に触れているため']) elif close_price > latest_data['BB_Upper']: evaluation.append(['ボリンジャーバンド', close_price, '強い売り', '価格がボリンジャーバンドの上限に触れているため']) elif close_price < (latest_data['BB_Lower'] + latest_data['BB_Upper']) / 2: evaluation.append(['ボリンジャーバンド', close_price, '買い', '価格がボリンジャーバンドの下限付近にあるため']) else: evaluation.append(['ボリンジャーバンド', close_price, '売り', '価格がボリンジャーバンドの上限付近にあるため']) # Ichimoku Cloud if close_price > latest_data['Senkou_span_A'] and close_price > latest_data['Senkou_span_B']: if latest_data['Tenkan-sen'] > latest_data['Kijun-sen']: evaluation.append(['一目均衡表', close_price, '強い買い', '価格が雲の上にあり、転換線が基準線を上回っているため']) else: evaluation.append(['一目均衡表', close_price, '買い', '価格が雲の上にあるため']) elif close_price < latest_data['Senkou_span_A'] and close_price < latest_data['Senkou_span_B']: if latest_data['Tenkan-sen'] < latest_data['Kijun-sen']: evaluation.append(['一目均衡表', close_price, '強い売り', '価格が雲の下にあり、転換線が基準線を下回っているため']) else: evaluation.append(['一目均衡表', close_price, '売り', '価格が雲の下にあるため']) else: evaluation.append(['一目均衡表', close_price, '中立', '価格が雲の中にあるため']) # MACD if latest_data['MACD'] > latest_data['MACD_signal']: evaluation.append(['MACD', latest_data['MACD'], '買い', 'MACDがシグナルラインを上回っているため']) elif latest_data['MACD'] < latest_data['MACD_signal']: evaluation.append(['MACD', latest_data['MACD'], '売り', 'MACDがシグナルラインを下回っているため']) else: evaluation.append(['MACD', latest_data['MACD'], '中立', 'MACDとシグナルラインが交差しているため']) # RSI if latest_data['RSI'] < 30: evaluation.append(['RSI', latest_data['RSI'], '強い買い', 'RSIが30以下のため']) elif latest_data['RSI'] > 70: evaluation.append(['RSI', latest_data['RSI'], '強い売り', 'RSIが70以上のため']) elif 30 <= latest_data['RSI'] <= 50: evaluation.append(['RSI', latest_data['RSI'], '買い', 'RSIが30から50の間にあるため']) elif 50 < latest_data['RSI'] <= 70: evaluation.append(['RSI', latest_data['RSI'], '売り', 'RSIが50から70の間にあるため']) else: evaluation.append(['RSI', latest_data['RSI'], '中立', 'RSIが50のため']) # Stochastic (%K and %D) if latest_data['%K'] < 20: evaluation.append(['ストキャスティクス', latest_data['%K'], '強い買い', '%Kが20以下のため']) elif latest_data['%K'] > 80: evaluation.append(['ストキャスティクス', latest_data['%K'], '強い売り', '%Kが80以上のため']) elif 20 <= latest_data['%K'] <= 50: evaluation.append(['ストキャスティクス', latest_data['%K'], '買い', '%Kが20から50の間にあるため']) elif 50 < latest_data['%K'] <= 80: evaluation.append(['ストキャスティクス', latest_data['%K'], '売り', '%Kが50から80の間にあるため']) else: evaluation.append(['ストキャスティクス', latest_data['%K'], '中立', '%Kが50のため']) # RCI if latest_data['RCI'] < -80: evaluation.append(['RCI', latest_data['RCI'], '強い買い', 'RCIが-80以下のため']) elif latest_data['RCI'] > 80: evaluation.append(['RCI', latest_data['RCI'], '強い売り', 'RCIが80以上のため']) elif -80 <= latest_data['RCI'] <= -20: evaluation.append(['RCI', latest_data['RCI'], '買い', 'RCIが-80から-20の間にあるため']) elif 20 < latest_data['RCI'] <= 80: evaluation.append(['RCI', latest_data['RCI'], '売り', 'RCIが20から80の間にあるため']) else: evaluation.append(['RCI', latest_data['RCI'], '中立', 'RCIが-20から20の間にあるため']) evaluate_indicators(latest_data) # Convert the evaluation results to a DataFrame for better readability evaluation_df = pd.DataFrame(evaluation, columns=['指標', '指標の値', '評価', '理由']) evaluation_df
以下のような出力が得られました。特に問題点はなさそうです。
指標 | 指標の値 | 評価 | 理由 |
---|---|---|---|
MA | 139.07759979248047/144.1038656616211 | 売り | MA25がMA75を下回っているため |
ボリンジャーバンド | 129.929993 | 買い | 価格がボリンジャーバンドの下限付近にあるため |
一目均衡表 | 129.929993 | 強い売り | 価格が雲の下にあり、転換線が基準線を下回っているため |
MACD | -4.416427 | 売り | MACDがシグナルラインを下回っているため |
RSI | 31.430277 | 買い | RSIが30から50の間にあるため |
ストキャスティクス | 16.846432 | 強い買い | %Kが20以下のため |
RCI | 100.0 | 強い売り | RCIが80以上のため |
5. 2と4のコードを統合して一つのpythonスクリプトにする
今回のコンセプトはChatGPTに生成してもらうことなので、ChatGPTに統合してもらいました。
>最終的なコード
import yfinance as yf import pandas as pd import numpy as np def calculate_moving_average(df, window): df[f'MA_{window}'] = df['Close'].rolling(window=window).mean() return df def calculate_bollinger_bands(df, window, num_std_dev): df['MA'] = df['Close'].rolling(window=window).mean() df['BB_Upper'] = df['MA'] + num_std_dev * df['Close'].rolling(window=window).std() df['BB_Lower'] = df['MA'] - num_std_dev * df['Close'].rolling(window=window).std() return df def calculate_ichimoku_cloud(df): high_9 = df['High'].rolling(window=9).max() low_9 = df['Low'].rolling(window=9).min() df['Tenkan-sen'] = (high_9 + low_9) / 2 high_26 = df['High'].rolling(window=26).max() low_26 = df['Low'].rolling(window=26).min() df['Kijun-sen'] = (high_26 + low_26) / 2 df['Senkou_span_A'] = ((df['Tenkan-sen'] + df['Kijun-sen']) / 2).shift(26) high_52 = df['High'].rolling(window=52).max() low_52 = df['Low'].rolling(window=52).min() df['Senkou_span_B'] = ((high_52 + low_52) / 2).shift(26) df['Chikou_span'] = df['Close'].shift(-26) return df def calculate_macd(df, short_window, long_window, signal_window): df['EMA_short'] = df['Close'].ewm(span=short_window, adjust=False).mean() df['EMA_long'] = df['Close'].ewm(span=long_window, adjust=False).mean() df['MACD'] = df['EMA_short'] - df['EMA_long'] df['MACD_signal'] = df['MACD'].ewm(span=signal_window, adjust=False).mean() return df def calculate_rsi(df, window): delta = df['Close'].diff() gain = (delta.where(delta > 0, 0)).rolling(window=window).mean() loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean() rs = gain / loss df['RSI'] = 100 - (100 / (1 + rs)) return df def calculate_stochastic_oscillator(df, k_window, d_window): df['L14'] = df['Low'].rolling(window=k_window).min() df['H14'] = df['High'].rolling(window=k_window).max() df['%K'] = (df['Close'] - df['L14']) * 100 / (df['H14'] - df['L14']) df['%D'] = df['%K'].rolling(window=d_window).mean() return df def calculate_rci(df, window): def compute_rci(series): n = len(series) rank_diff = series.rank() - pd.Series(range(1, n + 1)) rci = 1 - 6 * (rank_diff ** 2).sum() / (n * (n**2 - 1)) return rci * 100 df['RCI'] = df['Close'].rolling(window=window).apply(compute_rci, raw=False) return df def evaluate_indicators(latest_data): evaluation = [] close_price = latest_data['Close'] # MA25 and MA75 if latest_data['MA_25'] > latest_data['MA_75']: evaluation.append(['MA', str(latest_data['MA_25']) + "/" + str(latest_data['MA_75']), '買い', 'MA25がMA75を上回っているため']) elif latest_data['MA_25'] < latest_data['MA_75']: evaluation.append(['MA', str(latest_data['MA_25']) + "/" + str(latest_data['MA_75']), '売り', 'MA25がMA75を下回っているため']) else: evaluation.append(['MA', str(latest_data['MA_25']) + "/" + str(latest_data['MA_75']), '中立', 'MA25とMA75が交差しているため']) # Bollinger Bands if close_price < latest_data['BB_Lower']: evaluation.append(['ボリンジャーバンド', close_price, '強い買い', '価格がボリンジャーバンドの下限に触れているため']) elif close_price > latest_data['BB_Upper']: evaluation.append(['ボリンジャーバンド', close_price, '強い売り', '価格がボリンジャーバンドの上限に触れているため']) elif close_price < (latest_data['BB_Lower'] + latest_data['BB_Upper']) / 2: evaluation.append(['ボリンジャーバンド', close_price, '買い', '価格がボリンジャーバンドの下限付近にあるため']) else: evaluation.append(['ボリンジャーバンド', close_price, '売り', '価格がボリンジャーバンドの上限付近にあるため']) # Ichimoku Cloud if close_price > latest_data['Senkou_span_A'] and close_price > latest_data['Senkou_span_B']: if latest_data['Tenkan-sen'] > latest_data['Kijun-sen']: evaluation.append(['一目均衡表', close_price, '強い買い', '価格が雲の上にあり、転換線が基準線を上回っているため']) else: evaluation.append(['一目均衡表', close_price, '買い', '価格が雲の上にあるため']) elif close_price < latest_data['Senkou_span_A'] and close_price < latest_data['Senkou_span_B']: if latest_data['Tenkan-sen'] < latest_data['Kijun-sen']: evaluation.append(['一目均衡表', close_price, '強い売り', '価格が雲の下にあり、転換線が基準線を下回っているため']) else: evaluation.append(['一目均衡表', close_price, '売り', '価格が雲の下にあるため']) else: evaluation.append(['一目均衡表', close_price, '中立', '価格が雲の中にあるため']) # MACD if latest_data['MACD'] > latest_data['MACD_signal']: evaluation.append(['MACD', latest_data['MACD'], '買い', 'MACDがシグナルラインを上回っているため']) elif latest_data['MACD'] < latest_data['MACD_signal']: evaluation.append(['MACD', latest_data['MACD'], '売り', 'MACDがシグナルラインを下回っているため']) else: evaluation.append(['MACD', latest_data['MACD'], '中立', 'MACDとシグナルラインが交差しているため']) # RSI if latest_data['RSI'] < 30: evaluation.append(['RSI', latest_data['RSI'], '強い買い', 'RSIが30以下のため']) elif latest_data['RSI'] > 70: evaluation.append(['RSI', latest_data['RSI'], '強い売り', 'RSIが70以上のため']) elif 30 <= latest_data['RSI'] <= 50: evaluation.append(['RSI', latest_data['RSI'], '買い', 'RSIが30から50の間にあるため']) elif 50 < latest_data['RSI'] <= 70: evaluation.append(['RSI', latest_data['RSI'], '売り', 'RSIが50から70の間にあるため']) else: evaluation.append(['RSI', latest_data['RSI'], '中立', 'RSIが50のため']) # Stochastic (%K and %D) if latest_data['%K'] < 20: evaluation.append(['ストキャスティクス', latest_data['%K'], '強い買い', '%Kが20以下のため']) elif latest_data['%K'] > 80: evaluation.append(['ストキャスティクス', latest_data['%K'], '強い売り', '%Kが80以上のため']) elif 20 <= latest_data['%K'] <= 50: evaluation.append(['ストキャスティクス', latest_data['%K'], '買い', '%Kが20から50の間にあるため']) elif 50 < latest_data['%K'] <= 80: evaluation.append(['ストキャスティクス', latest_data['%K'], '売り', '%Kが50から80の間にあるため']) else: evaluation.append(['ストキャスティクス', latest_data['%K'], '中立', '%Kが50のため']) # RCI if latest_data['RCI'] < -80: evaluation.append(['RCI', latest_data['RCI'], '強い買い', 'RCIが-80以下のため']) elif latest_data['RCI'] > 80: evaluation.append(['RCI', latest_data['RCI'], '強い売り', 'RCIが80以上のため']) elif -80 <= latest_data['RCI'] <= -20: evaluation.append(['RCI', latest_data['RCI'], '買い', 'RCIが-80から-20の間にあるため']) elif 20 < latest_data['RCI'] <= 80: evaluation.append(['RCI', latest_data['RCI'], '売り', 'RCIが20から80の間にあるため']) else: evaluation.append(['RCI', latest_data['RCI'], '中立', 'RCIが-20から20の間にあるため']) return evaluation def main(): # Fetch stock data using yfinance ticker = 'AAPL' df = yf.download(ticker, start='2020-01-01', end='2023-01-01') # Calculate indicators df = calculate_moving_average(df, window=25) df = calculate_moving_average(df, window=75) df = calculate_bollinger_bands(df, window=20, num_std_dev=2) df = calculate_ichimoku_cloud(df) df = calculate_macd(df, short_window=12, long_window=26, signal_window=9) df = calculate_rsi(df, window=14) df = calculate_stochastic_oscillator(df, k_window=14, d_window=3) df = calculate_rci(df, window=9) # Save the result to a new CSV file df.to_csv('/path/to/your/outputfile.csv') # Extract the latest data row latest_data = df.iloc[-1] # Evaluate the latest data evaluation = evaluate_indicators(latest_data) # Convert the evaluation results to a DataFrame for better readability evaluation_df = pd.DataFrame(evaluation, columns=['指標', '指標の値', '評価', '理由']) print(evaluation_df) if __name__ == '__main__': main()
おまけ:可視化スクリプトも生成してみる
ChatGPTが生成したコード
>可視化コード
import matplotlib.pyplot as plt # Set the figure size plt.figure(figsize=(15, 10)) # Plot MA25 and MA75 plt.subplot(3, 1, 1) plt.plot(data['Date'], data['MA_20'], label='MA25') plt.plot(data['Date'], data['MA'], label='MA75') plt.title('Moving Averages (MA25 and MA75)') plt.xlabel('Date') plt.ylabel('Price') plt.legend() # Plot Bollinger Bands plt.subplot(3, 1, 2) plt.plot(data['Date'], data['Close'], label='Close Price') plt.plot(data['Date'], data['BB_Upper'], label='BB Upper') plt.plot(data['Date'], data['BB_Lower'], label='BB Lower') plt.title('Bollinger Bands') plt.xlabel('Date') plt.ylabel('Price') plt.legend() # Plot MACD plt.subplot(3, 1, 3) plt.plot(data['Date'], data['MACD'], label='MACD') plt.plot(data['Date'], data['MACD_signal'], label='MACD Signal') plt.title('MACD') plt.xlabel('Date') plt.ylabel('Value') plt.legend() plt.tight_layout() plt.show()
可視化結果
最後に
テクニカル指標の計算から実際の評価までの全部を行うスクリプトをChatGPTに生成してもらうことにより、今後はChatGPTを使用せずにスクリプトを実行するだけで評価が可能になります。
毎回生成結果の妥当性チェックをする必要性もなくなるので、結構嬉しいんじゃないかなと思います。気になる方はぜひ試してみてください。
Appendix
指標毎の評価基準(参考)
指標 | 強い買い | 買い | 中立 | 売り | 強い売り |
---|---|---|---|---|---|
MA25 | 短期移動平均線が長期移動平均線を上回るクロスが確認された場合 | 短期移動平均線が長期移動平均線より上 | 短期移動平均線と長期移動平均線が交差している | 短期移動平均線が長期移動平均線より下 | 短期移動平均線が長期移動平均線を下回るクロスが確認された場合 |
ボリンジャーバンド | 価格がボリンジャーバンドの下限に触れた場合 | 価格がボリンジャーバンドの下限付近にある場合 | 価格がボリンジャーバンドの中間帯にある場合 | 価格がボリンジャーバンドの上限付近にある場合 | 価格がボリンジャーバンドの上限に触れた場合 |
一目均衡表 | 価格が雲の上にあり、転換線が基準線を上回るクロスが確認された場合 | 価格が雲の上にある場合 | 価格が雲の中にある場合 | 価格が雲の下にある場合 | 価格が雲の下にあり、転換線が基準線を下回るクロスが確認された場合 |
MACD | MACDがシグナルラインを上回るクロスが確認された場合 | MACDがシグナルラインより上 | MACDとシグナルラインが交差している | MACDがシグナルラインより下 | MACDがシグナルラインを下回るクロスが確認された場合 |
RSI | RSIが30以下 | RSIが30から50の間 | RSIが50 | RSIが50から70の間 | RSIが70以上 |
ストキャスティクス | %Kが20以下 | %Kが20から50の間 | %Kが50 | %Kが50から80の間 | %Kが80以上 |
RCI | RCIが-80以下 | RCIが-80から-20の間 | RCIが-20から20の間 | RCIが20から80の間 | RCIが80以上 |