![]() 讀取黃金 ETF 數(shù)據(jù)本文使用機(jī)器學(xué)習(xí)方法來(lái)預(yù)測(cè)最重要的貴金屬之一黃金的價(jià)格。我們將創(chuàng)建一個(gè)線性回歸模型,該模型從過(guò)去的黃金 ETF (GLD) 價(jià)格中獲取信息,并返回對(duì)第二天黃金 ETF 價(jià)格的預(yù)測(cè)。GLD是直接投資實(shí)物黃金的最大ETF。(掃描本文最下方二維碼獲取全部完整源碼和Jupyter Notebook 文件打包下載。) 首先要做的是:導(dǎo)入所有必要庫(kù)。 # LinearRegression 是一個(gè)用于線性回歸的機(jī)器學(xué)習(xí)庫(kù) from sklearn.linear_model import LinearRegression # pandas 和 numpy 用于數(shù)據(jù)操作 import pandas as pd import numpy as np # matplotlib 和 seaborn 用于繪制圖形 import matplotlib.pyplot as plt %matplotlib inline plt.style.use('seaborn-darkgrid') # yahoo Finance用于獲取數(shù)據(jù) import yfinance as yf 然后,我們讀取過(guò)去 12 年的每日黃金 ETF 價(jià)格數(shù)據(jù)并將其存儲(chǔ)在 Df 中。我們刪除不相關(guān)的列并使用 dropna() 函數(shù)刪除 NaN 值。然后,我們繪制黃金 ETF 收盤(pán)價(jià)。
![]() 定義解釋變量解釋變量是一個(gè)被操縱以確定第二天黃金 ETF 價(jià)格的變量。簡(jiǎn)單地說(shuō),它們是我們想要用來(lái)預(yù)測(cè)黃金 ETF 價(jià)格的特征。 該策略中的解釋變量是過(guò)去 3 天和 9 天的移動(dòng)平均線。我們使用 dropna() 函數(shù)刪除 NaN 值并將特征變量存儲(chǔ)在 X 中。 但是,您可以向 X 添加更多您認(rèn)為對(duì)預(yù)測(cè)黃金 ETF 價(jià)格有用的變量。這些變量可以是技術(shù)指標(biāo)、其他 ETF 的價(jià)格,例如黃金礦工 ETF (GDX) 或石油 ETF (USO),或美國(guó)經(jīng)濟(jì)數(shù)據(jù)。 定義因變量同樣,因變量取決于解釋變量的值。簡(jiǎn)而言之,這是我們?cè)噲D預(yù)測(cè)的黃金 ETF 價(jià)格。我們將黃金 ETF 價(jià)格存儲(chǔ)在 y 中。 Df['S_3'] = Df['Close'].rolling(window=3).mean() Df['S_9'] = Df['Close'].rolling(window=9).mean() Df['next_day_price'] = Df['Close'].shift(-1) DfDf = Df.dropna() X = Df[['S_3', 'S_9']] y = Df['next_day_price'] 將數(shù)據(jù)拆分為訓(xùn)練和測(cè)試數(shù)據(jù)集在這一步中,我們將預(yù)測(cè)變量和輸出數(shù)據(jù)拆分為訓(xùn)練數(shù)據(jù)和測(cè)試數(shù)據(jù)。通過(guò)將輸入與預(yù)期輸出配對(duì),訓(xùn)練數(shù)據(jù)用于創(chuàng)建線性回歸模型。 測(cè)試數(shù)據(jù)用于估計(jì)模型的訓(xùn)練效果。 ![]() ·前 80% 的數(shù)據(jù)用于訓(xùn)練,剩余的數(shù)據(jù)用于測(cè)試 ·X_train & y_train 是訓(xùn)練數(shù)據(jù)集 ·X_test & y_test 是測(cè)試數(shù)據(jù)集
創(chuàng)建線性回歸模型我們現(xiàn)在將創(chuàng)建一個(gè)線性回歸模型。但是,什么是線性回歸? 如果我們?cè)噲D捕捉“x”和“y”變量之間的數(shù)學(xué)關(guān)系,通過(guò)對(duì)散點(diǎn)圖擬合一條線,“最好”根據(jù)“x”的觀察值解釋“y”的觀察值,那么這樣的方程 x 和 y 之間的關(guān)系稱為線性回歸分析。 ![]() 為了進(jìn)一步分解,回歸用自變量解釋了因變量的變化。因變量“y”是您要預(yù)測(cè)的變量。自變量“x”是您用來(lái)預(yù)測(cè)因變量的解釋變量。以下回歸方程描述了這種關(guān)系: Y = m1 * X1 + m2 * X2 + C Gold ETF price = m1 * 3 days moving average + m2 * 15 days moving average + c 然后我們使用擬合方法擬合自變量和因變量(x 和 y)以生成回歸系數(shù)和常數(shù)。
輸出線性回歸模型: 黃金 ETF 價(jià)格 (y) = 1.20 * 3 天移動(dòng)平均線 (x1) + -0.21 * 9 天移動(dòng)平均線 (x2) + 0.43(常數(shù)) 預(yù)測(cè)黃金ETF價(jià)格現(xiàn)在,是時(shí)候檢查模型是否在測(cè)試數(shù)據(jù)集中工作了。我們使用使用訓(xùn)練數(shù)據(jù)集創(chuàng)建的線性模型來(lái)預(yù)測(cè)黃金 ETF 價(jià)格。預(yù)測(cè)方法找到給定解釋變量 X 的黃金 ETF 價(jià)格 (y)。 predicted_price = linear.predict(X_test) predicted_price = pd.DataFrame( predicted_price, index=y_test.index, columns=['price']) predicted_price.plot(figsize=(10, 7)) y_test.plot() plt.legend(['predicted_price', 'actual_price']) plt.ylabel('Gold ETF Price') plt.show() ![]() 該圖顯示了黃金 ETF 的預(yù)測(cè)價(jià)格和實(shí)際價(jià)格。 現(xiàn)在,讓我們使用 score() 函數(shù)計(jì)算擬合優(yōu)度。
輸出: 99.21 可以看出,模型的 R 平方為 99.21%。R 平方始終介于 0 和 100% 之間。接近 100% 的分?jǐn)?shù)表明該模型很好地解釋了黃金 ETF 的價(jià)格。 繪制累積收益讓我們計(jì)算一下這個(gè)策略的累積收益來(lái)分析它的表現(xiàn)。 累計(jì)收益計(jì)算步驟如下: · 生成黃金價(jià)格的每日百分比變化 · 當(dāng)?shù)诙斓念A(yù)測(cè)價(jià)格高于當(dāng)天的預(yù)測(cè)價(jià)格時(shí),創(chuàng)建一個(gè)以“1”表示的買(mǎi)入交易信號(hào) · 通過(guò)將每日百分比變化乘以交易信號(hào)來(lái)計(jì)算策略回報(bào)。 · 最后,我們將繪制累積收益圖 gold = pd.DataFrame() gold['price'] = Df[t:]['Close'] gold['predicted_price_next_day'] = predicted_price gold['actual_price_next_day'] = y_test gold['gold_returns'] = gold['price'].pct_change().shift(-1) gold['signal'] = np.where(gold.predicted_price_next_day.shift(1) < gold.predicted_price_next_day,1,0) gold['strategy_returns'] = gold.signal * gold['gold_returns'] ((gold['strategy_returns']+1).cumprod()).plot(figsize=(10,7),color='g') plt.ylabel('Cumulative Returns') plt.show() 輸出如下: ![]() 我們還將計(jì)算夏普比:
輸出如下: 'Sharpe Ratio 1.06' 預(yù)測(cè)每日價(jià)格您可以使用以下代碼來(lái)預(yù)測(cè)黃金價(jià)格,并給出我們應(yīng)該購(gòu)買(mǎi) GLD 還是不持倉(cāng)的交易信號(hào): import datetime as dt current_date = dt.datetime.now() data = yf.download('GLD', '2008-06-01', current_date, auto_adjust=True) data['S_3'] = data['Close'].rolling(window=3).mean() data['S_9'] = data['Close'].rolling(window=9).mean() datadata = data.dropna() data['predicted_gold_price'] = linear.predict(data[['S_3', 'S_9']]) data['signal'] = np.where(data.predicted_gold_price.shift(1) < data.predicted_gold_price,'Buy','No Position') data.tail(1)[['signal','predicted_gold_price']].T 輸出如下: ![]() |
|