动量效应是金融市场中一种常见的现象,指的是过去表现较好的资产在未来一段时间内继续表现良好的趋势。本文将介绍一种基于动量效应的量化策略,并使用Python代码展示其实现过程。
策略逻辑
该策略的核心逻辑是:选取过去一段时间内涨幅最大的N只股票,持有它们在未来一段时间内,期望它们能够继续保持上涨趋势。
数据准备
首先,我们从AllTick的接口获取股票的历史价格数据。
import time
import requests
import pandas as pd
# 定义获取历史K线数据的函数
def get_historical_data(symbol, kline_type=1, kline_timestamp_end=0, query_kline_num=100, adjust_type=0):
url = 'http://quote.aatest.online/quote-stock-b-api/kline'
token = 'e945d7d9-9e6e-4721-922a-7251a9d311d0-1678159756806'
# 构造查询参数
query = {
"trace": "python_http_test1",
"data": {
"code": symbol,
"kline_type": kline_type, # K线类型:1为日线
"kline_timestamp_end": kline_timestamp_end, # 结束时间戳,0表示最新时间
"query_kline_num": query_kline_num, # 获取的K线数量
"adjust_type": adjust_type # 复权类型:0为不复权
}
}
# 发送请求
response = requests.get(
url=url,
params={"token": token, "query": json.dumps(query)},
headers={'Content-Type': 'application/json'}
)
# 解析返回的数据
if response.status_code == 200:
data = response.json()
if data.get("code") == 0: # 判断请求是否成功
kline_data = data["data"]["kline"]
df = pd.DataFrame(kline_data, columns=["timestamp", "open", "high", "low", "close", "volume"])
df["timestamp"] = pd.to_datetime(df["timestamp"], unit="s") # 转换时间戳为日期
df.set_index("timestamp", inplace=True)
return df
else:
print(f"Error: {data.get('message')}")
return None
else:
print(f"Request failed with status code: {response.status_code}")
return None
# 获取多只股票的历史数据
symbols = ["700.HK", "UNH.US", "AAPL.US"] # 示例股票代码
start_date = "2022-01-01"
end_date = "2023-01-01"
# 获取历史数据并计算收益率
data = {}
for symbol in symbols:
df = get_historical_data(symbol, query_kline_num=252) # 获取252个交易日的数据
if df is not None:
df['returns'] = df['close'].pct_change() # 计算每日收益率
data[symbol] = df
# 将所有股票数据合并到一个DataFrame中
all_data = pd.concat(data.values(), keys=data.keys(), names=['symbol'])
动量计算
接下来,我们计算每只股票在过去一段时间内的累计收益率,作为其动量指标。
lookback_period = 20 # 动量计算周期
all_data['momentum'] = all_data.groupby('symbol')['returns'].rolling(window=lookback_period).apply(lambda x: (x + 1).prod() - 1).reset_index(level=0, drop=True)
策略构建
在每个调仓日,我们选取动量最大的N只股票,等权重持有。
import numpy as np
N = 5 # 持有股票数量
rebalance_freq = 'M' # 每月调仓一次
# 计算每个调仓日的动量排名
all_data['rank'] = all_data.groupby('date')['momentum'].rank(ascending=False)
# 生成交易信号
all_data['signal'] = np.where(all_data['rank'] <= N, 1, 0)
# 计算策略收益
all_data['strategy_return'] = all_data.groupby('symbol')['signal'].shift(1) * all_data['returns']
# 计算组合收益
portfolio_return = all_data.groupby('date')['strategy_return'].sum() / N
策略评估
最后,我们可以计算策略的年化收益率、最大回撤等指标,并绘制策略的净值曲线。
# 计算年化收益率
annual_return = portfolio_return.mean() * 252
# 计算最大回撤
cumulative_return = (1 + portfolio_return).cumprod()
peak = cumulative_return.cummax()
drawdown = (cumulative_return - peak) / peak
max_drawdown = drawdown.min()
# 打印策略表现
print(f"年化收益率: {annual_return:.2%}")
print(f"最大回撤: {max_drawdown:.2%}")
# 绘制净值曲线
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 6))
plt.plot(cumulative_return)
plt.title('Strategy Cumulative Return')
plt.xlabel('Date')
plt.ylabel('Cumulative Return')
plt.show()
动量效应是量化交易中一个经典且有效的策略。本文介绍了一种基于动量效应的简单策略,并使用Python代码展示了其实现过程。需要注意的是,该策略仅作为示例,实际应用中需要考虑更多因素,如交易成本、风险控制等。