Skip to content

运用 121 策略模型,斩获 121% 的投资收益

作者:老余捞鱼

原创不易,转载请标明出处及原作者。

写在前面的话:上次写了一篇《股票“配统套利”实战终极指南》,有读者问还有没有更高收益的股票“配统套利”模型推荐。那今天我就还是接着上面这篇,介绍一个高收益率的121策略模型,这是一种结合了LSTM神经网络和协整原理的高收益交易策略,用于预测两家公司股票价格之间的短期偏差,并可根据微妙的价格走势进行交易并取得了翻倍的回报

如果一笔 2 万美元的投资在一年之内增长到了 43200 美元,哪是多么让人欣喜的事情啊!而这也正是 121 模型名字的由来(121%的年化收益率)。这个定制交易策略,将深度学习的预测能力与金融计量经济学的基本原理相融合。接下来,让我们一起了解使 121 模型与众不同的基本思想和方法吧。

一、什么是 121 模型

121 模型的两个基本概念是协整和长短期记忆(LSTM)神经网络。

协整(Cointegration):在金融市场中,有些资产对具有长期关系,它们的价格会随着时间的推移而相互跟随,同时也会出现短期偏差。这就是所谓的协整关系。该模型通过选择一对高度相关的资产(本例中为苹果公司 [AAPL] 和微软公司 [MSFT])并监测其价格之间的价差来利用这种关系。尽管存在这种短期偏差,但协整理论表明,这种价格一定会回到它们的均衡关系,从而提供一个临时交易机会。

长短期记忆(LSTM)神经网络:Long Short-Term Memory ,传统的统计模型只能捕捉几个方面,无法理解金融数据中复杂的非线性模式。LSTM 神经网络专门用于处理连续数据,并从过去的趋势中学习,预测未来的走势。当您用历史价差数据训练 LSTM 时,这意味着该模型将捕捉这些短期偏差的模式,从而根据回归均值生成买入或卖出信号。

换言之,121 模型依赖协整关系来检测具有长期均衡关系的一组资产对,再运用 LSTM 来预测短期偏离均衡的状况。正是这种双管齐下的方法,让该模型能够利用暂时的价格差异,实现 121% 左右的年化收益率。

接下来我会带你了解收集数据、计算价差、预处理输入、建立模型以及执行评估的各个步骤。在此过程中,你将明白如何通过运用机器学习来优化过往的金融原理,进而制定出高回报的策略。

二、模型实现


2.1 数据准备

我们的第一步是从雅虎财经(Yahoo Finance)收集 AAPL 和 MSFT 的历史调整收盘价数据。这些数据对于建立、训练和测试模型至关重要。

import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt

# Define ticker symbols and date range
ticker1 = 'AAPL'
ticker2 = 'MSFT'
start_date = '2015-01-01'
end_date = '2023-10-01'

# Download data
data1 = yf.download(ticker1, start=start_date, end=end_date)
data2 = yf.download(ticker2, start=start_date, end=end_date)

# Extract adjusted close prices and combine into a single DataFrame
df = pd.DataFrame({ticker1: data1['Adj Close'], ticker2: data2['Adj Close']})
df.dropna(inplace=True)

# Plot price series
plt.figure(figsize=(14, 7))
plt.plot(df[ticker1], label=ticker1)
plt.plot(df[ticker2], label=ticker2)
plt.title(f'Price Series of {ticker1} and {ticker2}')
plt.xlabel('Date')
plt.ylabel('Adjusted Close Price')
plt.legend()
plt.show()


2.2 将数据分成训练集和测试集

为评估 121 模型,我们将数据分为训练集(2015-2020 年)和测试集(2021-2024年)。这种拆分确保了在未见过的数据上对模型进行评估,以进行准确的性能评估。

# Split data into training and testing sets
split_date = '2021-01-01'
train = df[:split_date]
test = df[split_date:]

print(f"Training data from {train.index[0].date()} to {train.index[-1].date()}")
print(f"Testing data from {test.index[0].date()} to {test.index[-1].date()}")

2.3 训练数据的协整检验

协整是配对交易中的一个重要假设,因为它表明两种资产之间存在稳定的长期关系。这里采用恩格尔-格兰杰协整检验来评估 AAPL 和 MSFT 是否具有稳定的长期关系。

from statsmodels.tsa.stattools import coint

# Perform cointegration test on training data
score, pvalue, _ = coint(train[ticker1], train[ticker2])
print(f'Cointegration test p-value: {pvalue:.4f}')

2.4 估算对冲比率

对冲比率量化了两只股票之间的关系,用于计算它们之间的价差。该比率通过线性回归估算,MSFT 为自变量,AAPL 为因变量。

from sklearn.linear_model import LinearRegression

# Hedge ratio estimation
X_train_lr = train[ticker2].values.reshape(-1, 1)
y_train_lr = train[ticker1].values
lr_model = LinearRegression()
lr_model.fit(X_train_lr, y_train_lr)
hedge_ratio = lr_model.coef_[0]
print(f'Hedge Ratio: {hedge_ratio:.4f}')

该模型的对冲比率为 0.4658,表明 MSFT 在 AAPL 中的持仓平衡比例。

2.5 计算价差

有了对冲比率,我们就可以计算价差,即按对冲比率调整后的价格差异。该价差可作为 LSTM 模型的输入数据,捕捉 AAPL 和 MSFT 之间的偏差。

# Calculate the spread
df['Spread'] = df[ticker1] - hedge_ratio * df[ticker2]

2.6 数据预处理(缩放)

在将传播数据输入 LSTM 之前,我们使用 MinMaxScaler 将其归一化为 0-1 的范围。缩放可确保 LSTM 从数据中高效学习,而不受较大数值的影响。

from sklearn.preprocessing import MinMaxScaler

# Data preprocessing
scaler = MinMaxScaler(feature_range=(0, 1))
spread_values = df['Spread'].values.reshape(-1, 1)
scaled_spread = scaler.fit_transform(spread_values)
train_size = len(train)
train_spread = scaled_spread[:train_size]
test_spread = scaled_spread[train_size:]

2.7 为 LSTM 模型创建序列

为了让 LSTM 学习时间模式,我们将传播数据组织成序列。每个序列代表一个传播值的滑动窗口,使模型能够从最近的历史中学习。在这种情况下,我们使用 30 天的序列作为 LSTM 的输入。

# Function to create sequences
def create_sequences(data, time_steps=30):
    X = []
    y = []
    for i in range(len(data) - time_steps):
        X.append(data[i:(i + time_steps), 0])
        y.append(data[i + time_steps, 0])
    return np.array(X), np.array(y)

# Generate training sequences
time_steps = 30
X_train_seq, y_train_seq = create_sequences(train_spread, time_steps)
X_train_seq = X_train_seq.reshape((X_train_seq.shape[0], X_train_seq.shape[1], 1))

2.8 构建和训练 LSTM 模型

LSTM 模型是 121 模型的核心,它处理价差序列以预测未来走势。我们将该模型配置为从历史价差数据中学习,使用一个 LSTM 层和一个密集输出层。

# LSTM model architecture
model = Sequential()
model.add(LSTM(50, input_shape=(X_train_seq.shape[1], 1)))  # Crucial hyperparameters not shared
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')

# Model training (placeholder values)
history = model.fit(X_train_seq, y_train_seq, epochs=25, batch_size=32, verbose=1)

注:此处只共享模型架构,不公开关键超参数或敏感细节。

2.9 根据测试数据进行预测

有了训练后的模型,我们就可以对测试数据集进行预测。我们准备测试序列,并将预测值和实际值转换回原始比例进行评估。

# Prepare test data and make predictions
combined_spread = np.vstack((train_spread[-time_steps:], test_spread))
X_test_seq, y_test_seq = create_sequences(combined_spread, time_steps)
X_test_seq = X_test_seq.reshape((X_test_seq.shape[0], X_test_seq.shape[1], 1))

# Predict and invert scaling
predictions = model.predict(X_test_seq)
predictions_inv = scaler.inverse_transform(predictions)
y_test_seq_inv = scaler.inverse_transform(y_test_seq.reshape(-1, 1))

2.10 绘制带有买卖信号的蜡烛图

为了直观地显示 AAPL 价格图表上的信号,我们绘制了一张带有买点和卖点标记的蜡烛图。该图展示了模型建议的交易行动。

# Plot buy and sell signals on AAPL price chart
buy_signals = data1_test_signals[data1_test_signals['Signal'] == 1]
sell_signals = data1_test_signals[data1_test_signals['Signal'] == -1]

# Set buy/sell prices slightly above/below actual prices for visibility
signal_markers.loc[buy_signals.index, 'Buy'] = data1_test_signals.loc[buy_signals.index, 'Low'] * 0.99
signal_markers.loc[sell_signals.index, 'Sell'] = data1_test_signals.loc[sell_signals.index, 'High'] * 1.01

mpf.plot(data1_test_signals, type='candle', addplot=apds, title='AAPL Price with Buy and Sell Signals')


三、策略收益评估


3.1 计算策略回报

为评估盈利能力,我们根据模型信号和资产回报计算每日策略回报。然后对这些回报进行复利计算,得出累计策略回报。

# Calculate daily returns and cumulative strategy returns
returns = df[[ticker1, ticker2]].pct_change().loc[test_df.index]
test_df['Strategy_Return'] = test_df['Signal'] * (returns[ticker1] - hedge_ratio * returns[ticker2])
test_df['Cumulative_Strategy_Return'] = (1 + test_df['Strategy_Return'].fillna(0)).cumprod() - 1


3.2 性能指标设置

我们使用年化收益率、波动率、夏普比率和最大缩水率等关键指标来评估模型的风险调整后收益。

# Calculate performance metrics
annualized_return = daily_return_mean * 252
annualized_volatility = daily_return_std * np.sqrt(252)
sharpe_ratio = (annualized_return - risk_free_rate) / annualized_volatility
max_drawdown = test_df['Drawdown'].max()


3.3 修整交易成本

为了考虑现实世界中的交易费用,我们将每笔交易的交易成本纳入模型的收益中。调整后的净收益率更符合实际情况。

# Adjust for transaction costs
transaction_cost = 0.0005  # Placeholder for actual costs
test_df['Trades'] = test_df['Signal'].diff().abs()
test_df['Transaction_Costs'] = test_df['Trades'] * transaction_cost
test_df['Strategy_Return_Net'] = test_df['Strategy_Return'] - test_df['Transaction_Costs']
test_df['Cumulative_Strategy_Return_Net'] = (1 + test_df['Strategy_Return_Net'].fillna(0)).cumprod() - 1
# Calculate performance metrics after transaction costs
# Annualized Return after transaction costs
daily_return_mean_net = test_df['Strategy_Return_Net'].mean()
annualized_return_net = daily_return_mean_net * 252
print(f'Annualized Return (Net): {annualized_return_net:.2%}')

# Annualized Volatility after transaction costs
daily_return_std_net = test_df['Strategy_Return_Net'].std()
annualized_volatility_net = daily_return_std_net * np.sqrt(252)
print(f'Annualized Volatility (Net): {annualized_volatility_net:.2%}')

# Sharpe Ratio after transaction costs
sharpe_ratio_net = (annualized_return_net - risk_free_rate) / annualized_volatility_net
print(f'Sharpe Ratio (Net): {sharpe_ratio_net:.2f}')

# Maximum Drawdown after transaction costs
test_df['Cumulative_Max_Net'] = test_df['Cumulative_Strategy_Return_Net'].cummax()
test_df['Drawdown_Net'] = test_df['Cumulative_Max_Net'] - test_df['Cumulative_Strategy_Return_Net']
max_drawdown_net = test_df['Drawdown_Net'].max()
print(f'Maximum Drawdown (Net): {max_drawdown_net:.2%}')

结果如下:

3.4 绩效结果和讨论

1.原始战略回报与净战略回报

累计策略回报图显示了在无交易成本的情况下实施策略的回报增长情况。然而,现实世界中的交易会产生成本,对盈利能力产生重大影响。净策略回报图包含了这些交易成本,真实地反映了模型的表现。

观察结果:即使考虑了交易成本,该模型仍能保持较高的累计收益,这增强了其在实际应用中的稳健性。

2.性能指标说明

下表总结了该模型在交易成本之前和之后的风险调整后回报指标:

  • 年化收益率:这表示该策略的年增长率。交易成本略有下降后,仍能获得超过 116% 的可观回报。
  • 年化波动率:模型保持稳定的波动率,表明其在波动的市场条件下也能保持稳定。
  • 夏普比率:该比率用于衡量风险调整后的回报率,扣除成本后仍为 5.96,表明该模型相对于其风险实现了极佳的回报。
  • 最大回调:回调指标显示,模型会经历一段时间的下降。根据交易成本进行调整后,缩编情况有所改善,反映出在实际情况下采用了更现实、更可持续的方法。

以上这些指标共同证明了 121 模型在平衡收益潜力和风险管理方面的有效性。

四、观点回顾

121 模型展示了传统计量经济学原理(如协整关系)如何与 LSTM 等深度学习技术相结合,从而产生有利可图的交易策略。即使在扣除交易成本后,其结果也说明了获得丰厚回报和可控风险的潜力,凸显了机器学习如何改变量化金融。

  1. 传统的统计模型无法捕捉金融数据中复杂的非线性模式,而LSTM神经网络能够处理连续数据并从过去的趋势中学习,预测未来走势。
  2. 121模型结合了协整理论和LSTM技术,通过监测AAPL和MSFT之间的价格差异(价差),并利用这些信息来产生买入或卖出信号。
  3. 即使考虑了交易成本,121模型也能显示出强劲的回报和可管理的风险,尤其是在实际交易场景中,这表明了机器学习在量化金融领域的潜力。
  4. 性能评估指标(如年化收益率、波动率、夏普比率和最大缩水率)是衡量交易策略绩效的关键指标。
  5. 我认为,机器学习和深度学习技术能够改善传统的金融原理,并且可以通过实际的交易来产生高回报的策略。

对于那些希望探索算法交易或了解机器学习如何应用于金融领域的人来说,121 模型提供了一个令人信服的案例研究。随着我对模型的不断完善,我期待着与大家分享未来的见解和更新。

感谢您阅读到最后,希望本文能给您带来新的收获。祝您投资顺利!如果对文中的内容有任何疑问,请给我留言,必复。


本文内容仅仅是技术探讨和学习,并不构成任何投资建议。

Published inAI&Invest专栏

Be First to Comment

发表回复