VectorBT:Python量化交易策略开发与回测评估详解
VectorBT是一个基于Python的开源量化交易库,提供高效、灵活的工具来构建和回测交易策略。其核心优势在于向量化操作,能够快速处理大规模数据,适用于中高级水平的量化交易者。文档详细介绍了VectorBT的安装、数据获取与处理、策略开发、性能评估与优化以及高级策略开发等内容,通过丰富的代码示例和实际应用场景,帮助用户深入理解和掌握VectorBT的使用方法,从而提升量化交易策略的开发效率和质量。
文中内容仅限技术学习与代码实践参考,市场存在不确定性,技术分析需谨慎验证,不构成任何投资建议。适合量化新手建立系统认知,为策略开发打下基础。
第一章 初识VectorBT
1.1 VectorBT简介
VectorBT是一个基于Python的开源量化交易库,它提供了高效、灵活的工具来构建和回测交易策略。其核心优势在于向量化操作,能够快速处理大规模数据,适用于中高级水平的量化交易者。
核心优势
- 向量化操作:利用NumPy和Pandas的强大功能,实现高效的向量化计算。
- 灵活的策略定义:支持多种策略定义方式,包括基于信号的策略和基于事件的策略。
- 丰富的性能评估指标:内置多种性能评估指标,方便分析策略表现。
- 可视化工具:提供强大的可视化工具,帮助用户直观理解策略表现。
1.2 核心架构解析
量化回测范式演进
VectorBT作为第三代量化回测框架,采用向量化计算范式(Vectorized Backtesting),与前两代事件驱动型框架(如Backtrader)和迭代型框架(如Zipline)相比,具有显著优势:
特性 | 事件驱动型 | 迭代型 | 向量化型 (VectorBT) |
---|---|---|---|
计算方式 | 逐事件处理 | 逐K线迭代 | 矩阵运算批处理 |
性能表现 | O(n) 线性复杂度 | O(n) 线性复杂度 | O(1) 常数复杂度 |
内存占用 | 低 | 中等 | 较高 |
策略开发灵活性 | 高 | 中等 | 中等 |
历史数据分析能力 | 弱 | 中等 | 极强 |
技术架构特性
- N维矩阵运算核心:基于Pandas和NumPy实现张量级运算,支持在多维参数空间进行并行回测
- 离散化状态管理:通过状态矩阵记录每个时点的策略状态,支持复杂策略建模
- 自动参数优化:内置参数扫描和交叉验证机制,支持网格搜索和贝叶斯优化
- GPU加速支持:关键计算模块支持CuPy接口,可利用CUDA进行硬件加速
典型应用场景
- 多因子策略开发:支持在因子空间中快速验证数百个因子组合
- 参数敏感性分析:可视化展示策略参数在超平面上的表现分布
- 市场微观结构研究:Tick级数据的快速清洗和特征提取
- 组合优化:内置马科维茨优化器和风险平价模型
1.3 开发环境安装
安装VectorBT及相关库
python">!pip install "vectorbt[full]" pandas numpy plotly ta-lib scikit-learn scikit-optimize lightgbm torch torchvision torchaudio tushare
开发环境验证
python">import vectorbt as vbtprint(f"VectorBT版本: {vbt.__version__}")
1.4 数据获取与存储
在开始使用VectorBT之前,我们需要导入必要的库并设置Tushare的token。
python">import tushare as ts# 设置Tushare的token
ts.set_token("your_token") # 替换为你的Tushare token
pro = ts.pro_api()
获取A股数据
我们可以使用Tushare API获取A股的历史数据,并将其存储为Parquet文件,以便后续高效读取和处理。
python"># 获取A股数据
def get_tushare_data(ts_code, start_date, end_date):df = pro.daily(ts_code=ts_code, start_date=start_date, end_date=end_date)return df# 示例:获取某只A股股票的数据
ts_code = "600000.SH" # 示例股票代码 浦发银行(600000.SH)
start_date = "20200101"
end_date = "20241231"
tushare_data = get_tushare_data(ts_code, start_date, end_date)# 将数据存储为Parquet文件
tushare_data.to_parquet("./data/600000.SH.parquet")# 读取Parquet文件
df = pd.read_parquet("./data/600000.SH.parquet")df["trade_date"] = pd.to_datetime(df["trade_date"], format="%Y%m%d")print(df.head())
数据预览
python"># 查看数据前几行
print(df.head())
1.5 数据可视化
我们可以将价格K线图、成交量、资金流向组合在一起,形成一个更完整的图表,以便更全面地了解市场情况。
python">import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
import talibvbt.settings.set_theme("dark") # 设置暗黑主题
vbt.settings.plotting["layout"]["width"] = 1200 # 调整绘图尺寸fig = vbt.make_subplots(rows=3,cols=1,shared_xaxes=True,vertical_spacing=0.05,row_heights=[0.6, 0.2, 0.2],
)# K线主图
candlestick = go.Candlestick(x=df["trade_date"],open=df["open"],high=df["high"],low=df["low"],close=df["close"],name="价格",
)
fig.add_trace(candlestick, row=1, col=1)# 成交量副图
volume = go.Bar(x=df["trade_date"],y=df["vol"],marker_color=np.where(df["close"] > df["open"], "green", "red"),name="成交量",
)
fig.add_trace(volume, row=2, col=1)# 资金流向指标
mfi = go.Scatter(x=df["trade_date"],y=talib.MFI(df["high"], df["low"], df["close"], df["vol"], timeperiod=14),line={"color": "purple"},name="MFI",
)
fig.add_trace(mfi, row=3, col=1)# 布局优化
fig.update_layout(title="多维行情分析仪表盘")
fig.update_yaxes(title_text="价格", row=1, col=1)
fig.update_yaxes(title_text="成交量", row=2, col=1)
fig.update_yaxes(title_text="MFI", range=[0, 100], row=3, col=1)fig.show()
第二章 数据处理与准备
2.1 数据清洗与预处理
在量化交易中,数据清洗是确保策略准确性的关键步骤。我们需要处理缺失值、异常值等问题,以提高数据质量。
检查和处理缺失值
python"># 检查缺失值
print(df.isnull().sum())# 删除缺失值
df.dropna(inplace=True)# 或者填充缺失值
# df.fillna(method='ffill', inplace=True) # 前向填充
# df.fillna(method='bfill', inplace=True) # 后向填充
检测并处理异常值
我们可以使用Z-score方法来检测并处理异常值。
python"># 计算Z-score
z_scores = (df["close"] - df["close"].mean()) / df["close"].std()# 找出偏离均值3个标准差以上的异常值
outliers = df[np.abs(z_scores) > 3]# 打印异常值
print(outliers)# 可以选择删除或替换这些异常值
# df = df[np.abs(z_scores) <= 3]
2.2 特征工程
特征工程是量化交易中提升模型性能的重要环节。通过添加技术指标等特征,可以更好地捕捉市场趋势。这里我们使用TA-Lib来计算技术指标。
计算移动平均线
python"># 计算5日和20日移动平均线
df["ma5"] = talib.SMA(df["close"], timeperiod=5)
df["ma20"] = talib.SMA(df["close"], timeperiod=20)
计算RSI指标
python"># 计算14日RSI指标
df["rsi"] = talib.RSI(df["close"], timeperiod=14)
计算MACD指标
python"># 计算MACD指标
macd, macdsignal, macdhist = talib.MACD(df["close"], fastperiod=12, slowperiod=26, signalperiod=9)
df["macd"] = macd
df["macdsignal"] = macdsignal
df["macdhist"] = macdhist
计算布林带
python"># 计算布林带
upper, middle, lower = talib.BBANDS(df["close"], timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)
df["bb_upper"] = upper
df["bb_middle"] = middle
df["bb_lower"] = lower
其他常用技术指标
python"># 计算威廉指标
df["willr"] = talib.WILLR(df["high"], df["low"], df["close"], timeperiod=14)# 计算随机振荡器
slowk, slowd = talib.STOCH(df["high"], df["low"], df["close"], fastk_period=14, slowk_period=3, slowk_matype=0, slowd_period=3, slowd_matype=0)
df["stoch_slowk"] = slowk
df["stoch_slowd"] = slowd# 计算相对强弱指数
df["adx"] = talib.ADX(df["high"], df["low"], df["close"], timeperiod=14)
2.3 数据存储
将处理好的数据存储为Parquet格式,便于后续高效读取和处理。
python"># 存储为Parquet文件
df.to_parquet("./data/processed_600000.SH.parquet")
2.4 数据可视化
使用Plotly展示数据分布与特征关系,帮助我们直观理解数据。
绘制收盘价与移动平均线
python"># 创建图形对象
fig = go.Figure()# 添加收盘价
fig.add_trace(go.Scatter(x=df["trade_date"], y=df["close"], mode="lines", name="Close Price")
)# 添加5日移动平均线
fig.add_trace(go.Scatter(x=df["trade_date"], y=df["ma5"], mode="lines", name="5-day MA")
)# 添加20日移动平均线
fig.add_trace(go.Scatter(x=df["trade_date"], y=df["ma20"], mode="lines", name="20-day MA")
)# 设置布局
fig.update_layout(title="600000.SH 价格与移动平均线", xaxis_title="日期", yaxis_title="价格"
)# 显示图表
fig.show()
绘制RSI指标
python"># 绘制MACD指标
fig = go.Figure()# 添加MACD
fig.add_trace(go.Scatter(x=df["trade_date"], y=df["macd"], mode="lines", name="MACD"))# 添加MACD信号线
fig.add_trace(go.Scatter(x=df["trade_date"], y=df["macdsignal"], mode="lines", name="Signal Line")
)# 添加MACD柱状图
fig.add_trace(go.Bar(x=df["trade_date"], y=df["macdhist"], name="Histogram"))# 设置布局
fig.update_layout(title="MACD指标", xaxis_title="日期", yaxis_title="MACD值")# 显示图表
fig.show()
绘制布林带
python"># 绘制布林带
fig = go.Figure()# 添加收盘价
fig.add_trace(go.Scatter(x=df["trade_date"], y=df["close"], mode="lines", name="Close Price")
)# 添加上轨
fig.add_trace(go.Scatter(x=df["trade_date"], y=df["bb_upper"], mode="lines", name="Upper Band")
)# 添加中轨
fig.add_trace(go.Scatter(x=df["trade_date"], y=df["bb_middle"], mode="lines", name="Middle Band")
)# 添加下轨
fig.add_trace(go.Scatter(x=df["trade_date"], y=df["bb_lower"], mode="lines", name="Lower Band")
)# 设置布局
fig.update_layout(title="布林带", xaxis_title="日期", yaxis_title="价格")# 显示图表
fig.show()
第三章 策略开发基础
3.1 量化交易策略的基本构成
在量化交易中,一个完整的策略通常包括以下几个关键部分:
- 数据获取与预处理:获取历史数据并进行清洗和特征工程。
- 信号生成:根据技术指标或其他因素生成买卖信号。
- 订单执行:根据生成的信号执行买入或卖出操作。
- 风险控制:设置止损、止盈等风险管理措施。
- 性能评估:通过各种指标评估策略的表现。
3.1.1 数据处理
数据获取与预处理是策略开发的第一步。我们需要从可靠的数据源获取历史数据,并进行必要的清洗和特征工程,以确保数据的质量和可用性。
3.1.2 信号生成
信号生成是策略的核心部分。常见的信号生成方法包括基于技术指标(如移动平均线交叉)、统计模型(如回归分析)或机器学习模型(如分类器)。
3.1.3 订单执行
订单执行涉及根据生成的信号实际执行买入或卖出操作。在回测阶段,我们可以通过模拟交易来评估策略的表现;在实盘交易中,则需要连接到交易所API进行真实交易。
3.1.4 风险控制
风险控制是确保策略稳健运行的关键。常见的风险控制措施包括设置止损和止盈点、动态调整仓位大小以及使用多种风险管理工具。
3.1.5 性能评估
性能评估是衡量策略表现的重要步骤。常用的性能评估指标包括总回报、年化回报、夏普比率、最大回撤等。
3.2 VectorBT的策略构建框架
VectorBT提供了一套灵活且高效的策略构建框架,帮助用户快速实现和测试各种交易策略。以下是一个典型的策略构建流程:
- 数据处理:导入和预处理数据。
- 信号生成:根据规则或模型生成买卖信号。
- 策略回测:基于生成的信号进行回测。
- 性能评估:评估策略的表现。
3.2.1 数据处理
首先,我们需要导入和预处理数据。这包括读取历史数据、计算技术指标等。
python"># 读取处理后的数据
df = pd.read_parquet("./data/processed_600000.SH.parquet")# 检查数据
print(df[["trade_date", "close", "ma5", "ma20"]].head())
3.2.2 信号生成
接下来,我们需要生成买卖信号。假设我们的策略是当5日移动平均线上穿20日移动平均线时买入,当5日移动平均线下穿20日移动平均线时卖出。
python"># 生成买卖信号
df["signal"] = np.where(df["ma5"] > df["ma20"], 1, 0) # 1表示买入,0表示卖出# 检查信号
print(df[["trade_date", "close", "ma5", "ma20", "signal"]].head())
3.2.3 策略回测
使用VectorBT进行策略回测非常简单。我们可以直接使用Portfolio.from_signals
方法来创建一个策略实例,并进行回测。
python"># 创建价格序列
price = df["close"].astype(float)# 创建信号序列
entries = df["signal"] == 1 # 买入信号
exits = df["signal"] == 0 # 卖出信号# 定义并运行策略
pf = vbt.Portfolio.from_signals(price, entries, exits, fees=0.001, init_cash=100000, freq="D"
)# 打印策略的表现
print(pf.stats())
3.2.4 性能评估
回测完成后,我们可以使用VectorBT提供的各种性能评估指标来评估策略的表现。
python"># 打印主要性能指标
print(pf.stats())# 绘制累积收益曲线
pf.plot().show()# 绘制持仓情况
pf.plot_positions().show()# 绘制最大回撤图
pf.plot_drawdowns().show()# 打印详细交易记录
print(pf.trades.records_readable)
3.2.5 策略优化
通过上述图表和指标,我们可以直观地了解策略的表现。例如,累积收益曲线显示了策略的收益变化趋势,持仓情况展示了每次交易的细节,最大回撤图则反映了策略的风险水平。为了进一步优化策略,我们可以调整参数并进行网格搜索,找到最佳的参数组合。
python"># 定义参数范围
fast_ma_range = [5, 10, 15]
slow_ma_range = [20, 30, 40]# 初始化结果存储
results = []# 遍历参数组合
for fast_ma in fast_ma_range:for slow_ma in slow_ma_range:if fast_ma < slow_ma:df[f"ma{fast_ma}"] = talib.SMA(df["close"], timeperiod=fast_ma)df[f"ma{slow_ma}"] = talib.SMA(df["close"], timeperiod=slow_ma)signal = np.where(df[f"ma{fast_ma}"] > df[f"ma{slow_ma}"], 1, 0)entries = df["signal"] == 1exits = df["signal"] == 0pf = vbt.Portfolio.from_signals(price, entries, exits, fees=0.001, init_cash=100000, freq="D")results.append({"fast_ma": fast_ma,"slow_ma": slow_ma,"total_return": pf.total_return(),"sharpe_ratio": pf.sharpe_ratio(),})# 将结果转换为DataFrame
results_df = pd.DataFrame(results)# 查看结果
print(results_df)
第四章:性能评估与优化
4.1 量化交易中的性能评估指标
在量化交易中,评估策略的性能是至关重要的一步。常见的性能评估指标包括:
- 总回报:策略在整个回测期间的总收益。
- 年化回报:将总回报年化处理,便于比较不同时间段的策略表现。
- 夏普比率:衡量策略每承受一单位总风险所能获得的超过无风险收益率的超额收益。
- 最大回撤:策略净值从最高点下跌至最低点的幅度,反映策略的风险控制能力。
- 胜率:盈利交易占总交易的比例。
- 盈亏比:平均盈利与平均亏损的比值。
还有一些高级指标可以帮助我们更全面地评估策略的表现:
- 信息比率:衡量策略相对于基准的超额收益与跟踪误差的比值。
- 索提诺比率:与夏普比率类似,但只考虑下行风险。
- 卡玛比率:衡量策略的年化回报与最大回撤的比值。
- 斯特林比率:考虑了策略的平均年化回报、最大回撤以及回撤的波动性。
4.2 策略优化的实战技巧
4.2.1 参数稳定性测试
在优化策略时,需要确保参数在不同的市场条件下都具有稳定性。一种常见的方法是将数据分为多个子集进行测试。
python">window = (5, 20)# 将数据分为多个子集进行测试
subsets = np.array_split(df, 5) # 将数据分为5个子集for subset in subsets:subset["ma_fast"] = talib.SMA(subset["close"], timeperiod=window[0])subset["ma_slow"] = talib.SMA(subset["close"], timeperiod=window[1])subset["signal"] = np.where(subset["ma_fast"] > subset["ma_slow"], 1, 0)entries = subset["signal"] == 1exits = subset["signal"] == 0portfolio = vbt.Portfolio.from_signals(subset["close"], entries, exits, fees=0.001, init_cash=100000, freq="D")print(portfolio.stats())
4.2.2 多策略组合
通过组合多个策略,可以降低单一策略的风险,提高整体收益。以下是组合多个策略的示例。
定义多个策略
python"># 定义多个策略,生成买入信号 (1) 和卖出信号 (-1),保持观望 (0)
def strategy1(df):df["ma_fast"] = talib.SMA(df["close"], timeperiod=5)df["ma_slow"] = talib.SMA(df["close"], timeperiod=20)df["signal"] = np.where(df["ma_fast"] > df["ma_slow"], 1, -1)return df["signal"]def strategy2(df):df["rsi"] = talib.RSI(df["close"], timeperiod=14)df["signal"] = np.where(df["rsi"] < 30, 1, np.where(df["rsi"] > 70, -1, 0))return df["signal"]
组合策略
python"># 应用多个策略
df["signal1"] = strategy1(df)
df["signal2"] = strategy2(df)# 组合信号
df["combined_signal"] = (df["signal1"] + df["signal2"]) / 2
df["final_signal"] = np.where(df["combined_signal"] > 0.5, 1, np.where(df["combined_signal"] < -0.5, -1, 0))# 检查最终信号
print(df[["trade_date", "close", "signal1", "signal2", "combined_signal", "final_signal"]].head()
)
回测组合策略
python"># 创建信号序列
entries = df["final_signal"] == 1
exits = df["final_signal"] == -1# 定义并运行策略
pf = vbt.Portfolio.from_signals(price, entries, exits, fees=0.001, init_cash=100000, freq="D"
)# 打印策略的表现
print(pf.stats())# 绘制累积收益曲线
pf.plot().show()# 绘制持仓情况
pf.plot_positions().show()# 绘制最大回撤图
pf.plot_drawdowns().show()# 打印详细交易记录
print(pf.trades.records_readable)
第五章 高级策略开发
5.1 数据标准化与归一化
在量化交易中,不同特征之间的量纲差异可能会影响模型的性能。通过标准化和归一化处理,可以消除这些差异,提高模型的表现。
5.1.1 选择特征
python"># 选择特征
features = ["open","high","low","vol","ma5","ma20","rsi","macd","macdsignal","macdhist",
]
5.1.1 标准化
标准化(Standardization)是将数据转换为均值为0、标准差为1的标准正态分布。这有助于许多机器学习算法更好地收敛。
python">from sklearn.preprocessing import StandardScalerscaler = StandardScaler()
df[features] = scaler.fit_transform(df[features])
5.1.2 归一化
归一化(Normalization)是将数据缩放到一个特定的范围,通常是[0, 1]或[-1, 1]。这有助于某些算法(如神经网络)更好地工作。
python">from sklearn.preprocessing import MinMaxScalerscaler = MinMaxScaler()
df[features] = scaler.fit_transform(df[features])
5.2 基于机器学习的策略开发
机器学习技术可以帮助我们从历史数据中提取复杂的模式,并生成更准确的交易信号。以下是一些常见的机器学习方法及其应用。
5.2.1 使用LightGBM进行分类
LightGBM是一种高效的梯度提升框架,适用于大规模数据集。我们可以使用LightGBM来预测股票的涨跌,并生成交易信号。
数据准备
首先,我们需要准备训练数据和标签。
python">import lightgbm as lgb
from sklearn.model_selection import train_test_split# 生成标签:如果5天后收盘价高于今天,则为1(上涨),否则为0(下跌)
df["label"] = (df["close"].shift(-5) > df["close"]).astype(int)X = df[features]
y = df["label"]# 将数据分为训练集、验证集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.25, random_state=42
)
模型训练
接下来,我们使用LightGBM训练模型。
python"># 定义LightGBM数据集
train_data = lgb.Dataset(X_train, label=y_train, free_raw_data=False)
val_data = lgb.Dataset(X_val, label=y_val, reference=train_data, free_raw_data=False)def objective(trial):# 设置LightGBM模型参数params = {"objective": "regression", # 回归任务"metric": "mse", # 评估指标为均方误差"boosting_type": "gbdt", # 梯度提升决策树"num_leaves": trial.suggest_int("num_leaves", 20, 50), # 叶子数量"learning_rate": trial.suggest_float("learning_rate", 0.01, 0.1), # 学习率"max_depth": trial.suggest_int("max_depth", 3, 10),"min_child_samples": trial.suggest_int("min_child_samples", 5, 30),"feature_fraction": 0.9, # 特征采样比例"verbose": -1, # 日志输出级别"early_stopping_rounds": 10,}# 模型训练model = lgb.train(params,train_data,valid_sets=[val_data],num_boost_round=1000,)# 动态获取验证集名称和MSE值mse = model.best_score["valid_0"]["l2"] # 获取MSE值return mseimport optuna# 创建Optuna研究对象
study = optuna.create_study(direction="minimize") # 目标是最小化MSE# 执行优化
study.optimize(objective, n_trials=100)# 输出最优参数组合
print("最优参数组合:")
print(study.best_params)
print("最优MSE:")
print(study.best_value)# 模型训练
model = lgb.train(study.best_params,train_data,valid_sets=[val_data],num_boost_round=1000,
)# 预测
y_pred = model.predict(X_test, num_iteration=model.best_iteration)mse = model.best_score["valid_0"]["l2"] # 获取MSE值print(f"调优后模型评估结果:")
print(f"均方误差(MSE):{mse}")
生成交易信号
使用训练好的模型生成买卖信号,并将其应用于回测。
python"># 在整个数据集上进行预测
df["predicted_signal_lightgbm"] = model.predict(df[features])
df["signal"] = (df["predicted_signal_lightgbm"] > 0.5).astype(int)# 检查信号
print(df[["trade_date", "close", "predicted_signal_lightgbm", "signal"]].head())# 打印预测结果
print(df["predicted_signal_lightgbm"].describe())
print(df["predicted_signal_lightgbm"].value_counts(bins=10))
回测与性能评估
使用VectorBT进行策略回测是验证策略表现的重要步骤。通过回测,我们可以评估策略在历史数据上的表现,并对其进行优化。
python"># 创建价格序列
price = df["close"].astype(float)# 创建信号序列
entries = df["ml_signal"] == 1 # 买入信号
exits = df["ml_signal"] == 0 # 卖出信号# 定义并运行策略
pf = vbt.Portfolio.from_signals(price, entries, exits, fees=0.001, init_cash=100000, freq="D"
)# 打印策略的表现
print(pf.stats())# 绘制累积收益曲线
pf.plot().show()# 绘制持仓情况
pf.plot_positions().show()# 绘制最大回撤图
pf.plot_drawdowns().show()# 打印详细交易记录
print(pf.trades.records_readable)
5.2.2 使用PyTorch进行深度学习
PyTorch是一个强大的深度学习库,我们可以使用它来构建神经网络模型,预测市场趋势并生成交易信号。
数据准备
python">import torch
import torch.nn as nn
import torch.optim as optim# 转换数据为Tensor
X_train_tensor = torch.tensor(X_train.values, dtype=torch.float32)
y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32).view(-1, 1)
X_test_tensor = torch.tensor(X_test.values, dtype=torch.float32)
y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32).view(-1, 1)# 创建数据加载器
train_dataset = torch.utils.data.TensorDataset(X_train_tensor, y_train_tensor)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=32, shuffle=True)
构建神经网络模型
python">class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.fc1 = nn.Linear(10, 16)self.fc2 = nn.Linear(16, 8)self.fc3 = nn.Linear(8, 1)self.sigmoid = nn.Sigmoid()def forward(self, x):x = torch.relu(self.fc1(x))x = torch.relu(self.fc2(x))x = self.sigmoid(self.fc3(x))return xmodel = Net()
criterion = nn.BCELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
训练模型
python"># 训练模型
num_epochs = 100
for epoch in range(num_epochs):for inputs, targets in train_loader:optimizer.zero_grad()outputs = model(inputs)loss = criterion(outputs, targets)loss.backward()optimizer.step()if (epoch + 1) % 10 == 0:print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}")for inputs, targets in train_loader:print(f"Inputs shape: {inputs.shape}")print(f"Targets shape: {targets.shape}")break
生成交易信号
python"># 在整个数据集上进行预测
with torch.no_grad():df["predicted_signal_pytorch"] = (model(torch.tensor(df[features].values, dtype=torch.float32)).numpy().flatten())df["signal"] = (df["predicted_signal_pytorch"] > 0.5).astype(int)# 检查信号
print(df[["trade_date", "close", "predicted_signal_pytorch", "signal"]].head())
5.2.3 回测与性能评估
使用VectorBT进行策略回测是验证策略表现的重要步骤。通过回测,我们可以评估策略在历史数据上的表现,并对其进行优化。
python"># 创建价格序列
price = df["close"].astype(float)# 创建信号序列
entries = df["signal"] == 1 # 买入信号
exits = df["signal"] == 0 # 卖出信号# 定义并运行策略
pf = vbt.Portfolio.from_signals(price, entries, exits, fees=0.001, init_cash=100000, freq="D"
)# 打印策略的表现
print(pf.stats())# 绘制累积收益曲线
pf.plot().show()# 绘制持仓情况
pf.plot_positions().show()# 绘制最大回撤图
pf.plot_drawdowns().show()# 打印详细交易记录
print(pf.trades.records_readable)
5.3 风险管理与资金管理
有效的风险管理与资金管理是确保策略稳健运行的关键。以下是一些常用的风险管理和资金管理方法。
5.3.1 止损与止盈设置
止损和止盈是风险管理的重要手段,可以帮助我们控制单笔交易的风险。
止损(Stop Loss)
- 定义:限制单次交易的最大损失。
- 合理设置:
- 市场波动性:A股市场的波动性相对较高,因此可以设置稍大的止损范围。
- 风险管理:建议单次交易的风险不超过账户总资金的1%到2%。
例如,如果你的账户有10万元人民币,每次交易的风险不超过2%,那么单次交易的最大损失应该是2,000元人民币。
止盈(Take Profit)
- 定义:在达到一定盈利水平时平仓。
- 合理设置:
- 风险回报比:通常建议止盈与止损的比例至少为2:1或更高,这意味着预期盈利至少是潜在亏损的两倍。
- 市场趋势:在强劲的趋势市场中,可以设置更高的止盈目标;在震荡市场中,止盈目标可能需要较低。
例如,如果你的止损是2%,为了保持2:1的风险回报比,止盈应该设置为4%。
固定比例法(Fixed Ratio)
- 定义:每次交易投入的资金占总资金的固定比例。
- 合理设置:
- 风险控制:一般建议每次交易投入的资金不超过总资金的5%到10%。
- 资金管理:确保有足够的资金进行多次交易,并且不会因为一次大的亏损而严重影响整个账户。
例如,如果你的账户有10万元人民币,每次交易投入5%的资金,那么每次交易的资金量是5,000元人民币。
python"># 设置止损和止盈
stop_loss = 0.02 # 2%的止损
take_profit = 0.04 # 4%的止盈# 生成止损和止盈信号
df["stop_loss_price"] = df["close"] * (1 - stop_loss)
df["take_profit_price"] = df["close"] * (1 + take_profit)# 更新信号
df["signal"] = np.where((df["close"] > df["ma5"]) & (df["close"] < df["take_profit_price"]),1,np.where((df["close"] < df["ma5"]) | (df["close"] < df["stop_loss_price"]), -1, 0),
)# 检查信号
print(df[["trade_date", "close", "ma5", "signal", "stop_loss_price", "take_profit_price"]].head()
)
5.3.2 资金分配策略
合理的资金分配策略可以提高整体收益并降低风险。常见的资金分配策略包括固定比例法和凯利公式等。
固定比例法(Fixed Ratio)
- 定义:每次交易投入的资金占总资金的固定比例。
- 合理设置:
- 风险控制:一般建议每次交易投入的资金不超过总资金的5%到10%。
- 资金管理:确保有足够的资金进行多次交易,并且不会因为一次大的亏损而严重影响整个账户。
例如,如果你的账户有10万元人民币,每次交易投入5%的资金,那么每次交易的资金量是5,000元人民币。
python"># 固定比例法
fixed_ratio = 0.05 # 每次交易投入资金的比例# 计算每次交易的资金量
df["position_size"] = fixed_ratio * 100000 / df["close"]# 检查资金分配
print(df[["trade_date", "close", "position_size"]].head())
5.3.3 风险调整后的收益最大化
通过优化资金分配和风险管理措施,我们可以实现风险调整后的收益最大化。
python"># 使用VectorBT进行资金管理和风险管理
pf = vbt.Portfolio.from_signals(price,entries,exits,fees=0.001,init_cash=100000,size=np.abs(df["position_size"]),sl_stop=stop_loss,tp_stop=take_profit,freq="D",
)# 打印策略的表现
print(pf.stats())# 绘制累积收益曲线
pf.plot().show()# 绘制持仓情况
pf.plot_positions().show()# 绘制最大回撤图
pf.plot_drawdowns().show()# 打印详细交易记录
print(pf.trades.records_readable)
风险提示与免责声明
本文内容基于公开信息研究整理,不构成任何形式的投资建议。历史表现不应作为未来收益保证,市场存在不可预见的波动风险。投资者需结合自身财务状况及风险承受能力独立决策,并自行承担交易结果。作者及发布方不对任何依据本文操作导致的损失承担法律责任。市场有风险,投资须谨慎。