人工智能與量化投資-金融與神經網絡

機器學習和深度學習已經成爲量化對衝基金常用的新有效策略,並且能幫助他們最大化其利潤。作爲一名人工智能和金融愛好者,這是一個不一樣的時代,因爲這個時代將兩個領域完美的結合起來。

本文將介紹如何使用神經網絡預測股票市場,特別是股票(或指數)的價格。我們的目標是使用機器學習和神經網絡的方法預測所選公司的股票價格。

對於股票預測的更高級的神經網絡實現,請看我後面的文章。

金融中神經網絡的需求

金融是高度非線性的,有時股票價格數據甚至可能看起來完全隨機。傳統的時間序列方法(如ARIMA和GARCH模型)僅在序列是靜止時纔有效,這是一個限制性假設,需要通過記錄返回(或其他變換)對序列進行預處理。然而,主要問題出現在實時交易系統中實施這些模型,因爲在添加新數據時無法保證穩定性。

我們通過使用不需要使用任何穩定性的神經網絡來解決這個問題。此外,神經網絡可以從本質上有效地找到數據之間的關係並使用它來預測(或分類)新數據。

典型的完整棧式數據科學項目具有以下工作流程:

數據採集​​ - 這爲我們提供了特徵

數據預處理 - 去除一些噪聲並使數據具有可用性

設計和實現模型 - 我們選擇神經網絡

回測模型 - 任何交易策略中非常關鍵的一步

優化 - 找到合適的參數

我們的神經網絡的輸入數據是過去十天的股票價格數據,我們用它來預測第二天的股票價格數據。

1、數據採集

幸運的是,該項目所需的股票價格數據在雅虎財經中可以找到。可以使用他們的Python API,pdr.get_yahoo_data(ticker,start_date,end_date或直接從他們的網站獲取)數據。

2、數據預處理

在我們的案例中,我們需要將數據分解爲十個價格和第二天價格的訓練組。我通過定義一個類預處理,將其分解爲訓練和測試數據並定義一個方法get_train(self,seq_len)來完成此操作,該方法將訓練數據(輸入和輸出)作爲numpy數組返回,給定特定長度的週期。完整代碼如下:

def gen_train(self, seq_len):

"""

Generates training data

:param seq_len: length of window

:return: X_train and Y_train

"""

for i in range((len(self.stock_train)//seq_len)*seq_len - seq_len - 1):

x = np.array(self.stock_train.iloc[i: i + seq_len, 1])

y = np.array([self.stock_train.iloc[i + seq_len + 1, 1]], np.float64)

self.input_train.append(x)

self.output_train.append(y)

self.X_train = np.array(self.input_train)

self.Y_train = np.array(self.output_train)

同樣,對於測試數據,我定義了一個返回測試數據X_test和Y_test的方法。

3、設計並實現模型

神經網絡模型

對於這個項目,我使用了兩種神經網絡模型:多層感知器(MLP)和長短期模型(LSTM)。我將簡要介紹這些模型的工作原理。

MLP是最簡單的神經網絡形式,其中輸入被饋送到模型中,並且使用特定權重,值通過隱藏層向前饋送以產生輸出。學習來自於通過隱藏層反向傳播以改變每個神經元之間權重的值。 MLP的一個問題是缺乏“記憶”。對先前的訓練數據中發生的事情以及如何影響新的訓練數據沒有任何意義。在我們的模型中,一個數據集中的十天數據與另一個數據集之間的差異可能很重要(例如),但MLP無法分析這些關係。

這就是LSTM或一般的遞歸神經網絡(RNN)的用武之地。RNN能夠存儲有關數據的某些信息供以後使用,這擴展了網絡分析股票價格數據之間關係的複雜結構的能力。 RNN的一個問題是梯度消失問題。這是因爲當層數增加時,梯度不斷減小。 LSTM對此進行了改進,使其更有效。

實現模型

爲了實現模型,我選擇了keras,因爲它使用了向網絡添加層而不是一次定義整個網絡。這使我們能夠快速更改層數和層類型,這在優化網絡時非常方便。

使用股票價格數據的一個重要步驟是正則化數據。這通常意味着你減去平均值併除以標準差,但在我們的情況下,我們希望能夠在一段時間內在實時交易中使用該系統。因此,採用統計方法可能不是正則化數據的最準確方法。所以我只將整個數據除以200。雖然近似正則化看起來不靠譜,但它仍然有效地確保神經網絡中的權重不會變得太大。

讓我們從更簡單的MLP開始。在keras中,這是通過在順序模型上添加Dense層來完成的。完整代碼如下:

model = tf.keras.models.Sequential()

model.add(tf.keras.layers.Dense(100, activation=tf.nn.relu))

model.add(tf.keras.layers.Dense(100, activation=tf.nn.relu))

model.add(tf.keras.layers.Dense(1, activation=tf.nn.relu))

model.compile(optimizer="adam", loss="mean_squared_error")

這就是keras的優雅所在。只需要這五行代碼,我們就創建了一個帶有兩個隱藏層的MLP,每個隱藏層都有一百個神經元。關於優化器的一點說法。 Adam優化器在機器學習社區中越來越受歡迎,因爲與傳統的隨機梯度下降相比,它是一種更有效的優化算法。通過觀察隨機梯度下降的另外兩個擴展的優點,可以最好地理解這些優點:

自適應梯度算法(AdaGrad),保持每參數學習速率,改善稀疏梯度問題(例如自然語言和計算機視覺問題)的性能。

均方根傳播(RMSProp)還保持每參數學習速率,該每參數學習速率基於權重的最近梯度的平均值(例如,它的變化速度)進行調整。這意味着該算法在在線和非靜止問題(例如噪聲)上表現良好。

Adam可以被認爲是結合上述擴展的好處,這就是爲什麼我選擇使用Adam作爲我的優化器。

現在我們需要將模型與我們的訓練數據相匹配。同樣,keras使它變得簡單,只需要以下代碼:

model.fit(X_train, Y_train, epochs=100)

一旦我們適合我們的模型,我們需要根據我們的測試數據對其進行評估,以瞭解它的執行情況。這是通過

model.evaluate(X_test, Y_test)

您可以使用評估中的信息來評估模型預測股票價格的能力。

對於LSTM模型,程序類似,代碼如下:

model = tf.keras.Sequential()

model.add(tf.keras.layers.LSTM(20, input_shape=(10, 1), return_sequences=True))

model.add(tf.keras.layers.LSTM(20))

model.add(tf.keras.layers.Dense(1, activation=tf.nn.relu))

model.compile(optimizer="adam", loss="mean_squared_error")

model.fit(X_train, Y_train, epochs=50)

model.evaluate(X_test, Y_test)

需要注意的一點是,keras要求輸入數據具有特定尺寸,由模型決定。使用numpy重新構造數據至關重要。

4、回測模型

現在我們已經使用我們的訓練數據擬合了我們的模型並使用我們的測試數據對其進行了評估,我們可以通過對新數據的模型進行回溯測試來進一步評估。回溯測試基本上是針對一段時間內的數據運行您的策略(或我的情況,預測算法),以查看算法的損益或準確性。這很簡單

def back_test(strategy, seq_len, ticker, start_date, end_date, dim):

"""

A simple back test for a given date period

:param strategy: the chosen strategy. Note to have already formed the model, and fitted with training data.

:param seq_len: length of the days used for prediction

:param ticker: company ticker

:param start_date: starting date

:type start_date: "YYYY-mm-dd"

:param end_date: ending date

:type end_date: "YYYY-mm-dd"

:param dim: dimension required for strategy: 3dim for LSTM and 2dim for MLP

:type dim: tuple

:return: Percentage errors array that gives the errors for every test in the given date range

"""

data = pdr.get_data_yahoo(ticker, start_date, end_date)

stock_data = data["Adj Close"]

errors = []

for i in range((len(stock_data)//10)*10 - seq_len - 1):

x = np.array(stock_data.iloc[i: i + seq_len, 1]).reshape(dim) / 200

y = np.array(stock_data.iloc[i + seq_len + 1, 1]) / 200

predict = strategy.predict(x)

while predict == 0:

predict = strategy.predict(x)

error = (predict - y) / 100

errors.append(error)

total_error = np.array(errors)

print(f"Average error = {total_error.mean()}")

但是,這種回溯測試是一個簡化版本,而不是一個完整的回測系統。對於完整的回測系統,您需要考慮諸如生存偏差,預測偏差,市場體制變化和交易成本等因素。由於這只是一個教學項目,簡單的回測就足夠了。但是,如果您對設置完整的回測系統有疑問,請隨時與我聯繫。

下面顯示了我的LSTM模型在預測2月份Apple股票價格時的表現

對於沒有優化的簡單LSTM模型,這是非常好的預測。它真實地向我們展示了神經網絡和機器學習模型在建模參數之間複雜關係方面的穩健性。

5、優化 - 超參數調整

優化神經網絡模型對於在樣本外測試中提高模型的性能通常很重要。我沒有在我的開源版本的項目中包含調優,因爲我希望它對那些閱讀它的人來說是一個挑戰,並嘗試優化模型以使其表現更好。對於那些不瞭解優化的人來說,它涉及找到最大化模型性能的超參數。您可以通過多種方式搜索這些理想的超參數,從網格搜索到隨機方法。我強烈認爲,學習優化模型可以將您的機器學習知識提升到新的水平。

結論

機器學習每天都在不斷髮展,每天都在開發新的方法。至關重要的是,我們不斷更新我們的知識,爲有趣的項目建立模型,如股票價格預測。雖然上面的LSTM模型不足以用於實時交易,但通過開發這種模型構建的基礎可以幫助我們構建更好的模型,這些模型有一天可能會在我們的交易系統中使用。

人工智能與深度學習做量化請關注:AI量化(https://t.zsxq.com/RvfY37y) 星球限時免費,如需加入,請私信我獲得免費邀請碼!

零基礎學習Python與深度學習應用請關注星球:Python與深度學習 https://t.zsxq.com/bUFayZ3

微信公衆號:QTechAI

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章