USDJPYの動きを予測する0
やること
USDJPYの動きをランダムフォレストを用いて予測する。
サイン点灯(上がるという予測がでたら)ポジションを取り基本的に1日でクローズするという簡単な設定でまずやってみる。
参考サイト
Python scikit-learnのランダムフォレストで受診予約のNo-Showを予測する - け日記
コード
import asset_df import numpy as np import pandas as pd import seaborn as sns from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import f1_score def calc_rsi(inp: pd.Series) -> pd.Series: diff = inp.diff() up, down = diff.copy(deep = True), diff.copy(deep = True) up[up < 0] = 0 down[down > 0] = 0 up_sma_14 = up.rolling(window = 14).mean() down_sma_14 = down.abs().rolling(window = 14).mean() rs = up_sma_14 / down_sma_14 rsi = 100. - (100. / (rs + 1.)) rsi.name = 'RSI' return rsi # make DataFrame df = asset_df.make_df() # % USDJPY = df['USDJPYCR'] # USDJPY.head(10) # make correct answer flag y = USDJPY.apply(lambda x:1 if x > 0 else 0) y.name = 'UpDown' # data in sample ma_5 = USDJPY.rolling(window = 5).mean() # moving average in 5 days ma_5.name = 'MA5' ma_20 = USDJPY.rolling(window = 20).mean() # moving average in 20 days ma_20.name = 'MA20' rsi = calc_rsi(USDJPY) # RSI(14 days) sample = pd.concat([ma_5, ma_20, rsi], axis = 1) # merge data data = pd.concat([y, sample], axis = 1) data = data.dropna() # data.head(5) ma5_ = data['MA5'] ma20_ = data['MA20'] ma_diff = ma5_ - ma20_ ma_diff.name = 'MA5-MA20' data = pd.concat([data, ma_diff], axis = 1) # 特徴量の偏りをチェック sns.set() data.hist(figsize = (12,12)) # random forest features = data.drop('UpDown', axis = 1).values label = data['UpDown'] X_train, X_test, y_train, y_test = train_test_split(features, label, test_size = 0.3, random_state = 1234) clf = RandomForestClassifier(random_state = 1234) clf.fit(X_train, y_train) # 評価 print('Test score: {}'.format(clf.score(X_test, y_test))) print('Train score: {}'.format(clf.score(X_train, y_train))) print('f1 score: {:.3f}'.format(f1_score(y_test, clf.predict(X_test))))
結果
Test score: 0.7230878186968839 Train score: 0.978749241044323 f1 score: 0.719
train scoreがtest scoreよりかなり大きくなってしまい、過学習が起きていそう。これをもとに特徴量など改善していきたい。
個人的にまず気になったのが、RSI。一般的に20~30%を切ったら買い時、70~80%を超えたら売り時とされるが、ほぼ30~70%内で推移しており、予測に適しているのか疑問。次で詳しくみてみる。