![見出し画像](https://assets.st-note.com/production/uploads/images/143626564/rectangle_large_type_2_6d4453b1042876f44cdf1b5ffe8ccb78.png?width=1200)
主成分分析を生かしてみる。
今回も主成分分析について
久々の投稿となってしまいましたが、今回は主成分分析についてまたいろいろ試したいと思い記事を作成しております。
今回のテーマは株を持っていた方がいいのか、持たない方がいいのか、判断を保留した方がいいのか?です。
NISAが始まり、その背景を探る
NISAが始まり、株を買った方がいいのか、それとも手放した方がいいのか?という判断がなかなか難しいという方はいらっしゃるんじゃないかな?というか、自分がそういった感じになっていますので、それを打開するツールをchatGPTを使って作ってみました。
今回のコードは当てにしてはいけません。
まだ、テスト段階のため、今後の参考というか試しに作ってみたものとなりますので、実用性は皆無です。結果を見れば一目瞭然ではありますが、当てになりませんが、この考えを基盤とすることがきちんとしたものができないかなと思って改良を今後加える予定です。
先に結果を
![](https://assets.st-note.com/img/1718022803562-OQmEGvDMm0.png?width=1200)
概要としては、アップルのチャートを出しています。その中で主成分分析と判断をどうすれば良いかのクラスタリングをしております。ちなみに黄色の線はバックテストをして資産がどうなったかのテスト結果となります。
一応プラスにはなってますが、今回のコードに関してはまだまだ改良の余地があることがわかります。
今回作成してもらったコード
import pandas as pd
import numpy as np
import yfinance as yf
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
# 株価データを取得
data = yf.download('AAPL', start='2020-01-01')
# 特徴量の作成
data['SMA50'] = data['Close'].rolling(window=50).mean()
data['SMA200'] = data['Close'].rolling(window=200).mean()
data['Volatility'] = data['Close'].pct_change().rolling(window=50).std()
data = data.dropna()
# 特徴量の標準化
features = ['Close', 'SMA50', 'SMA200', 'Volatility']
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data[features])
# PCAの実行
pca = PCA(n_components=2)
principal_components = pca.fit_transform(data_scaled)
pca_df = pd.DataFrame(data=principal_components, columns=['PC1', 'PC2'])
pca_df['Date'] = data.index
pca_df = pca_df.set_index('Date')
# K-meansクラスタリング
kmeans = KMeans(n_clusters=3, random_state=0)
clusters = kmeans.fit_predict(principal_components)
pca_df['Cluster'] = clusters
# 投資判断の関数を定義
def investment_decision(cluster):
if cluster == 0:
return "Invest"
elif cluster == 1:
return "Do not invest"
else:
return "Hold"
pca_df['Decision'] = pca_df['Cluster'].apply(investment_decision)
# 最新の日付を取得して結果を表示
latest_data_point = scaler.transform(data[features].iloc[[-1]])
latest_principal_components = pca.transform(latest_data_point)
latest_cluster = kmeans.predict(latest_principal_components)[0]
latest_decision = investment_decision(latest_cluster)
print(f"Current PC1: {latest_principal_components[0][0]}")
print(f"Current PC2: {latest_principal_components[0][1]}")
print(f"Current Cluster: {latest_cluster}")
print(f"Investment Decision: {latest_decision}")
# クラスタごとに色分けしてチャートを表示
past_60_days = pca_df.tail(60)
color_map = {0: 'green', 1: 'red', 2: 'blue'}
colors = past_60_days['Cluster'].map(color_map)
plt.figure(figsize=(14, 7))
plt.plot(data.tail(60).index, data['Close'].tail(60), label='Close Price', color='black')
plt.scatter(past_60_days.index, data['Close'].tail(60), c=colors)
plt.title('PCA of Stock Data - Last 60 Days with Close Prices')
plt.xlabel('Date')
plt.ylabel('Price')
plt.legend()
plt.show()
# クラスタリングに基づく取引のシミュレーション
pca_df['Close'] = data['Close']
pca_df['Position'] = pca_df['Decision'].apply(lambda x: 1 if x == 'Invest' else 0)
pca_df['Strategy_Returns'] = pca_df['Close'].pct_change() * pca_df['Position'].shift(1)
# 累積リターンを計算
pca_df['Cumulative_Strategy_Returns'] = (pca_df['Strategy_Returns'] + 1).cumprod()
pca_df['Cumulative_Market_Returns'] = (pca_df['Close'].pct_change() + 1).cumprod()
# 結果のプロット
plt.figure(figsize=(14, 7))
plt.plot(pca_df.index, pca_df['Cumulative_Market_Returns'], label='Market Returns', color='blue')
plt.plot(pca_df.index, pca_df['Cumulative_Strategy_Returns'], label='Strategy Returns', color='orange')
plt.title('Cumulative Returns: Market vs. Strategy')
plt.xlabel('Date')
plt.ylabel('Cumulative Returns')
plt.legend()
plt.show()
# 過去60日間のデータを表示
print(past_60_days.tail())
# 最終的なリターンを表示
final_market_return = pca_df['Cumulative_Market_Returns'].iloc[-1]
final_strategy_return = pca_df['Cumulative_Strategy_Returns'].iloc[-1]
print(f"Final Market Return: {final_market_return}")
print(f"Final Strategy Return: {final_strategy_return}")
この記事が気に入ったらサポートをしてみませんか?