
大家好,我是量化老王。上一篇我们完成了多因子策略的实盘落地,包括API对接、自动交易程序开发和实时监控系统搭建——信任不少朋友已经在模拟盘跑通了基础策略。但量化交易的进阶之路,核心在于“持续优化”与“拓展边界”:如何用机器学习提升策略胜率?如何把A股策略适配到港股、美股?如何保障实盘程序7×24小时稳定运行?
本文作为上一篇的进阶篇,依然全程聚焦实操,拒绝理论空谈:① 用随机森林优化多因子策略(含特征工程、模型训练、实盘适配);② 实现策略多市场适配(A股→港股/美股,核心差异与改造步骤);③ 实盘程序运维指南(云服务器部署、日志分析、自动重启);④ 进阶避坑:机器学习过拟合、跨市场交易成本控制等关键问题解决方案。
前置说明:本文代码基于上一篇的多因子实盘框架开发,需先确保上一篇的基础程序能正常运行;部分功能(如美股行情获取)需补充安装依赖库;所有跨市场交易示例均基于同花顺OpenAPI(支持港股/美股对接),权限申请流程与A股类似。
第一部分:用机器学习优化多因子策略(随机森林实操)
上一篇的多因子策略,因子权重是我们主观设定的(如ROE、均线等因子同等重大),这种方式的弊端是“无法适配市场风格变化”。而用随机森林等机器学习算法,能自动学习因子权重、捕捉非线性特征,从而提升策略的预测准确率。
核心逻辑:把“股票未来10天是否上涨”作为标签(1=上涨,0=下跌),以上一篇的基本面+技术面因子作为特征,用历史数据训练随机森林模型,再用模型预测实盘股票的上涨概率,只对概率高于阈值的股票执行交易。
第一步:数据准备与特征工程(实盘级数据处理)
特征工程是机器学习策略的核心,直接决定模型效果。我们基于上一篇的6个基础因子,新增4个衍生因子,同时处理缺失值、异常值和数据标准化。
# 数据准备与特征工程
from thsopenapi import THSAPI
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
# 1. 初始化API(沿用之前的配置)
APP_KEY = "你的appkey"
APP_SECRET = "你的appsecret"
ths_api = THSAPI(appkey=APP_KEY, appsecret=APP_SECRET, test=True)
ths_api.login()
# 2. 定义因子列表(基础因子+衍生因子)
BASIC_FACTORS = [
"roe", "debt_to_assets", "pe_ttm", # 基本面基础因子
"ma5/ma20", "ma20/ma60", "volume/vol_20_avg" # 技术面基础因子(比值形式)
]
DERIVED_FACTORS = [
"roe_3m_change", # ROE近3个月变化率
"pe_relative", # 个股PE/沪深300PE
"volatility_20d", # 20日波动率(收盘价标准差)
"momentum_20d" # 20日动量(当前价/20日前价-1)
]
ALL_FACTORS = BASIC_FACTORS + DERIVED_FACTORS
# 3. 获取历史数据(用于训练模型,提议取3年数据)
def get_historical_data(symbol_list, start_date="20210101", end_date="20231231"):
all_data = []
for symbol in symbol_list[:30]: # 取30只沪深300成分股,平衡数据量与效率
try:
# 获取日线数据(含行情和基础因子)
daily_data = ths_api.get_historical_data(
symbol=symbol,
start_date=start_date,
end_date=end_date,
fields="date,close,ma5,ma20,ma60,volume,vol_20_avg,roe,debt_to_assets,pe_ttm"
)
# 计算基础因子(比值形式)
daily_data["ma5/ma20"] = daily_data["ma5"] / daily_data["ma20"]
daily_data["ma20/ma60"] = daily_data["ma20"] / daily_data["ma60"]
daily_data["volume/vol_20_avg"] = daily_data["volume"] / daily_data["vol_20_avg"]
# 计算衍生因子
daily_data["roe_3m_change"] = daily_data["roe"].pct_change(12) # 每月1个ROE数据,3个月=12个交易日
hs300_pe = ths_api.get_index_historical_data(
index_code="000300.SH",
start_date=start_date,
end_date=end_date,
fields="date,pe_ttm"
).rename(columns={"pe_ttm": "hs300_pe"})
daily_data = pd.merge(daily_data, hs300_pe, on="date", how="left")
daily_data["pe_relative"] = daily_data["pe_ttm"] / daily_data["hs300_pe"]
daily_data["volatility_20d"] = daily_data["close"].rolling(20).std()
daily_data["momentum_20d"] = daily_data["close"] / daily_data["close"].shift(20) - 1
# 构建标签:未来10天上涨则为1,否则为0
daily_data["next_10d_return"] = daily_data["close"].shift(-10) / daily_data["close"] - 1
daily_data["label"] = (daily_data["next_10d_return"] > 0).astype(int)
# 保留有效列,删除缺失值
daily_data = daily_data[["date", "symbol"] + ALL_FACTORS + ["label"]].dropna()
all_data.append(daily_data)
except Exception as e:
print(f"获取{symbol}历史数据失败:{e}")
continue
return pd.concat(all_data, ignore_index=True)
# 4. 数据预处理(标准化+划分训练集/测试集)
def preprocess_data(data):
# 分离特征和标签
X = data[ALL_FACTORS]
y = data["label"]
# 标准化特征(避免量纲影响模型)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
X_scaled = pd.DataFrame(X_scaled, columns=ALL_FACTORS)
# 划分训练集(80%)和测试集(20%),按时间划分避免数据泄露
split_date = data["date"].quantile(0.8)
X_train = X_scaled[data["date"] < split_date]
y_train = y[data["date"] < split_date]
X_test = X_scaled[data["date"] >= split_date]
y_test = y[data["date"] >= split_date]
return X_train, y_train, X_test, y_test, scaler
# 执行数据准备与预处理
hs300_stocks = ths_api.get_index_constituents(index_code="000300.SH")["symbol"].tolist()
historical_data = get_historical_data(hs300_stocks)
X_train, y_train, X_test, y_test, scaler = preprocess_data(historical_data)
print(f"训练集规模:{X_train.shape},测试集规模:{X_test.shape}")
print(f"测试集正样本比例(上涨股票占比):{y_test.mean():.2f}")
第二步:训练随机森林模型(含超参数调优)
我们使用scikit-learn库的随机森林分类器,通过网格搜索进行超参数调优,同时验证模型效果(重点关注准确率、召回率和F1分数,避免只看准确率导致的偏差)。
# 训练随机森林模型
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
# 1. 定义模型与超参数搜索范围
rf_model = RandomForestClassifier(random_state=42)
param_grid = {
"n_estimators": [100, 200], # 决策树数量
"max_depth": [5, 10, None], # 最大深度
"min_samples_split": [2, 5], # 最小分裂样本数
"min_samples_leaf": [1, 2] # 最小叶子节点样本数
}
# 2. 网格搜索超参数(交叉验证)
grid_search = GridSearchCV(
estimator=rf_model,
param_grid=param_grid,
cv=5, # 5折交叉验证
scoring="f1", # 用F1分数评估(平衡准确率和召回率)
n_jobs=-1 # 利用所有CPU核心加速
)
grid_search.fit(X_train, y_train)
# 3. 最优模型与效果评估
best_rf = grid_search.best_estimator_
y_pred = best_rf.predict(X_test)
# 计算评估指标
metrics = {
"准确率": accuracy_score(y_test, y_pred),
"准确率": precision_score(y_test, y_pred),
"召回率": recall_score(y_test, y_pred),
"F1分数": f1_score(y_test, y_pred)
}
print("模型最优超参数:", grid_search.best_params_)
print("模型评估指标:")
for k, v in metrics.items():
print(f"{k}:{v:.4f}")
# 4. 特征重大性分析(了解哪些因子对预测最关键)
feature_importance = pd.DataFrame({
"factor": ALL_FACTORS,
"importance": best_rf.feature_importances_
}).sort_values("importance", ascending=False)
print("
特征重大性排序:")
print(feature_importance)
# 5. 保存模型和scaler(实盘时直接加载,无需重新训练)
import joblib
joblib.dump(best_rf, "rf_quant_model.pkl")
joblib.dump(scaler, "data_scaler.pkl")
print("
模型和标准化器已保存至本地!")
第三步:模型适配实盘(预测+交易信号生成)
将训练好的模型集成到上一篇的实盘框架中,把“因子筛选”替换为“模型预测”,只对上涨概率≥0.6的股票生成买入信号(阈值可根据实盘效果调整)。
# 模型适配实盘(集成到上一篇的实盘程序)
import joblib
from thsopenapi import THSAPI
import pandas as pd
# 1. 加载模型和scaler
best_rf = joblib.load("rf_quant_model.pkl")
scaler = joblib.load("data_scaler.pkl")
# 2. 实盘数据预处理(与训练时一致)
def preprocess_real_time_data(stock_data):
# 构建特征矩阵(顺序与训练时一致)
features = pd.DataFrame({
"roe": [stock_data["roe"]],
"debt_to_assets": [stock_data["debt_to_assets"]],
"pe_ttm": [stock_data["pe_ttm"]],
"ma5/ma20": [stock_data["ma5"] / stock_data["ma20"]],
"ma20/ma60": [stock_data["ma20"] / stock_data["ma60"]],
"volume/vol_20_avg": [stock_data["volume"] / stock_data["vol_20_avg"]],
"roe_3m_change": [stock_data["roe_3m_change"]],
"pe_relative": [stock_data["pe_ttm"] / stock_data["hs300_pe"]],
"volatility_20d": [stock_data["volatility_20d"]],
"momentum_20d": [stock_data["momentum_20d"]]
})
# 标准化
features_scaled = scaler.transform(features)
return features_scaled
# 3. 改造generate_signal函数(用模型预测替代传统因子筛选)
def generate_signal_with_rf(symbol):
try:
# 获取实时数据(含基础因子和衍生因子)
real_time_data = get_real_time_data(symbol) # 复用之前的函数,补充衍生因子计算
if not real_time_data:
return "none"
# 预处理实时数据
features_scaled = preprocess_real_time_data(real_time_data)
# 预测上涨概率(predict_proba返回[负类概率, 正类概率])
up_prob = best_rf.predict_proba(features_scaled)[0][1]
# 获取持仓信息(用于止损)
position = ths_api.get_position(symbol=symbol)
avg_cost = position["avg_cost"] if position else 0
current_price = real_time_data["close"]
# 买入信号:上涨概率≥0.6且无持仓
if up_prob >= 0.6 and not position:
return "buy"
# 卖出信号:上涨概率≤0.3或触发止损(亏损5%)
stop_loss_condition = (avg_cost > 0) and (current_price < avg_cost * 0.95)
if (up_prob <= 0.3 and position) or stop_loss_condition:
return "sell"
return "none"
except Exception as e:
print(f"{symbol} 信号生成失败:{e}")
return "none"
# 4. 替换实盘主程序中的信号生成函数
# 找到上一篇real_trade_main函数中的信号生成部分,替换为:
# signal = generate_signal_with_rf(symbol)
print("模型已成功集成到实盘信号生成逻辑!")
关键提示:机器学习策略避坑要点
1. 避免数据泄露:绝对不能用未来数据训练模型(如用当天收盘价计算的因子预测当天是否上涨),本文按时间划分训练集/测试集是核心解决方案;
2. 拒绝过度拟合:模型在测试集的准确率远高于实盘准确率,就是过度拟合。解决方案:减少特征数量、增加正则化(如设置max_depth)、用更大规模数据训练;
3. 动态更新模型:市场风格会变(如2023年小盘股行情,2024年蓝筹股行情),提议每月用最新1个月数据微调模型参数,每季度重新训练一次模型。
第二部分:策略多市场适配(A股→港股/美股实操)
把A股多因子策略拓展到港股、美股,核心是解决“市场规则差异”和“数据格式差异”。我们以同花顺OpenAPI为例,实现策略的跨市场迁移,重点改造3个部分:市场基础信息、交易规则适配、数据字段调整。
第一步:跨市场API权限申请与基础配置
# 跨市场API配置(A股+港股+美股)
from thsopenapi import THSAPI
import time
from datetime import datetime
# 1. 多市场API配置(需在同花顺开放平台额外申请港股/美股权限)
APP_KEY = "你的appkey"
APP_SECRET = "你的appsecret"
TEST_MODE = True
# 2. 多市场基础信息配置(核心差异:代码前缀、交易时间、最小交易单位)
MARKET_CONFIG = {
"A股": {
"prefix": "", # 股票代码无前缀,如600000.SH
"index_code": "000300.SH", # 基准指数:沪深300
"trading_hours": [(9, 30, 11, 30), (13, 0, 15, 0)],
"min_trade_unit": 100, # 最小交易单位:100股
"commission_rate": 0.0005, # 佣金率:0.05%
"stamp_duty": 0.001 # 印花税:0.1%(卖出时收取)
},
"港股": {
"prefix": "HK.", # 股票代码前缀,如HK.00700(腾讯控股)
"index_code": "HSI.HI", # 基准指数:恒生指数
"trading_hours": [(9, 30, 12, 0), (13, 0, 16, 0)],
"min_trade_unit": 100, # 部分股票为1000股,需单独处理
"commission_rate": 0.0015, # 佣金率:0.15%
"stamp_duty": 0.0013 # 印花税:0.13%(卖出时收取)
},
"美股": {
"prefix": "US.", # 股票代码前缀,如US.AAPL(苹果)
"index_code": "SPX.GI", # 基准指数:标普500
"trading_hours": [(21, 30, 4, 0)], # 北京时间(夏令时)
"min_trade_unit": 1, # 最小交易单位:1股
"commission_rate": 0.00, # 部分券商免佣金
"stamp_duty": 0.00 # 无印花税
}
}
# 3. 初始化多市场API(同花顺API支持多市场统一对接)
ths_api = THSAPI(appkey=APP_KEY, appsecret=APP_SECRET, test=TEST_MODE)
ths_api.login()
# 4. 通用函数:获取指定市场的成分股列表
def get_market_constituents(market):
config = MARKET_CONFIG[market]
try:
constituents = ths_api.get_index_constituents(index_code=config["index_code"])
# 为港股/美股添加代码前缀
constituents["symbol"] = config["prefix"] + constituents["symbol"]
return constituents["symbol"].tolist()
except Exception as e:
print(f"获取{market}成分股失败:{e}")
return []
# 测试多市场成分股获取
a_share_stocks = get_market_constituents("A股")
hk_stocks = get_market_constituents("港股")
us_stocks = get_market_constituents("美股")
print(f"A股沪深300成分股数量:{len(a_share_stocks)}")
print(f"港股恒生指数成分股数量:{len(hk_stocks)}")
print(f"美股标普500成分股数量:{len(us_stocks)}")
第二步:核心函数跨市场改造(数据获取+下单+风险控制)
重点改造3个核心函数:① 跨市场数据获取(适配不同市场的字段差异);② 下单函数(适配最小交易单位、成本计算);③ 交易时间判断(适配不同市场的交易时段)。
第三步:多市场实盘主程序整合
# 多市场实盘主程序
def cross_market_real_trade(markets=["A股", "港股", "美股"]):
print("="*60)
print(f"多市场实盘程序启动时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"当前模式:{'模拟盘' if TEST_MODE else '实盘'}")
print(f"参与市场:{','.join(markets)}")
print("="*60)
while True:
for market in markets:
# 仅在该市场交易时间执行
if not is_cross_market_trading_time(market):
print(f"{market}当前非交易时间,跳过...")
continue
try:
# 1. 获取该市场成分股
stock_list = get_market_constituents(market)
if not stock_list:
print(f"未获取到{market}股票列表,跳过...")
continue
# 2. 筛选股票(用改造后的机器学习模型)
selected_stocks = []
for symbol in stock_list[:10]: # 取前10只,提升效率
stock_data = get_cross_market_stock_data(symbol, market)
if stock_data:
selected_stocks.append(symbol)
selected_stocks = selected_stocks[:3] # 每个市场最多选3只,分散风险
print(f"{market}当前筛选出的优质股票:{selected_stocks}")
# 3. 生成信号并交易
for symbol in selected_stocks:
signal = generate_signal_with_rf(symbol) # 复用机器学习信号函数
if signal != "none":
cross_market_auto_trade(symbol, signal, market)
except Exception as e:
print(f"{market}交易环节异常:{e}")
continue
# 休眠60秒,刷新行情
print(f"
等待60秒后刷新多市场行情...")
print("-"*60)
time.sleep(60)
# 启动多市场实盘程序
if __name__ == "__main__":
cross_market_real_trade(markets=["A股", "港股"]) # 可根据需求选择市场
第三部分:实盘程序运维指南(云服务器部署+稳定运行)
个人量化实盘的最大痛点之一是“程序稳定性”——本地电脑关机、断网都会导致程序停止。解决方案是将程序部署在云服务器(阿里云/腾讯云),并配置自动重启、日志监控、异常报警,实现7×24小时稳定运行。
第一步:云服务器环境配置(以阿里云ECS为例)
# 云服务器环境配置步骤(Linux CentOS 7)
# 1. 登录云服务器(通过SSH工具,如Xshell)
# ssh 用户名@服务器公网IP(如:ssh root@123.45.67.89)
# 2. 安装Python 3.9(CentOS默认Python 2.7,需升级)
yum install -y gcc openssl-devel bzip2-devel libffi-devel
wget https://www.python.org/ftp/python/3.9.10/Python-3.9.10.tgz
tar xzf Python-3.9.10.tgz
cd Python-3.9.10
./configure --enable-optimizations
make altinstall # 避免覆盖系统默认Python
# 3. 安装pip3.9
wget https://bootstrap.pypa.io/get-pip.py
python3.9 get-pip.py
# 4. 安装实盘所需依赖库
pip3.9 install thsopenapi pandas numpy scikit-learn matplotlib joblib
# 5. 配置防火墙(开放SSH端口和程序所需端口)
firewall-cmd --permanent --add-port=22/tcp # SSH端口
firewall-cmd --permanent --add-port=8080/tcp # 若监控程序需web访问
firewall-cmd --reload
# 6. 上传本地程序文件到服务器(用SCP工具)
# scp 本地文件路径 用户名@服务器IP:服务器目标路径
# 示例:scp C:/quant/real_trade.py root@123.45.67.89:/root/quant/
第二步:配置程序自动启动与重启(systemd服务)
通过systemd配置服务,实现“服务器开机自动启动程序”“程序崩溃自动重启”,无需手动干预。
# 配置systemd服务
# 1. 创建服务文件
vi /etc/systemd/system/quant_trade.service
# 2. 写入以下内容(按实际路径修改)
[Unit]
Description=Quant Trading Service
After=network.target # 网络启动后再启动服务
[Service]
User=root # 运行用户
WorkingDirectory=/root/quant # 程序所在目录
ExecStart=/usr/local/bin/python3.9 /root/quant/cross_market_real_trade.py # 程序启动命令
Restart=always # 任何情况下崩溃都自动重启
RestartSec=60 # 崩溃后60秒再重启
StandardOutput=append:/root/quant/trade_service.log # 输出日志路径
StandardError=append:/root/quant/trade_error.log # 错误日志路径
[Install]
WantedBy=multi-user.target
# 3. 启用并启动服务
systemctl daemon-reload # 重新加载服务配置
systemctl enable quant_trade.service # 设置开机自启
systemctl start quant_trade.service # 启动服务
# 4. 查看服务状态
systemctl status quant_trade.service
# 常用命令
# 停止服务:systemctl stop quant_trade.service
# 重启服务:systemctl restart quant_trade.service
# 查看日志:tail -f /root/quant/trade_service.log
第三步:日志分析与远程监控(实操方案)
配置远程日志查看和监控告警,实时掌握程序运行状态,出现异常立即处理。
远程访问监控:在本地浏览器输入“http://服务器公网IP:8080/quant/status”,即可查看程序运行状态和最新日志(需确保服务器8080端口已开放)。
第四部分:进阶避坑指南——跨市场与机器学习策略专属
1. 跨市场汇率风险:港股/美股交易以港币/美元结算,人民币汇率波动会影响实际收益。解决方案:在风险控制参数中加入“汇率波动容忍度”,或配置外汇对冲工具(新手暂可忽略,小资金影响有限);
2. 美股夏令时/冬令时切换:每年3月和11月美股会切换时间,程序需自动适配。解决方案:调用API获取实时交易时间(而非硬编码),本文已提供简化版适配方案;
3. 机器学习模型漂移:模型在实盘运行一段时间后,准确率下降(市场风格变化导致)。解决方案:设置“模型健康度监控”,当实盘胜率连续2周低于测试集胜率的80%,自动触发模型重新训练;
4. 云服务器成本控制:阿里云/腾讯云入门级ECS(2核4G)每月成本约100-200元,新手可选择“突发性能实例”降低成本,非交易时间可关闭服务器(需配合定时任务)。
第五部分:今日练习(进阶实操巩固)
1. 基于本文代码,完成随机森林模型训练与实盘集成,对比优化前后策略的模拟盘收益(重点看胜率和最大回撤);
2. 开通港股/美股模拟盘权限,跑通多市场实盘程序,记录不同市场的策略表现差异;
3. 购买阿里云ECS服务器,完成程序部署、systemd服务配置和远程监控搭建;
4. 新增“模型漂移监控”功能,当实盘胜率低于阈值时,自动发送邮件预警。
最后:量化交易的进阶之路无止境
到这一篇为止,我们已经从“Python基础”走到了“机器学习优化+多市场实盘+云服务器运维”——这已经超越了大部分个人量化新手的水平。但请记住:量化交易没有“终极策略”,市场永远在变化,你的策略也需要持续迭代。
下一篇,我们将进入“高阶内容”:教大家搭建量化交易回测平台(支持多策略对比、自定义因子),以及高频交易策略的核心实操(含订单簿数据处理、延迟优化)。如果在进阶过程中遇到模型过拟合、跨市场交易报错、服务器部署失败等问题,评论区贴出你的问题和代码,我会逐一解答。
温馨提示:本文所有代码仅作学习参考,不构成投资提议。跨市场交易风险高于单一市场,实盘前务必充分测试!





