短期売買と分析力が向上しそうな株価予測をだらだらとやる part6

前回のあらすじ トレンド系指標の説明変数を追加したところで終わりました。 オシレーター系指標 今回作成したのは RSI RCI 移動平均線乖離率 スローストキャスティクス モメンタムとROC MFI CCI ギャップ ヒストリカル・ボラティリティ def rsi(df): # RSIの計算 window = 14 # 終値の変化 df['Change'] = df['Adj Close'].diff() # 上昇幅と下落幅の計算 df['Gain'] = np.where(df['Change'] > 0, df['Change'], 0) df['Loss'] = np.where(df['Change'] < 0, -df['Change'], 0) # 平均上昇幅と平均下落幅の計算 df['Avg_Gain'] = df['Gain'].rolling(window=window).mean() df['Avg_Loss'] = df['Loss'].rolling(window=window).mean() # 相対力(RS)の計算 df['RS'] = df['Avg_Gain'] / df['Avg_Loss'] # RSIの計算 df['RSI'] = 100 - (100 / (1 + df['RS'])) # シグナルの判定 df['rsi_Signal'] = np.where(df['RSI'] > 70, 'Sell', np.where(df['RSI'] < 30, 'Buy', 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['RCI'] = df['Adj Close'].rolling(window=window).apply(calculate_rci, raw=False) # シグナルの判定(RSIと同様に70以上で売りシグナル、30以下で買いシグナル) df['rci_Signal'] = np.where(df['RCI'] > 70, 'Sell', np.where(df['RCI'] < 30, 'Buy', np.nan)) def madp(df): # 乖離率の計算 df['madp'] = (df['Adj Close'] - df['SMA']) / df['SMA'] * 100 # シグナルの判定 df['madp_Signal'] = np.nan threshold = 5 # 閾値の設定 for i in range(1, len(df)): if df['madp'].iloc[i-1] < -threshold and df['madp'].iloc[i] > df['madp'].iloc[i-1]: df.at[df.index[i], 'madp_Signal'] = 'Buy' elif df['madp'].iloc[i-1] > threshold and df['madp'].iloc[i] < df['madp'].iloc[i-1]: df.at[df.index[i], 'madp_Signal'] = 'Sell' def stochastic(df): # %Kの計算 window = 14 df['14-High'] = df['High'].rolling(window=window).max() df['14-Low'] = df['Low'].rolling(window=window).min() df['%K'] = (df['Adj Close'] - df['14-Low']) / (df['14-High'] - df['14-Low']) * 100 # スロー%Dの計算 df['slow%D'] = df['%K'].rolling(window=3).mean() # シグナルの判定 df['sto_Signal'] = np.nan for i in range(1, len(df)): if df['slow%D'].iloc[i-1] < 20 and df['slow%D'].iloc[i] > df['slow%D'].iloc[i-1]: df.at[df.index[i], 'sto_Signal'] = 'Buy' elif df['slow%D'].iloc[i-1] > 80 and df['slow%D'].iloc[i] < df['slow%D'].iloc[i-1]: df.at[df.index[i], 'sto_Signal'] = 'Sell' def momentum_roc(df): # モメンタムとROCの計算 window = 14 df['Momentum'] = df['Adj Close'] - df['Adj Close'].shift(window) df['ROC'] = ((df['Adj Close'] - df['Adj Close'].shift(window)) / df['Adj Close'].shift(window)) * 100 # トレンドの判定 df['Momentum_Trend'] = np.where(df['Momentum'] > 0, 'Uptrend', np.where(df['Momentum'] < 0, 'Downtrend', 'Neutral')) df['ROC_Trend'] = np.where(df['ROC'] > 0, 'Uptrend', np.where(df['ROC'] < 0, 'Downtrend', 'Neutral')) def mfi(df): # 典型価格(TP)の計算 df['TP'] = (df['High'] + df['Low'] + df['Adj Close']) / 3 # マネーフロー(Raw Money Flow)の計算 df['Raw Money Flow'] = df['TP'] * df['Volume'] # ポジティブマネーフローとネガティブマネーフローの計算 df['Positive Money Flow'] = np.where(df['TP'] > df['TP'].shift(1), df['Raw Money Flow'], 0) df['Negative Money Flow'] = np.where(df['TP'] < df['TP'].shift(1), df['Raw Money Flow'], 0) # 14期間の合計 window = 14 df['Positive Money Flow Sum'] = df['Positive Money Flow'].rolling(window=window).sum() df['Negative Money Flow Sum'] = df['Negative Money Flow'].rolling(window=window).sum() # MFIの計算 df['Money Flow Ratio'] = df['Positive Money Flow Sum'] / df['Negative Money Flow Sum'] df['MFI'] = 100 - (100 / (1 + df['Money Flow Ratio'])) # シグナルの判定 df['mfi_Signal'] = np.nan for i in range(1, len(df)): if df['MFI'].iloc[i-1] < 20 and df['MFI'].iloc[i] > df['MFI'].iloc[i-1]: df.at[df.index[i], 'mfi_Signal'] = 'Buy' elif df['MFI'].iloc[i-1] > 80 and df['MFI'].iloc[i] < df['MFI'].iloc[i-1]: df.at[df.index[i], 'mfi_Signal'] = 'Sell' def cci(df): # 典型価格(TP)の計算 df['TP'] = (df['High'] + df['Low'] + df['Adj Close']) / 3 # 単純移動平均(SMA)の計算 window = 20 df['cci_SMA'] = df['TP'].rolling(window=window).mean() # 偏差(Mean Deviation)の計算 df['Mean Deviation'] = df['TP'].rolling(window=window).apply(lambda x: np.mean(np.abs(x - x.mean())), raw=True) # CCIの計算 df['CCI'] = (df['TP'] - df['cci_SMA']) / (0.015 * df['Mean Deviation']) # シグナルの判定 df['cci_Signal'] = np.nan for i in range(1, len(df)): if df['CCI'].iloc[i-1] < -100 and df['CCI'].iloc[i] > df['CCI'].iloc[i-1]: df.at[df.index[i], 'cci_Signal'] = 'Buy' elif df['CCI'].iloc[i-1] > 100 and df['CCI'].iloc[i] < df['CCI'].iloc[i-1]: df.at[df.index[i], 'cci_Signal'] = 'Sell' def gap(df): # ギャップアップとギャップダウンの計算 df['Previous Close'] = df['Adj Close'].shift(1) df['Gap'] = df['Open'] - df['Previous Close'] df['Gap Type'] = np.where(df['Gap'] > 0, 'Gap Up', np.where(df['Gap'] < 0, 'Gap Down', 'No Gap')) def hv(df): # ヒストリカル・ボラティリティの計算 window = 20 # リターンの計算 df['Return'] = np.log(df['Adj Close'] / df['Adj Close'].shift(1)) # 標準偏差の計算 df['HV'] = df['Return'].rolling(window=window).std() * np.sqrt(252) # df['RCI'] = df['Adj Close'].rolling(window=window).apply(calculate_rci, raw=False) # シグナルの判定 df['hv_Signal'] = np.nan for i in range(1, len(df)): if df['RCI'].iloc[i-1] < -80 and df['RCI'].iloc[i] > df['RCI'].iloc[i-1]: df.at[df.index[i], 'hv_Signal'] = 'Buy' elif df['RCI'].iloc[i-1] > 80 and df['RCI'].iloc[i] < df['RCI'].iloc[i-1]: df.at[df.index[i], 'hv_Signal'] = 'Sell' 次回は予測をしていこうと思います。 ...

2024年7月2日

MRI検査を初見で受けてきたよ

掲題の通り本日初めてMRIを受けてきました~ 受けた経緯 2週間前の6/15(土)に頭がくらくらする 翌日にはましになるが1週間たっても完治せず 先週脳神経内科に行って検査を受け、MRIを勧められる 本日MRI検査を受け、何事もなく帰宅 ということで検査結果は"異状なし"ということでした。 深刻または緊急性があるような病気でないことはよかったです。 ただ、歩くとふらふらすることがあるので少し危ないんですよね… 検査の感想 私が受けたMRIは20分くらい検査にかかるものでした。 MRIを受けるときは金属なし(ベルト、マスクも含む)の服装で受けます。 仰向けになってヘッドホンを付けた上に、体を少し縛った状態で機械の中に勝手に入っていきます。 びっくりしたのはスキャンの音がかなり大きいんですよね。 イメージとして工事の音が近くでするような感じですね。数分刻みで異なる大音量が聞こえてきます。そのうえ、不安になるような音だったりします。 ヘッドホン付けてても結構聞こえるので寝るのも難しいですね。 さらにMRIの中は狭いので閉所恐怖症の人じゃなくても怖さを感じますね。目をつむってればだいぶ気にはならなくなりますが… 料金は7,500円くらいでした。3割負担でこれくらいなので本来は約25,000円ですね。 とりあえず何もなくてよかったですが、まだふらつきがあるので心配です。 もしかしたら精神的な問題もあるかもしれないですね。実は以前も似たようなことがあったのですが、その時は数日で治ったので不安です。 年内に仕事をやめて他にやりたいことがあるので早めに治るといいんですけどね。ではでは。

2024年6月29日

短期売買と分析力が向上しそうな株価予測をだらだらとやる part5

前回のあらすじ オシレータ系指標とその他の指標について確認しました。 今回は実際にコードに落とし込んで、グラフで見てみようと思います。 作成したコード 今回はとりあえずトレンド系指標の説明変数を見てみたいと思います。クラスかはまだやってないので、いずれやっておきます。 import pandas as pd import numpy as np import matplotlib.pyplot as plt import os out_fol = "./stock_data/" import glob stock_list = glob.glob(out_fol + "*.csv") def moveing_average(df): # 単純移動平均線(SMA)の計算 df['SMA'] = df['Adj Close'].rolling(window=20).mean() # 指数平滑移動平均線(EMA)の計算 df['EMA'] = df['Adj Close'].ewm(span=20, adjust=False).mean() # グラフのプロット plt.figure(figsize=(14, 7)) plt.plot(df['Adj Close'], label='Close Price', color='black') plt.plot(df['SMA'], label='20-Day SMA', color='blue') plt.plot(df['EMA'], label='20-Day EMA', color='red') plt.title('Stock Price with 20-Day SMA and 20-Day EMA') plt.xlabel('Date') plt.ylabel('Price') plt.legend() plt.grid(True) plt.show() def macd(df): # 短期EMA(12日)の計算 short_ema = df['Adj Close'].ewm(span=12, adjust=False).mean() # 長期EMA(26日)の計算 long_ema = df['Adj Close'].ewm(span=26, adjust=False).mean() # MACDラインの計算 df['MACD'] = short_ema - long_ema # シグナルラインの計算(9日間のMACDのEMA) df['Signal_Line'] = df['MACD'].ewm(span=9, adjust=False).mean() # MACDヒストグラムの計算 df['MACD_Histogram'] = df['MACD'] - df['Signal_Line'] # グラフのプロット plt.figure(figsize=(14, 7)) # 終値のプロット plt.subplot(2, 1, 1) plt.plot(df['Close'], label='Close Price', color='black') plt.title('Stock Price and MACD') plt.xlabel('Date') plt.ylabel('Price') plt.legend() # MACDとシグナルラインのプロット plt.subplot(2, 1, 2) plt.plot(df['MACD'], label='MACD', color='blue') plt.plot(df['Signal_Line'], label='Signal Line', color='red') plt.bar(df.index, df['MACD_Histogram'], label='MACD Histogram', color='gray') plt.xlabel('Date') plt.ylabel('Value') plt.legend() plt.tight_layout() plt.show() def bollinger_bands(df): # 中央バンド(20日間の単純移動平均線)の計算 df['Middle_Band'] = df['Adj Close'].rolling(window=20).mean() # 標準偏差の計算 df['STD'] = df['Adj Close'].rolling(window=20).std() # 上部バンドの計算 df['Upper_Band'] = df['Middle_Band'] + (2 * df['STD']) # 下部バンドの計算 df['Lower_Band'] = df['Middle_Band'] - (2 * df['STD']) # 過熱感の判断 df['bands_buy_flg'] = df['Adj Close'] > df['Lower_Band'] df['bands_sell_flg'] = df['Adj Close'] < df['Upper_Band'] # グラフのプロット plt.figure(figsize=(14, 7)) plt.plot(df['Adj Close'], label='Close Price', color='black') plt.plot(df['Middle_Band'], label='Middle Band (SMA 20)', color='blue') plt.plot(df['Upper_Band'], label='Upper Band (Middle + 2*STD)', color='red') plt.plot(df['Lower_Band'], label='Lower Band (Middle - 2*STD)', color='green') plt.fill_between(df.index, df['Upper_Band'], df['Lower_Band'], color='grey', alpha=0.1) plt.scatter(df.index[df['bands_buy_flg']], df['Adj Close'][df['bands_buy_flg']], label='bands_buy_flg', color='red', marker='o') plt.scatter(df.index[df['bands_sell_flg']], df['Adj Close'][df['bands_sell_flg']], label='bands_sell_flg', color='green', marker='o') plt.title('Bollinger Bands with bands_buy_flg and bands_sell_flg Signals') plt.xlabel('Date') plt.ylabel('Price') plt.legend() plt.grid(True) plt.show() def ichimoku_kinko_hyo(df): # 転換線(過去9日間の最高値と最安値の平均値) df['Tenkan_sen'] = (df['High'].rolling(window=9).max() + df['Low'].rolling(window=9).min()) / 2 # 基準線(過去26日間の最高値と最安値の平均値) df['Kijun_sen'] = (df['High'].rolling(window=26).max() + df['Low'].rolling(window=26).min()) / 2 # 先行スパン1(転換線と基準線の平均値を26日先にプロット) df['Senkou_Span_A'] = ((df['Tenkan_sen'] + df['Kijun_sen']) / 2).shift(26) # 先行スパン2(過去52日間の最高値と最安値の平均値を26日先にプロット) df['Senkou_Span_B'] = ((df['High'].rolling(window=52).max() + df['Low'].rolling(window=52).min()) / 2).shift(26) # 遅行スパン(現在の終値を26日遅らせてプロット) df['Chikou_Span'] = df['Adj Close'].shift(-26) # 雲の上・下の判定とシグナル df['Signal'] = np.where(df['Tenkan_sen'] > df['Kijun_sen'], 'Buy', 'Sell') df['Trend'] = np.where(df['Adj Close'] > df[['Senkou_Span_A', 'Senkou_Span_B']].max(axis=1), 'Uptrend', np.where(df['Adj Close'] < df[['Senkou_Span_A', 'Senkou_Span_B']].min(axis=1), 'Downtrend', 'Neutral')) # グラフのプロット plt.figure(figsize=(14, 7)) plt.plot(df['Adj Close'], label='Close Price', color='black') plt.plot(df['Tenkan_sen'], label='Tenkan-sen (Conversion Line)', color='blue') plt.plot(df['Kijun_sen'], label='Kijun-sen (Base Line)', color='red') plt.plot(df['Senkou_Span_A'], label='Senkou Span A (Leading Span 1)', color='green') plt.plot(df['Senkou_Span_B'], label='Senkou Span B (Leading Span 2)', color='orange') plt.plot(df['Chikou_Span'], label='Chikou Span (Lagging Span)', color='purple') # 先行スパンの領域を塗りつぶす plt.fill_between(df.index, df['Senkou_Span_A'], df['Senkou_Span_B'], where=df['Senkou_Span_A'] >= df['Senkou_Span_B'], color='lightgreen', alpha=0.5) plt.fill_between(df.index, df['Senkou_Span_A'], df['Senkou_Span_B'], where=df['Senkou_Span_A'] < df['Senkou_Span_B'], color='lightcoral', alpha=0.5) plt.title('Ichimoku Kinko Hyo (Ichimoku Cloud)') plt.xlabel('Date') plt.ylabel('Price') plt.legend() plt.grid(True) plt.show() # シグナルとトレンドの表示 print(df[['Adj Close', 'Tenkan_sen', 'Kijun_sen', 'Signal', 'Trend']].tail(30)) def directional_movement_index(df): # True Range(TR)の計算 df['TR'] = df[['High', 'Low', 'Adj Close']].apply(lambda x: max(x['High'] - x['Low'], abs(x['High'] - x['Adj Close']), abs(x['Low'] - x['Adj Close'])), axis=1) # +DMと-DMの計算 df['+DM'] = df['High'].diff().apply(lambda x: x if x > 0 else 0) df['-DM'] = df['Low'].diff().apply(lambda x: -x if x < 0 else 0) # 14期間のTR、+DM、-DMの合計 df['TR14'] = df['TR'].rolling(window=14).sum() df['+DM14'] = df['+DM'].rolling(window=14).sum() df['-DM14'] = df['-DM'].rolling(window=14).sum() # +DIと-DIの計算 df['+DI14'] = 100 * (df['+DM14'] / df['TR14']) df['-DI14'] = 100 * (df['-DM14'] / df['TR14']) # DXの計算 df['DX'] = 100 * (abs(df['+DI14'] - df['-DI14']) / (df['+DI14'] + df['-DI14'])) # ADXの計算 df['ADX'] = df['DX'].rolling(window=14).mean() # シグナルとトレンド強度の判定 df['Signal'] = np.where(df['+DI14'] > df['-DI14'], 'Buy', 'Sell') df['Trend_Strength'] = np.where(df['ADX'] >= 25, 'Strong', 'Weak') # ADXのトレンド(前日と比べて上昇または下降を判定) df['ADX_Trend'] = df['ADX'].diff().apply(lambda x: 'Uptrend' if x > 0 else 'Downtrend' if x < 0 else 'No Change') # グラフのプロット plt.figure(figsize=(14, 7)) plt.plot(df['+DI14'], label='+DI (Positive Directional Indicator)', color='green') plt.plot(df['-DI14'], label='-DI (Negative Directional Indicator)', color='red') plt.plot(df['ADX'], label='ADX (Average Directional Index)', color='blue') plt.title('DMI (Directional Movement Index)') plt.xlabel('Date') plt.ylabel('Value') plt.legend() plt.grid(True) plt.show() # 結果の表示 print(df[['+DI14', '-DI14', 'ADX', 'Signal', 'Trend_Strength']].tail(30)) def parabolic(df): # パラボリックSARの計算 df['SAR'] = np.nan df['EP'] = np.nan df['AF'] = np.nan # 初期値設定 initial_trend = 'up' if df['Adj Close'].iloc[1] > df['Adj Close'].iloc[0] else 'down' initial_AF = 0.02 max_AF = 0.2 # 初期SAR、EP、AFの設定 df.at[df.index[1], 'SAR'] = df['Low'].iloc[0] if initial_trend == 'up' else df['High'].iloc[0] df.at[df.index[1], 'EP'] = df['High'].iloc[1] if initial_trend == 'up' else df['Low'].iloc[1] df.at[df.index[1], 'AF'] = initial_AF # パラボリックSARの計算ループ for i in range(2, len(df)): prev_SAR = df['SAR'].iloc[i-1] prev_AF = df['AF'].iloc[i-1] prev_EP = df['EP'].iloc[i-1] trend = 'up' if df['Adj Close'].iloc[i-1] > prev_SAR else 'down' if trend == 'up': SAR = prev_SAR + prev_AF * (prev_EP - prev_SAR) EP = max(prev_EP, df['High'].iloc[i]) AF = min(prev_AF + 0.02, max_AF) if df['High'].iloc[i] > prev_EP else prev_AF else: SAR = prev_SAR - prev_AF * (prev_SAR - prev_EP) EP = min(prev_EP, df['Low'].iloc[i]) AF = min(prev_AF + 0.02, max_AF) if df['Low'].iloc[i] < prev_EP else prev_AF # トレンドの反転 if trend == 'up' and df['Low'].iloc[i] < SAR: SAR = prev_EP EP = df['Low'].iloc[i] AF = initial_AF trend = 'down' elif trend == 'down' and df['High'].iloc[i] > SAR: SAR = prev_EP EP = df['High'].iloc[i] AF = initial_AF trend = 'up' df.at[df.index[i], 'SAR'] = SAR df.at[df.index[i], 'EP'] = EP df.at[df.index[i], 'AF'] = AF # シグナルの判定 df['Signal'] = np.where((df['Adj Close'].shift(1) < df['SAR'].shift(1)) & (df['Adj Close'] > df['SAR']), 'Sell', np.where((df['Adj Close'].shift(1) > df['SAR'].shift(1)) & (df['Adj Close'] < df['SAR']), 'Buy', np.nan)) # グラフのプロット plt.figure(figsize=(14, 7)) plt.plot(df['Adj Close'], label='Close Price', color='black') plt.plot(df['SAR'], label='Parabolic SAR', linestyle='dashed', color='blue') plt.scatter(df[df['Signal'] == 'Buy'].index, df[df['Signal'] == 'Buy']['Adj Close'], marker='^', color='green', label='Buy Signal', s=100) plt.scatter(df[df['Signal'] == 'Sell'].index, df[df['Signal'] == 'Sell']['Adj Close'], marker='v', color='red', label='Sell Signal', s=100) plt.title('Parabolic SAR with Buy and Sell Signals') plt.xlabel('Date') plt.ylabel('Price') plt.legend() plt.grid(True) plt.show() # 結果の表示 print(df[['Adj Close', 'SAR', 'EP', 'AF', 'Signal']].tail(30)) def Envelope(df): # エンベロープの計算 percentage = 0.02 # 2% のエンベロープ df['Upper Envelope'] = df['SMA'] * (1 + percentage) df['Lower Envelope'] = df['SMA'] * (1 - percentage) # シグナルの判定 df['Signal'] = np.where(df['Adj Close'] > df['Upper Envelope'], 'Sell', np.where(df['Adj Close'] < df['Lower Envelope'], 'Buy', np.nan)) # グラフのプロット plt.figure(figsize=(14, 7)) plt.plot(df['Adj Close'], label='Close Price', color='black') plt.plot(df['SMA'], label='20-Day SMA', color='blue') plt.plot(df['Upper Envelope'], label='Upper Envelope (SMA + 2%)', color='green') plt.plot(df['Lower Envelope'], label='Lower Envelope (SMA - 2%)', color='red') plt.scatter(df[df['Signal'] == 'Buy'].index, df[df['Signal'] == 'Buy']['Adj Close'], marker='^', color='green', label='Buy Signal', s=100) plt.scatter(df[df['Signal'] == 'Sell'].index, df[df['Signal'] == 'Sell']['Adj Close'], marker='v', color='red', label='Sell Signal', s=100) plt.title('Envelopes with Buy and Sell Signals') plt.xlabel('Date') plt.ylabel('Price') plt.legend() plt.grid(True) plt.show() # 結果の表示 print(df[['Adj Close', 'SMA', 'Upper Envelope', 'Lower Envelope', 'Signal']].tail(30)) for stock_data in stock_list: # データフレームの作成 df = pd.read_csv(stock_data) df['Date'] = pd.to_datetime(df['Date']) df.set_index('Date', inplace=True) moveing_average(df) macd(df) bollinger_bands(df) ichimoku_kinko_hyo(df) directional_movement_index(df) parabolic(df) Envelope(df) os.system("pause") 実行結果の確認 コードの作成が完了したので実行してグラフを見てみます。実行したデータはAppleの20年分とMcDonald’sの1年分になります。比較してみてみようと思います。 ...

2024年6月25日

短期売買と分析力が向上しそうな株価予測をだらだらとやる part4

前回までのあらすじ 株価の基本情報とトレント系指標について見てみました。 今回はオシレーター系指標とその他について見ていこうと思います。 技術分析データ オシレーター系指標 RSI(相対力指数): 株価の過熱感を示す指標。 サイコロジカルライン:一定期間の中で株価が上昇した日数の割合を示す。市場の投資家心理を測る指標。 RCI:日付の順位と価格の順位の相関関係を示し、トレンドの強さを判断する指標。 移動平均線乖離率:現在の株価と移動平均線との乖離を示しす。価格が移動平均線からどれだけ離れているかを判断する指標。 スローストキャスティクス:ストキャスティクスの変動を滑らかにする。買われ過ぎや売られ過ぎの状態をより安定して示す指標。 モメンタムとROC:モメンタムは価格の変化のスピードを示す。ROCは一定期間の価格変動率を示す指標。 MFI:出来高を加味したRSIに似た指標。買われ過ぎや売られ過ぎを判断するための指標。 CCI:価格と移動平均線の乖離を基に、トレンドの強さと異常値を判断する指標。 その他 ヒストリカル・ボラティリティ:過去の一定期間の価格変動の大きさを測定した指標。 ギャップ(ギャップアップ、ギャップダウン):前日の終値と当日の始値の差で市場の初期のトレンド。 レジスタンスライン:株価が上昇する際に止まりやすい価格帯のこと。 サポートライン:株価が下落する際に止まりやすい価格帯のこと。 軽く調べただけでこれくらいあるんですね。ローソク足を使ったりチャートの動きを使う指標もありましたが、今回は割愛します。他にも使いたいデータはありますので。 技術分析データ_補足説明 RSI (Relative Strength Index, 相対力指数) 株価の過熱感を示すオシレータータイプの指標で0~100の範囲で表す。14日間のデータを使用するのが一般的。 70以上: 買われ過ぎ(Overbought)を示し、価格の反転を予想。 30以下: 売られ過ぎ(Oversold)を示し、価格の上昇を予想 RCI(Rank Correlation Index) 株価の日付順位と価格順位の相関を示す指標。トレンドの強さと方向を判断するために使用される。 各日付に順位を付ける(最新の日を1位とする)。各価格にも順位を付ける(高い価格を1位とする)。日付順位と価格順位の差を二乗して合計。RCIを計算。 RCI=1 − 6∑(日付順位−価格順位)^2 / n(n^2−1) 移動平均線乖離率(Moving Average Convergence Divergence, MACD) 現在の株価と移動平均線との乖離を示す。価格が移動平均線からどれだけ離れているかを判断する指標。 移動平均線(通常は25日移動平均線)を計算。現在の株価と移動平均線の差を求める。その差を移動平均線で割り、百分率で表示する。 乖離率=(現在の株価 − 移動平均線) / 移動平均線 ×100 乖離率が大きくマイナスに乖離した後に反転したら買いシグナル。乖離率が大きくプラスに乖離した後に反転したら売りシグナル スローストキャスティクス(Slow Stochastic Oscillator) ストキャスティクスの変動を滑らかにする。買われ過ぎや売られ過ぎの状態をより安定して示す指標 ストキャスティクスとは価格が特定の期間内でどれだけ高値と安値の間にあるかを示す指標。スロー以外にもファストがあるがここでは割愛。 過去N日間(通常は14日間)の最高値と最安値を求める。現在の終値から最安値を引き、最高値と最安値の差で割る。この値に100を掛ける。%Kの値が出る。過去3日間の%Kラインの平均を求める。%Dの値が出る。%Dの単純移動平均を求める。Slow%Dの値が出る。 スロー%Dが20以下から上昇し始めたら買いシグナル、スロー%Dが80以上から下落し始めたら売りシグナル。 モメンタム(Momentum) 一定期間内の価格変動の速度や勢いを示す指標。トレンドの強さや反転の可能性を判断する。プラスの値は上昇トレンドを、マイナスの値は下降トレンドを示す。 momentum = 現在の株価 - N期間前の株価 ROC(Rate of Change) モメンタムを百分率で表したもので、トレンドの強さを評価する。プラスの値は上昇トレンドを、マイナスの値は下降トレンドを示す.。 ROC = ((現在の株価 - N期間前の株価) / N期間前の株価) * 100 MFI(Money Flow Index) 出来高を加味したRSIに似た指標で、市場の過熱感を判断するために使用される。MFIが80以上で下落し始めたら売りシグナル、20以下で上昇し始めたら買いシグナル。 TP = H + L + C / 3 (TP: その日の取引価格の中央値、H: 最高値、L: 最安値、C: 終値) ...

2024年6月22日

短期売買と分析力が向上しそうな株価予測をだらだらとやる part3

株価予測_前回のおさらい 前回はティッカー一覧を取得できたので、株価を取得する方法を書きました。株価取得のコードはpart1とそこまで大きな差はないですが… 株価予測_今回やること 今回は予測の前に使用する変数について記載していきます。 株価で取得した値は6つになります。 ただし、トレーダーの一部の人は組み合わせて説明変数を作って使っていると思います。 なのでChat-GPTに質問を投げた後、説明変数を見ていこうと思います。 株価とは 特定の時間における株式の市場価格を示します。この値は技術分析で使用される「移動平均線、RSI、MACD」などで使用されます。株価の情報は以下のデータが存在します。 変数名 説明 Open(始値) 引日の最初の取引価格。ギャップを分析できる。 High(高値) 取引日の中で最も高い取引価格。レジスタンラインの形成にも使用する。 Low(安値) 取引日の中で最も低い取引価格。サポート来の形成にも使用する。 Close(終値) 取引日の最後の取引価格。 Adj Close(調整後終値) 分割や配当を調整した後の終値。 Volume(出来高) 取引日の中で売買された株式の総数。 出来高についての補足 特定の期間に取引された株式の数量を示します。出来高の増減は市場の関心度やトレンドの強さを示します。また、高い出来高を伴う価格変動は信頼性が高く、トレンドが続く可能性がある。 技術分析データについて 株価からわかる基本的な情報はこれで以上になります。この情報を組み合わせて変数を作り、そのデータを株価予測に使用していきます。次は技術分析についてです。 技術分析はザックリ分けると以下の2タイプに分かれます。 トレンド系指標(順張り系指標) オシレーター系指標(逆張り系指標) この2つを組み合わせることでだましに合わず有効活用できると言われています。※だまし(理論通りの動きとならず反対の動きをすること) まずはトレンド系指標から見ていこうと思います。他にも指標はありますが文量が多くなるので次回に回します。 トレンド系指標 移動平均線: 一定期間の平均株価。 MACD(移動平均収束拡散法): 短期と長期の移動平均線の差。 ボリンジャーバンド: 株価の変動範囲を示す指標。 一目均衡表:市場のトレンド、サポート・レジスタンス、買い・売りのシグナルを同時に把握できる総合的なテクニカル指標。 DMI:上昇トレンドと下降トレンドの強さを示し、相場の方向性を判断するための指標。 パラボリック:トレンドの転換点を示し、上昇トレンドでは株価の下、下降トレンドでは株価の上に点を描く指標。 エンベロープ:一定期間の移動平均線に対して上下に一定割合だけ離れたバンドを描き、過熱感を判断する指標。 技術分析データ_補足説明 移動平均線 (Moving Average, MA) 一定期間の平均株価を計算し、その期間が過ぎると新しいデータで更新される指標。 単純移動平均線 (Simple Moving Average, SMA):指定された期間の株価の平均値を計算。例:5日移動平均線、25日移動平均線、75日移動平均線 指数平滑移動平均線 (Exponential Moving Average, EMA):最近のデータに重みを置いて計算する移動平均線。 MACD (Moving Average Convergence Divergence, 移動平均収束拡散法) 短期のEMAと長期のEMAの差を基にした指標。3つの要素で構成され、MACDラインがシグナルラインを上抜けると買いシグナル、下抜けると売りシグナルとされる。 MACDライン: 12日EMAと26日EMAの差 シグナルライン: 9日EMA(MACDラインのEMA) ...

2024年6月19日

WordPressにパスキーを導入してセキュリティ意識を高めよう!

はじめに ここ最近セキュリティに関するニュースが後を絶たないですね…。例えば 岡山の病院で患者情報流出 ニコニコ動画サイバー攻撃 積水ハウス個人情報流出 流出や攻撃だけでも頻繁に起きますし、脆弱性の発見も日々起こっています。こちらのサイトなどで見ることができます。 そこで自身もセキュリティ意識を高めるため、パスワードではなくパスキーを使ったWordPressのログインを試みようという話になります。 設定手順 まずはWordPressにログインして「OwnID Passwordless Login」をインストールします。その後設定画面に移動すると以下の画像画面に行くので、「OwnID Console.」をクリックします。 OwnID Console画面に入ったらアカウントを作ってログインしましょう!Githubがあればそちらでも大丈夫です。 ログインができたら「Create Application」でアプリの作成を行います。 まずはアプリ名を決めましょう。適当で大丈夫です。 アプリ名を決めたら使用するシステムを選択しましょう!今回の場合はWordPressになります。 もし開発に使用する場合は以下から選択することになると思います。いつか開発で使ってみたいですね。 WordPressの場合は自身のURLサイトを設定しましょう。 設定が完了したら準備完了です! 複数サイト設定 ここから先は複数作る場合になります。カスタムドメインで作ると複数パターン設定できます。 カスタムドメインをまずは作ります。基本は「passwordless.あなたのドメイン」で設定します。 カスタムドメインの設定が完了したらDNSにStep1とStep2の値を設定します。 設定が完了してチェックが通れば「Verified」になります。 設定が完了したら「App ID」と「Shared Secret」の画面を出したまま、WordPressの画面に戻ります。 OwnIDの設定画面で先ほどのApp IDとShared secretを入力して完了です。 ...

2024年6月16日

短期売買と分析力が向上しそうな株価予測をだらだらとやる part2

前回までの話 前回ティッカーが取れないという話をしたがあれは嘘だ。 pyppeteerを使うといったがあれも嘘だ。 ティッカー取得時の注意点 前回作成したものからほとんど変えることなくSBIに記載されている全てのティッカーを取得することができました。 ただ、注意点があります。 アメリカ以外の国ではティッカーの後に特定の文字列をつける必要がある。 ベトナムの「DCL」であれば後ろに「.VN」をつけて「DCL.VN」にする必要がある。 中国(香港)の「000621」であれば後ろに「.HK」をつけて、さらに前の0を削除して「00621.HK」にする必要がある。 シンガポールとマレーシアに関しては扱うティッカーの文字列がそもそも違うので使えない。 日本の場合は東京で扱っているものは後ろに「.T」、札幌であれば「.S」が必要。 前回の修正箇所 日本はまだ取得してないですが上記の点に注意して、コード書いていく必要があります。修正した個所はここ sbi_foreign_stock_list = [ {"america": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_usequity_list.html", "tag": "table", "c_cd":"", "class": "foo_table md-l-table-01 md-l-utl-mt10"}}, {"china": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_hk_list.html", "tag": "div", "c_cd":".HK", "class": "accTbl01"}}, {"korea": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_kr_list.html", "tag": "div", "c_cd":".KS", "class": "accTbl01"}}, {"russia": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_ru_list.html", "tag": "div", "c_cd":".ME", "class": "accTbl01"}}, {"vietnam": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_vn_list.html", "tag": "div", "c_cd":".VN", "class": "accTbl01"}}, {"Indonesia": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_id_list.html", "tag": "div", "c_cd":".JK", "class": "accTbl01"}}, # {"Singapore": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_sg_list.html", "tag": "div", "c_cd":".SI", "class": "accTbl01"}}, # SBIとyahooのティカーが一致しない件 {"thailand": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_th_list.html", "tag": "div", "c_cd":".BK", "class": "accTbl01"}}, # {"malaysia": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_my_list.html", "tag": "div", "c_cd":".KL", "class": "accTbl01"}}, # SBIとyahooのティカーが一致しない件(SBIは英略、yahooは数値) ] 株価取得コード 修正するとティッカーリストが作られるので、取得したティッカーリストをもとに株価を取得すると以下のようなコードになります。 ...

2024年6月13日

短期売買と分析力が向上しそうな株価予測をだらだらとやる part1

前回RAGシステムを作ってみてある程度できました。次に、何を作ろうかということで表題になります。 前回と違って完成形は全く思い浮かんでません。とりあえずやってれば何かできるかということで作っていきます。 ティッカー取得 まずは株価の取得が必要なのですが今回はyahoo! financeのAPIを使って取得しようと思います。取得する際のコードは以下。 import pandas_datareader.data as web df = web.get_data_yahoo('1304', '1980-01-01', '2024-06-10') pandas_datareaderにyahoo用の株価取得ライブラリがあるのでそれを利用します。ティッカー(銘柄)と株価取得の時間を設定します。 株価の取得は簡単なのですが、ティッカーをいちいち手入力するのは面倒ですね。時間は変数で設定できますので問題ないです。 というわけでティッカーを取得するプログラムを作ります。 ティッカーを取得するには東京証券取引所、名古屋証券取引所、福岡証券取引所、札幌証券取引所、各国別SBI証券ティッカー一覧から取れると思いますが、今回はSBI証券から取得しようと思います。 昔やろうとしたことがあったのでそれを流用しようと思います。対象となるサイトはこちらです。 ティッカー取得プログラム # SBI証券から海外のティッカーまたはコードと銘柄を取得 from bs4 import BeautifulSoup import re, sys, time import requests import pandas as pd sbi_foreign_stock_list = [ {"america": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_usequity_list.html", "tag": "table", "c_cd":"", "class": "md-l-table-01 md-l-utl-mt10"}}, {"china": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_hk_list.html", "tag": "div", "c_cd":"HK", "class": "accTbl01"}}, {"korea": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_kr_list.html", "tag": "div", "c_cd":"KS", "class": "accTbl01"}}, {"russia": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_ru_list.html", "tag": "div", "c_cd":"ME", "class": "accTbl01"}}, {"vietnam": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_vn_list.html", "tag": "div", "c_cd":"VN", "class": "accTbl01"}}, {"Indonesia": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_id_list.html", "tag": "div", "c_cd":"JK", "class": "accTbl01"}}, {"Singapore": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_sg_list.html", "tag": "div", "c_cd":"SI", "class": "accTbl01"}}, # SBIとyahooのティカーが一致しない件 {"thailand": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_th_list.html", "tag": "div", "c_cd":"BK", "class": "accTbl01"}}, {"malaysia": {"url": "https://search.sbisec.co.jp/v2/popwin/info/stock/pop6040_my_list.html", "tag": "div", "c_cd":"KL", "class": "accTbl01"}} # SBIとyahooのティカーが一致しない件 ] for foreign_dict in sbi_foreign_stock_list: for country, values in foreign_dict.items(): country_url = values["url"] country_tag = values["tag"] country_code = values["c_cd"] country_class = values["class"] html = requests.get(country_url) soup = BeautifulSoup(html.content, "html.parser") for table_soup in soup.find_all(country_tag, class_=country_class): stock_data = [] rows = table_soup.find_all("tr") for row in rows[1:]: ticker = row.find_all("th")[0].text.strip() cols = row.find_all("td") name = cols[0].text.strip() stock_data.append((ticker, name)) continue df_foreign_stock = pd.DataFrame(stock_data, columns=["コード", "銘柄名"]) df_foreign_stock["コード"] = df_foreign_stock["コード"].astype(str) + country_code df_foreign_stock.to_csv(out_oth_fol + country + "_stock_list.csv") time.sleep(2) これを流用すれば取得できますが、今のサイトではできません。少し前のサイトがこちらです。こちらであれば取得できますが、最新のティッカー情報が取れないので修正します。 ...

2024年6月10日

最近読んだ"プログラマー脳"はプログラムを書く人は読んだほうが関わる人全員が幸せになる話だった

読書習慣とおすすめの一冊「プログラマー脳」 読書をするということを習慣化しているのですが、たまたまどっかの記事で見かけて買ったプログラマー脳は読んでおくといいなと思ったので記事にしました。こちらから買えます。 私の読書習慣 ちなみに私の読書週間としては 毎日20:30~21:30までは読書をする 電車に乗って満員200%じゃなければ読む(大体10分ほど) 没頭するほど集中力が続かないこともあるのでちょこちょこ休憩しながら読んでいます。 読書のスタイル 読み方は状況によりけりですが、例を出すところは飛ばすことが多いです。実体験や見聞きしたことよりは論文やデータから見た考察とかのほうが個人的にはいいかなと思うので。 人によっては例があったほうがイメージがわかりやすいので、そっちを中心に読む人もいるかと思いますが、全てを読む必要はないかなと思います。特にある程度知っている内容なら。 感想と本書の概要 本の要約は場合によっては著作権違反になったりするので、私の感想をメインにしつつ引用を少し出しながら書いていこうと思います。 この本で一貫して書かれていることが認知負荷を減らすようにしましょうという話になります。 認知負荷とプログラミング 人間には短期記憶、長期記憶、ワーキングメモリがあり、短期記憶はコードに置き換えると変数、長期記憶は構文(forやif等)、ワーキングメモリは処理の内容になります。認知負荷はワーキングメモリに関わってきます。 コードを読むときにどんな処理になっているのがわからないということがあります。その時、単純に言語の情報が足りないのか?構文がわかっていないのか?処理内容がわかってないのか?ということがあります。ドメイン知識も関係してそうですがここでは言及されていません。 認知負荷の軽減方法 言語の情報や構文についてはある程度調べて覚えれば大丈夫なのですが処理内容に関しては自身の記憶だけではどうにもなりません。すでに書いてあるものを改修したりする場合は大変な作業になると思います。 ちなみに本書では言語の構文などの覚え方や定着の仕方なども言及しているので、気になればぜひ読んでみてください。 命名やコードの整理の重要性 認知負荷についてはいくつか気を付けるポイントが書いてあり、命名の仕方やコードを適切に分けて関数化することについて書いています。関数化じゃなくてもクラス化でもいいと思います。 他人のコードを読む際のコツ それから人のコードを読む際に良い方法も書いてあります。変数同士を結び付けて紙に書いたり、パッドで書き込むのもいいと思います。 割り込みタスクと新人サポートについて 他の内容としては割り込みタスクが入るや新人へのサポートについて書かれていました。ここもためになりますね。 読書の重要性 本を読むといろんなことが知れます。技術的な面ももちろん必要ですが、メンタルや考え方なども必要だと思います。 他にも本を読んでいるのでいくつか面白いものがあれば紹介したいなとは思います。 Kindle Unlimitedのおすすめ ちなみにKindle Unlimitedは速く本を読んで理解するのにおススメです。月額で読み放題だし、内容が薄いものはバンバン飛ばし読みもできるので練習にもなります。ではでは。

2024年6月7日

ニューラルネットワークの仕組みを理解しているかテストするためのゲームで遊ぶ

機械学習と深層学習の復習 G検定やE資格である程度機械学習や深層学習で使われている技術を学んだのですが、特に深層学習についてはあやふやな部分が多いなと感じていました。 とはいえまた学習教材を買うのもと思ってましたが、良いサイトを見つけました。 Graph Game: ニューラルネットワークの理解度をテスト Graph Gameというニューラルネットワークを理解しているかわかるサイトになります。(こちらから遊べます。) とはいえこのサイトでできるのはRNN、LSTM、GRU、ResNet、Deep RNNのテストになります。CNNやGANなどはテストできません。 RNNのテスト まずはRNNから試してみましょう。“clicks” は繋げた回数、“edges remaining” は繋げる必要がある本数、“extra edges” は余計な繋がりの本数になります。 RNNについて補足すると連続的なデータや時系列データを処理するのに最適です。株価などの時系列分析、テキスト生成、音声認識など様々なところに使われる重要なニューラルネットワークです。 ちなみにHelpはチュートリアルの確認になります。 もし正解できれば画面の文字が左上にでます。何回でも挑戦できるので理解しながらつなげてみましょう! LSTMのテスト LSTMはこんな感じ。 長い依存関係を持つ時系列データの処理に向いています。RNNでは勾配消失問題が発生するのでそれを解消するために考えられました。3つ(入力、忘却、出力)のゲートを使って重要なデータは保持、不要なデータは捨てます。 GRUのテスト GRUはこんな感じ。 補足するとGRUはLSTMの精度を保ったまま計算量が少ないと言われています。GRUは2つ(リセット、更新)のゲートで情報を制御します。 ResNetのテスト ResNetはこんな感じ 補足すると深い層のニューラルネットワークで使われ、画像認識で使用されています。残差ブロックがあり、skip connectionで直接値を渡すことで勾配消失問題が解消されます。 Deep RNNのテスト 最後にDeep RNNはこんな感じ。 Deep RNNの補足としては複数のRNN層を組み合わせたものになります。より複雑なパターンを学習することができます。 まとめと感想 少し忘れていたのでここで視覚的に思い出せました。初めての人でもなんとなくでわかるようになるし、ある程度知っている人も視覚的に覚えられるので良いと思います。 忘れていた処理を思い出せたので良かったです。他の深層学習や機械学習でも視覚的にわかるようなサイトがあるとイメージが付きやすそうですね。ではでは。

2024年6月5日