MACD デシジョン ツリー モデルを使用した株価トレンドの予測

55beb1de8f2a80aa56819a3b46091672.gif

序文

前回述べたように、LSTM 時系列モデルは株価の予測に使用できます。株価テクニカル分析では、古典的な取引指標として常に売買のタイミングをガイドしてきた MACD が使用されます。今回は、この指標に基づいたディシジョン ツリー モデルを使用して、将来の株価動向を予測します。

基本的な考え方

MACDインジケーター

MACD (Moving Average Convergence/Divergence) は、1970 年代後半にジェラルド・アペルによって作成された、株価分析に使用されるテクニカル指標です。株価トレンドの強さ、方向性、勢い、期間の変化を明らかにすることを目的としています。

3bfb4ef5f6659c1ffb1a5f20e01d3b1d.png

MACDインジケーターは、過去の価格データ(通常は終値)に基づいて3つの時系列から計算されるインジケーターです。、つまり 3 つの EMA の時定数で、通常は「MACD(a, b, c)」と表されます。ここで、MACD シーケンスは、特性時間 a (短周期) と b (長周期) の指数移動平均 (EMA) の差であり、平均シーケンスは特性時間 c の MACD シーケンスの EMA です。

これらのパラメータは通常、日単位で測定されます。最も一般的に使用される値は 12、26、9 日、つまり MACD(12,26,9) です。ほとんどのテクニカル指標と同様に、MACD もテクニカル分析から循環パターンを見つけます。これまでは主に日足チャートに基づいていました。

以前は 1 週間の稼働日数が 6 日であったため、期間設定 (12、26、9) はそれぞれ 2 週間、1 か月、1 週間半を表します。取引週が 5 日しかない場合、それに応じてサイクル パラメーターを (10、20、7) のように調整することもできます。ただし、標準設定に基づいて売買を決定すると、その方向の価格にさらに影響を与える可能性があるため、ほとんどのトレーダーが使用する期間設定に固執することが最善です。

短期 EMA は、長期 EMA よりも最近の株価の変化に迅速に反応します。異なる期間の EMA を比較することにより、MACD シーケンスは株価のトレンドの変化を示すことができます。ダイバージェンスシリーズは株価トレンドの微妙な変化を明らかにすると言われています。

MACDは移動平均に基づいているため、遅行指標です。将来の価格動向を予測するための指標として、まったく不規則なレンジで取引される場合や価格が予測できない場合には、MACD をそのまま使用することはできません。そして、MACD がトレンドを示している場合、そのトレンドは完全またはほぼ完全です。

デシジョンツリーモデル

デシジョン ツリー モデルは、統計、データ マイニング、機械学習で使用される予測モデリング手法の 1 つです。予測モデルとしてデシジョン ツリーを使用し、ブランチで履歴データの観察を提示し、リーフで目標値を予測します。

4ed4aeeaace7eecd0d90b75e80490cd0.png

ターゲット値が一連の離散値の形式を取ることができる場合のツリー モデルは分類ツリーと呼ばれます。これらのツリー構造では、葉は分類ラベルを表し、枝はこれらの分類ラベルの特徴につながる結合を表します。 。目標値が連続値 (通常は実数) を取ることができる場合の決定木は、回帰木と呼ばれます。ここでの予測対象は株価であるため、回帰モデルが使用されます。

デシジョン ツリーは、その理解しやすさとシンプルさにより、最も人気のある機械学習アルゴリズムの 1 つです。意思決定分析では、意思決定ツリーを使用して、意思決定と意思決定を直観的かつ明確に表現できます。

つまり、MACD は平均的な指標であり、刻々と変化するリアルタイムの株価を直接反映することには適していませんが、一定期間にわたる価格の乖離の程度を反映するために使用できます。将来の期間を予測するための決定木、価格傾向。

環境整備

また、最初に新しいものを作成しjupyterライブラリをNotebookインポートします。sklearn

import math
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeRegressor
plt.style.use('fivethirtyeight')

データの準備

トランザクションデータを取得する

2015 年以降の履歴データを取得します。これは前の記事と同様なので、詳細は説明しません。

security = '510300.XSHG'
his_period = 60  # 历史时间
df = get_price(security, start_date="2015-01-05", end_date="2022-1-25", frequency='daily')

EMAの計算

3 つの時間パラメータを個別に計算します。現在は 5 日取引日ですが、依然として古典的な MACD (12、26、9) を使用しています。興味がある場合は、パラメータを自分で調整できます。

5a9200108651fa8cdf695564a8219cdd.png
ShortEMA = df.close.ewm(span=12, adjust=False).mean()
LongEMA = df.close.ewm(span=26, adjust=False).mean()
MACD = ShortEMA - LongEMA
signal = MACD.ewm(span=9, adjust=False).mean()

パラメータ曲線を視覚化する

macd_parameter = (12, 26, 9)
ShortEMA = df.close.ewm(span=macd_parameter[0], adjust=False).mean()
LongEMA = df.close.ewm(span=macd_parameter[1], adjust=False).mean()
MACD = ShortEMA - LongEMA
signal = MACD.ewm(span=macd_parameter[2], adjust=False).mean()
9e72f9b606dcfdf5c0ea1f8b00824a2c.png

インジケーター データをデータセットに保存する

df['MACD'] = MACD
df['Signal Line'] = signal
df.tail()
f41334fa234bea29950542d25834e8c8.png

売買シグナルを取得する

MACDクロスオーバーインジケーター、MACDがシグナルラインを下回った場合、それは売りの時期である可能性があるという弱気のシグナルです。逆に、MACD がシグナルラインを上回って上昇すると、インジケーターは強気のシグナルを送信し、資産価格に上昇の勢いがある可能性があることを示します。

def buy_sell(signal):
    Buy = []
    Sell = []
    flag = -1
    
    for i in range(0, len(signal)):
        if signal['MACD'][i] > signal['Signal Line'][i]:
            Sell.append(np.nan)
            if flag != 1:
                # 买入信号
                Buy.append(signal['close'][i])
                flag = 1
            else:
                Buy.append(np.nan)
        elif signal['MACD'][i] < signal['Signal Line'][i]:
            Buy.append(np.nan)
            if flag != 0:
                # 卖出信号
                Sell.append(signal['close'][i])
                flag = 0
            else:
                Sell.append(np.nan)
        else:
            Buy.append(np.nan)
            Sell.append(np.nan)
            
    return (Buy, Sell)

売買シグナルをデータセットにインポートする

df['Buy_Signal_Price'], df['Sell_Signal_Price'] = buy_sell(df)
df.head()
5380fbd3ba66315ef7bc86fa8fc4fda7.png

視覚的な売買シグナル

period = 500  # 可视化范围
plt.figure(figsize=(16,8))
plt.scatter(df.index[-period:], df['Buy_Signal_Price'][-period:], label="Buy", color='green', marker='^',alpha=1, linewidths=5)
plt.scatter(df.index[-period:], df['Sell_Signal_Price'][-period:], label="Sell", color='red', marker='v',alpha=1, linewidths=5)
plt.plot(df['close'][-period:], label='Close Price', alpha=0.35)
plt.title('Close Prcie Buy & Sell Signals')
plt.xlabel('Date', fontsize=18)
plt.ylabel('Close Price', fontsize=18)
plt.legend(loc='upper left')
plt.show()
b7a4978c2ea1bc71d036db4de061f3b4.png

図では緑が買いシグナル、赤が売りシグナルですが、変動が大きいときはこの指標が有効であることがわかりますが、変動が小さいときは底値で売って高値で買うケースが多いため、テクニカル指標は完全には信用できませんが、実戦ではやはり自己判断でお願いします。

デシジョンツリー回帰モデル

目標値の生成

今後 60 日間の傾向を予測する場合、まず終値データを 1 範囲分上方にシフトします。

# his_period = 60
df['Prediction'] = df[['close']].shift(-his_period)

データの前処理

以前に売買シグナルを視覚化したときは終値を使用しましたが、トレーニング データの漏洩を避けるために、これらのデータは最初に処理されてから、一連の特徴としてデータ セットにインポートされましたonehot

df['Buy_Signal_Price'][np.invert(df['Buy_Signal_Price'].isna())] = 1
df['Buy_Signal_Price'] = df['Buy_Signal_Price'].fillna(0)

df['Sell_Signal_Price'][np.invert(df['Sell_Signal_Price'].isna())] = 1
df['Sell_Signal_Price'] = df['Sell_Signal_Price'].fillna(0)

トレーニング セットとテスト セットを分割する

ここでは、今後 60 日間の傾向を予測するため、まずデータ セットを (2015 ~ 最初の 60 日間) に分割し、次にトレーニング セットを (2015 ~ 最初の 120 日間) とテスト セットに分割します。は (最初の 120 日間~(過去 60 日間))、つまり、過去 60 日間のデータを使用して次の 60 日間の傾向を予測します。

X = np.array(df.drop(['Prediction'],1)[:-his_period])
y = np.array(df['Prediction'][:-his_period])
x_train = X[:-his_period]
x_test = X[-his_period:]
y_train = y[:-his_period]
y_test = y[-his_period:]
print(x_train.shape, x_test.shape, y_train.shape, y_test.shape)

出力:(1601, 10) (60, 10) (1601,) (60,)

デシジョン ツリー モデルをトレーニングする

すべての準備が整ったので、sklearnライブラリを使用してDecisionTreeRegressorモデルを構築し、以前に分割されたトレーニング セットを使用してモデルをトレーニングします。

tree = DecisionTreeRegressor(criterion='mse', splitter='best', max_depth=None, min_samples_split=2, min_samples_leaf=1).fit(x_train, y_train)

モデル効果の検証

テストセットデータを予測用のモデルにインポートする

prediction = tree.predict(x_test)
print("The model training score is" , tree.score(X, y))

出力:The model training score is 0.9977305489482631

period = 500  # 可视化范围
valid = df[X.shape[0]-his_period:-his_period]
valid['Prediction'] = prediction
plt.figure(figsize=(16,8))
plt.title('Model')
plt.xlabel('Date', fontsize=18)
plt.ylabel('Close Price', fontsize=18)
plt.plot(df[-period:X.shape[0]-his_period+1]['close'], linewidth=3, color='blue')
plt.plot(valid['close'], linewidth=5, alpha=0.5)
plt.plot(valid['Prediction'], linewidth=2, color='red')
plt.legend(['Train', 'Val', 'Predictions'], loc='lower right')
plt.show()
059cc001ca0c8397714cbfc624ea10c6.png

図からわかるように、モデルでは30日程度で大暴落が起きると予測していましたが(実際はこんなに早く起きるとは予想していませんでしたが…)、その後は少し反発して徐々に安定してきました。

将来の傾向を予測する

過去 60 日間のデータを再取得し、モデルをインポートして予測値を取得します

x_future = np.array(df.drop(['Prediction'], 1)[-his_period:])
prediction = tree.predict(x_future)

plt.figure(figsize=(16,8))
plt.title('Model')
plt.xlabel('Days', fontsize=18)
plt.ylabel('Close Price', fontsize=18)
plt.plot(prediction)
plt.legend(['Predictions'], loc='lower right')
plt.show()
3d3be0fd1e807b881fe922931f257b4b.png

このモデルは、市場が来月は比較的横ばいで、2 か月目にはチャンスがあるように見えることを示していますが、それは正確でしょうか? 待ってみましょう...

ソースコードのダウンロード

7faa0160aa38cab9606be35edcf91060.png

この問題に関連する文書と情報は、公開アカウント「Deep Awakening」で見つけることができ、バックグラウンドで「trade02」と返信してダウンロード リンクを入手してください。

12b615b3a24ba26bda810c735118a8fa.gif

おすすめ

転載: blog.csdn.net/weixin_47479625/article/details/122711265