机器学习量化投资:如何构建高收益的价值投资组合

机器学习量化投资:如何构建高收益的价值投资组合

引言:价值投资的“老酒”与机器学习的“新瓶”

沃伦·巴菲特的办公室里挂着一张本杰明·格雷厄姆的照片——这位“价值投资之父”的名言“价格是你付出的,价值是你得到的”,至今仍是价值投资的核心准则。但在21世纪的今天,当4000+只A股、10万+条财务数据、每分钟10万条新闻涌来时,传统价值投资者的“手动筛选+主观判断”模式,早已无法应对数据爆炸的挑战。

机器学习(ML)的出现,给价值投资带来了“升维”的可能:它能像“超级显微镜”一样,从噪声中挖掘财务数据的非线性关联;像“情绪探测器”一样,解析新闻、社交媒体中的隐藏信号;像“动态优化器”一样,实时调整组合权重以应对市场变化。

本文将带你从0到1构建一个机器学习驱动的价值投资组合——不仅讲清楚“为什么”,更用Python代码演示“怎么做”,最终帮你实现“高收益+低风险”的价值投资目标。

一、基础概念:价值投资与机器学习的“化学反应”

在开始实战前,我们需要先明确三个核心概念,避免“为了机器学习而机器学习”。

1.1 价值投资的本质:买“被低估的好公司”

价值投资的底层逻辑可以用一个公式概括:
投资收益 = 内在价值回归收益 + 公司成长收益 \text{投资收益} = \text{内在价值回归收益} + \text{公司成长收益} 投资收益=内在价值回归收益+公司成长收益

  • 内在价值(Intrinsic Value):公司未来现金流的折现总和(经典DCF模型);
  • 被低估:市场价格 < 内在价值(即“用50元买价值100元的东西”);
  • 好公司:具有“护城河”(Moat)——比如品牌(茅台)、技术(华为)、规模(宁德时代),能持续产生现金流。

传统价值投资的痛点:

  • 依赖线性指标(PE、PB、ROE),无法捕捉特征间的交互(比如“ROE高但负债高”的公司可能风险更大);
  • 忽略非财务数据(比如新闻中的管理层风险、社交媒体的用户情绪);
  • 无法处理高维数据(比如同时分析100个财务指标+50个替代数据)。

1.2 机器学习的角色:增强价值投资的“三大能力”

机器学习不是取代价值投资,而是强化其核心能力

  1. 数据挖掘能力:从高维数据中发现非线性关联(比如“ROE趋势+行业集中度”共同影响收益率);
  2. 信号处理能力:将非结构化数据(新闻、年报)转化为可量化的特征(比如用BERT提取年报中的“风险关键词”频率);
  3. 动态优化能力:用强化学习实时调整组合权重,应对市场波动(比如在经济下行期降低高负债公司的权重)。

1.3 高收益价值组合的目标:夏普比率>2,最大回撤<15%

我们的目标不是“赚快钱”,而是长期稳定的超额收益。关键指标:

  • 年化收益率:超过基准(比如沪深300)5%以上;
  • 夏普比率:≥2(每承担1单位风险获得2单位收益);
  • 最大回撤:≤15%(下跌幅度不超过15%,避免“一夜回到解放前”)。

二、核心流程:构建机器学习价值组合的“六步曲”

构建高收益价值组合的核心流程可以总结为:
数据收集→预处理→特征工程→模型训练→回测验证→组合优化

接下来我们用Python代码逐一实现每个步骤,并解释背后的逻辑。


2.1 第一步:数据收集——“巧妇难为无米之炊”

价值投资的数据源分为两类:财务数据(公司基本面)和替代数据(非财务信号)。

2.1.1 数据来源推荐
数据类型推荐工具/API说明
财务数据Tushare(免费)、Wind(付费)包含PE、PB、ROE、净利润增长率等核心指标
股价数据Yahoo Finance、Tushare日度/月度收盘价、成交量
行业分类申万一级行业分类用于计算行业调整后的指标(比如“公司ROE-行业平均ROE”)
替代数据NewsAPI(新闻)、Twitter API非结构化数据,用于提取市场情绪(比如“特斯拉召回”的新闻 sentiment)
2.1.2 代码实现:用Tushare获取财务数据

首先安装Tushare并获取token(注册地址:https://tushare.pro/):

pip install tushare pandas numpy

然后编写数据获取代码:

import tushare as ts
import pandas as pd
import numpy as np

# 初始化Tushare API
ts.set_token("你的Tushare Token")
pro = ts.pro_api()

# 1. 获取沪深300成分股(价值投资通常选择大盘股,稳定性更强)
hs300 = pro.index_component(index_code="000300.SH", start_date="20180101", end_date="20231231")
stock_list = hs300["con_code"].tolist()[:100]  # 取前100只股票(减少计算量)

# 2. 获取财务数据(PE_TTM、PB、ROE、净利润增长率)
financial_data = []
for ts_code in stock_list:
    df = pro.fina_indicator(
        ts_code=ts_code,
        start_date="20180101",
        end_date="20231231",
        fields="ts_code,ann_date,pe_ttm,pb,roe,net_profit_growth_rate"
    )
    financial_data.append(df)
financial_data = pd.concat(financial_data, ignore_index=True)

# 3. 获取股价数据(用于计算未来收益率)
price_data = []
for ts_code in stock_list:
    df = pro.daily(
        ts_code=ts_code,
        start_date="20180101",
        end_date="20231231",
        fields="ts_code,trade_date,close"
    )
    price_data.append(df)
price_data = pd.concat(price_data, ignore_index=True)
price_data["trade_date"] = pd.to_datetime(price_data["trade_date"])
price_data.set_index("trade_date", inplace=True)

2.2 第二步:数据预处理——“脏数据比没有数据更可怕”

财务数据往往存在缺失值异常值时间错位问题,必须先清洗。

2.2.1 处理缺失值:用行业均值填充

财务数据的缺失通常是因为公司未披露(比如新上市公司),直接删除会损失样本,因此用行业均值填充(同一行业的公司特征更相似):

# 获取行业分类(需要先实现get_industry函数,可调用Tushare的stock_basic接口)
def get_industry(ts_code):
    df = pro.stock_basic(ts_code=ts_code, fields="industry")
    return df["industry"].iloc[0]

financial_data["industry"] = financial_data["ts_code"].apply(get_industry)

# 用行业均值填充缺失值
industry_means = financial_data.groupby("industry")[["pe_ttm", "pb", "roe", "net_profit_growth_rate"]].transform("mean")
financial_data.fillna(industry_means, inplace=True)
2.2.2 处理异常值: Winsorize截断

异常值(比如PE=1000)会干扰模型训练,用Winsorize截断(保留95%的正常数据):

from scipy.stats.mstats import winsorize

# 对PE_TTM、PB进行Winsorize(截断上下2.5%的异常值)
financial_data["pe_ttm"] = winsorize(financial_data["pe_ttm"], limits=[0.025, 0.025])
financial_data["pb"] = winsorize(financial_data["pb"], limits=[0.025, 0.025])
2.2.3 时间对齐:财务数据→月度频率

财务数据是季度/年度的,而股价数据是日度的,需要将财务数据对齐到月度频率(避免数据滞后):

# 将ann_date转换为 datetime
financial_data["ann_date"] = pd.to_datetime(financial_data["ann_date"])
# 按月度重采样(取每月最后一个交易日的财务数据)
financial_data = financial_data.set_index("ann_date").resample("M").last().reset_index()

2.3 第三步:特征工程——“数据决定模型上限”

特征工程是机器学习价值投资的核心竞争力。我们需要将原始数据转化为有预测能力的特征,分为三类:

2.3.1 传统财务特征:“经典指标的再加工”

传统指标(PE、PB、ROE)是价值投资的基础,但需要行业调整趋势分析

  • 行业调整后的PEpe_industry_adjusted = 公司PE - 行业平均PE(消除行业估值差异);
  • ROE趋势roe_trend = 过去3年ROE的斜率(判断公司盈利能力是否持续提升);
  • PE分位数pe_quantile = 公司PE在过去5年的分位数(判断当前PE是否处于历史低位)。

代码实现:

# 1. 行业调整后的PE
financial_data["pe_industry_adjusted"] = financial_data["pe_ttm"] - financial_data.groupby("industry")["pe_ttm"].transform("mean")

# 2. ROE趋势(过去3个月的斜率)
def calculate_trend(series):
    if len(series) < 3:
        return np.nan
    x = np.arange(len(series))
    slope, _ = np.polyfit(x, series, 1)  # 线性回归求斜率
    return slope

financial_data["roe_trend"] = financial_data.groupby("ts_code")["roe"].transform(calculate_trend)

# 3. PE分位数(过去12个月的分位数)
financial_data["pe_quantile"] = financial_data.groupby("ts_code")["pe_ttm"].transform(lambda x: x.rank(pct=True))
2.3.2 替代数据特征:“非财务信号的量化”

替代数据(新闻、社交媒体)能提前反映市场情绪,比如“公司被监管处罚”的新闻会导致股价下跌。我们用BERT模型提取新闻的sentiment(正面/负面):

首先安装Hugging Face的Transformers库:

pip install transformers torch

然后编写sentiment分析代码:

from transformers import BertTokenizer, BertForSequenceClassification
import torch

# 加载预训练的BERT sentiment模型(中文)
tokenizer = BertTokenizer.from_pretrained("uer/bert-base-chinese-finetuned-dianping-chinese")
model = BertForSequenceClassification.from_pretrained("uer/bert-base-chinese-finetuned-dianping-chinese")

def get_news_sentiment(news_text):
    #  tokenize文本
    inputs = tokenizer(news_text, return_tensors="pt", truncation=True, padding=True)
    # 模型预测
    outputs = model(**inputs)
    logits = outputs.logits
    # 转换为sentiment分数(0=负面,1=正面)
    sentiment = torch.argmax(logits, dim=1).item()
    return sentiment

# 假设我们有新闻数据(news_data:包含ts_code、ann_date、news_text)
news_data["sentiment"] = news_data["news_text"].apply(get_news_sentiment)

# 将sentiment合并到财务数据中
financial_data = pd.merge(financial_data, news_data[["ts_code", "ann_date", "sentiment"]], on=["ts_code", "ann_date"], how="left")
2.3.3 特征选择:“保留有用的,剔除冗余的”

并非所有特征都有预测能力,我们用**互信息(Mutual Information)**筛选与目标变量(未来收益率)相关性高的特征:

from sklearn.feature_selection import mutual_info_regression

# 定义目标变量:未来12个月的收益率(超过沪深300的部分)
def calculate_excess_return(ts_code):
    # 获取公司股价和沪深300指数
    stock_price = price_data[price_data["ts_code"] == ts_code]["close"]
    hs300_price = pro.index_daily(ts_code="000300.SH", start_date=stock_price.index.min(), end_date=stock_price.index.max())["close"]
    # 对齐时间
    stock_price = stock_price.reindex(hs300_price.index, method="ffill")
    # 计算未来12个月的收益率
    future_return = stock_price.pct_change(periods=12).shift(-12)
    # 计算超额收益率(公司收益率 - 沪深300收益率)
    hs300_return = hs300_price.pct_change(periods=12).shift(-12)
    excess_return = future_return - hs300_return
    return excess_return

# 计算每个股票的超额收益率
financial_data["excess_return"] = financial_data["ts_code"].apply(calculate_excess_return)

# 特征列表
features = ["pe_ttm", "pb", "roe", "net_profit_growth_rate", "pe_industry_adjusted", "roe_trend", "pe_quantile", "sentiment"]
X = financial_data[features]
y = financial_data["excess_return"]

# 计算互信息
mi = mutual_info_regression(X, y)
mi_series = pd.Series(mi, index=features)
mi_series.sort_values(ascending=False, inplace=True)

# 保留互信息前5的特征
selected_features = mi_series[:5].index.tolist()
print(f"Selected Features: {selected_features}")

输出示例:
Selected Features: ['roe_trend', 'pe_industry_adjusted', 'pe_quantile', 'sentiment', 'roe']


2.4 第四步:模型训练——“选择最适合价值投资的模型”

价值投资的核心是预测“被低估”的股票,属于回归问题(预测未来超额收益率)或分类问题(判断是否跑赢基准)。我们选择XGBoost(极端梯度提升树)——它能处理非线性特征、避免过拟合,是量化投资中最常用的模型之一。

2.4.1 模型选择的逻辑
  • 线性模型(比如LR):无法捕捉特征交互(比如“ROE高且sentiment正面”的组合效应);
  • 随机森林:容易过拟合高维数据;
  • XGBoost:通过梯度提升和正则化,平衡了模型复杂度和泛化能力。
2.4.2 代码实现:用XGBoost预测超额收益率
from xgboost import XGBRegressor
from sklearn.model_selection import TimeSeriesSplit
from sklearn.metrics import mean_squared_error, r2_score

# 时间序列分割(避免数据泄漏)
tscv = TimeSeriesSplit(n_splits=5)  # 5折交叉验证

# 初始化模型
model = XGBRegressor(
    n_estimators=100,  # 树的数量
    learning_rate=0.1,  # 学习率
    max_depth=3,  # 树的深度(避免过拟合)
    subsample=0.8,  # 样本采样率
    colsample_bytree=0.8,  # 特征采样率
    random_state=42
)

# 训练与验证
scores = []
for train_idx, test_idx in tscv.split(X):
    # 时间序列分割:训练集是过去,测试集是未来
    X_train, X_test = X.iloc[train_idx][selected_features], X.iloc[test_idx][selected_features]
    y_train, y_test = y.iloc[train_idx], y.iloc[test_idx]
    
    # 训练模型
    model.fit(X_train, y_train)
    
    # 预测
    y_pred = model.predict(X_test)
    
    # 计算指标(RMSE:均方根误差;R²:决定系数)
    rmse = mean_squared_error(y_test, y_pred, squared=False)
    r2 = r2_score(y_test, y_pred)
    scores.append((rmse, r2))

# 输出平均指标
avg_rmse = np.mean([s[0] for s in scores])
avg_r2 = np.mean([s[1] for s in scores])
print(f"Average RMSE: {avg_rmse:.4f}")
print(f"Average R²: {avg_r2:.4f}")

输出示例:
Average RMSE: 0.0823
Average R²: 0.3567

说明:R²=0.35表示模型能解释35%的收益率变化,这在金融领域已经是非常不错的结果(金融数据的噪声很大)。

2.4.3 模型解释:用SHAP值看“哪些特征最关键”

机器学习模型常被诟病“黑箱”,我们用**SHAP(SHapley Additive exPlanations)**解释模型的决策逻辑:

import shap

# 初始化SHAP解释器
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X_train[selected_features])

# 1. Summary Plot(展示特征的重要性和影响方向)
shap.summary_plot(shap_values, X_train[selected_features], feature_names=selected_features)

# 2. Dependence Plot(展示单个特征与预测结果的关系)
shap.dependence_plot("roe_trend", shap_values, X_train[selected_features], feature_names=selected_features)

结果解读

  • Summary Plot显示:roe_trend(ROE趋势)是最关键的特征,且斜率为正(ROE趋势越高,预测超额收益率越高);
  • Dependence Plot显示:当roe_trend>0.5时,预测超额收益率显著上升——这符合价值投资的逻辑:持续提升的ROE说明公司盈利能力在增强

2.5 第五步:回测验证——“用历史数据检验策略”

回测是量化投资的“试金石”——只有通过历史数据验证的策略,才能进入实盘。我们用Backtrader(Python最流行的回测框架)实现回测。

2.5.1 回测的核心逻辑

我们的策略是:

  1. 每月末用模型预测所有股票的未来12个月超额收益率;
  2. 选择预测收益率前20%的股票(被低估的好公司);
  3. 等权重买入这些股票,持有12个月后卖出(价值投资需要长期持有)。
2.5.2 代码实现:Backtrader回测

首先安装Backtrader:

pip install backtrader

然后编写策略代码:

import backtrader as bt
import backtrader.feeds as btfeeds

class ValueInvestingStrategy(bt.Strategy):
    params = (
        ("model", None),  # 训练好的XGBoost模型
        ("features", None),  # 选中的特征
        ("top_percent", 0.2),  # 选择前20%的股票
        ("hold_period", 12),  # 持有12个月
    )

    def __init__(self):
        self.data_close = self.datas[0].close  # 股价数据
        self.data_features = self.getdatabyname("features")  # 特征数据
        self.rebalance_dates = []  # 再平衡日期(每月末)
        self.current_holdings = []  # 当前持有的股票

    def next(self):
        # 每月末进行再平衡
        if self.data.datetime.date(0).month != self.data.datetime.date(-1).month:
            self.rebalance()

    def rebalance(self):
        # 1. 获取当前时间点的特征数据
        current_date = self.data.datetime.date(0)
        current_features = self.data_features.loc[current_date, self.params.features]
        
        # 2. 预测超额收益率
        predicted_returns = self.params.model.predict(current_features)
        
        # 3. 选择前20%的股票
        top_stocks = predicted_returns.sort_values(ascending=False)[:int(len(predicted_returns)*self.params.top_percent)].index
        
        # 4. 卖出不在top_stocks中的股票
        for stock in self.current_holdings:
            if stock not in top_stocks:
                self.sell(data=self.getdatabyname(stock))
        
        # 5. 买入top_stocks中的股票(等权重)
        weight = 1 / len(top_stocks)
        for stock in top_stocks:
            size = (self.broker.getvalue() * weight) // self.getdatabyname(stock).close[0]
            if size > 0:
                self.buy(data=self.getdatabyname(stock), size=size)
        
        # 更新当前持仓
        self.current_holdings = top_stocks

# 1. 初始化Backtrader引擎
cerebro = bt.Cerebro()

# 2. 添加策略(传入训练好的模型和特征)
cerebro.addstrategy(ValueInvestingStrategy, model=model, features=selected_features)

# 3. 添加数据(股价数据和特征数据)
# 假设price_data是按股票代码分组的DataFrame,index是trade_date
for ts_code in stock_list:
    df = price_data[price_data["ts_code"] == ts_code][["close"]]
    data = btfeeds.PandasData(dataname=df, name=ts_code)
    cerebro.adddata(data)

# 添加特征数据(假设features_data是按日期索引的DataFrame)
features_data = financial_data.set_index("ann_date")[selected_features]
features_feed = btfeeds.PandasData(dataname=features_data, name="features")
cerebro.adddata(features_feed)

# 4. 设置初始资金和佣金
cerebro.broker.setcash(1000000.0)  # 初始资金100万
cerebro.broker.setcommission(commission=0.001)  # 佣金0.1%

# 5. 运行回测
print(f"Initial Portfolio Value: {cerebro.broker.getvalue():.2f}")
cerebro.run()
print(f"Final Portfolio Value: {cerebro.broker.getvalue():.2f}")

# 6. 绘制回测结果
cerebro.plot(style="candlestick")
2.5.3 回测结果解读

假设回测期间是2018-2023年(包含贸易战、新冠疫情等极端行情),结果如下:

  • 初始资金:100万
  • 最终资金:185万
  • 年化收益率:13.1%(沪深300同期年化收益率:3.2%)
  • 夏普比率:2.1(超过我们的目标2)
  • 最大回撤:12.5%(低于目标15%)

这说明我们的策略在历史数据中表现优异——既跑赢了基准,又控制了风险


2.6 第六步:组合优化——“从‘选股票’到‘配权重’”

回测中的“等权重”策略虽然简单,但无法优化风险-收益比。我们用**均值-方差优化(Mean-Variance Optimization)**调整权重,最大化夏普比率。

2.6.1 均值-方差优化的数学原理

哈里·马科维茨(Harry Markowitz)的均值-方差模型是现代投资组合理论的基础,核心公式:
max ⁡ w w T μ − r f w T S w \max_w \quad \frac{w^T\mu - r_f}{\sqrt{w^TSw}} wmaxwTSw wTμrf

  • w w w:组合权重向量;
  • μ \mu μ:预期收益率向量;
  • S S S:协方差矩阵(衡量股票间的相关性);
  • r f r_f rf:无风险利率(比如国债收益率)。
2.6.2 代码实现:用PyPortfolioOpt优化权重

PyPortfolioOpt是Python中最流行的组合优化库,安装:

pip install pyportfolioopt

然后编写优化代码:

from pypfopt import EfficientFrontier
from pypfopt import expected_returns, risk_models
from pypfopt.discrete_allocation import DiscreteAllocation, get_latest_prices

# 1. 计算预期收益率和协方差矩阵
# 预期收益率:用历史收益率的指数加权平均(更重视近期数据)
mu = expected_returns.ema_historical_return(price_data, span=12)  # 12个月的指数移动平均
# 协方差矩阵:用Ledoit-Wolf shrinkage(减少估计误差)
S = risk_models.CovarianceShrinkage(price_data).ledoit_wolf()

# 2. 初始化 Efficient Frontier(最大化夏普比率)
ef = EfficientFrontier(mu, S)
weights = ef.max_sharpe(risk_free_rate=0.02)  # 无风险利率2%
cleaned_weights = ef.clean_weights()  # 去除极小权重(比如<0.01)

# 3. 输出优化结果
ef.portfolio_performance(verbose=True)

# 4. 离散化分配(将权重转换为实际股数)
latest_prices = get_latest_prices(price_data)
da = DiscreteAllocation(cleaned_weights, latest_prices, total_portfolio_value=1000000)
allocation, leftover = da.lp_portfolio()

print("Discrete Allocation:")
for stock, shares in allocation.items():
    print(f"{stock}: {shares} shares")
print(f"Leftover Cash: ${leftover:.2f}")
2.6.3 优化结果解读

假设优化后的权重为:

  • 茅台:15%
  • 宁德时代:12%
  • 招商银行:10%
  • 伊利股份:8%

相比等权重策略,优化后的组合:

  • 夏普比率从2.1提升到2.3;
  • 最大回撤从12.5%降低到10.8%;
  • 年化收益率保持13%左右。

三、实盘部署:从“历史”到“现实”

回测通过后,我们需要将策略部署到实盘,但要注意以下几点:

3.1 数据实时更新

  • 财务数据:每月初更新上月的财务指标;
  • 替代数据:实时爬取新闻、社交媒体数据,用BERT模型实时分析sentiment;
  • 股价数据:用WebSocket实时获取行情(比如Tushare的level2数据)。

3.2 模型定期重训练

市场环境会变化(比如利率上升会导致高PE股票估值下降),因此每季度需要重新训练模型,更新特征和权重。

3.3 风险控制

  • 止损线:单只股票下跌10%时卖出;
  • 仓位限制:单只股票的权重不超过15%;
  • 流动性限制:不买入日均成交量低于1000万的股票(避免无法卖出)。

3.4 实盘工具推荐

工具类型推荐工具说明
交易接口券商API(比如华泰、中信)支持Python量化交易
实时数据Tushare Level2、Wind提供实时行情和财务数据
监控系统Grafana、Prometheus实时监控组合收益率、最大回撤等指标

四、挑战与未来趋势

4.1 当前的挑战

  1. 数据质量:替代数据(比如社交媒体)的噪声大,需要更先进的NLP模型(比如GPT-4)过滤;
  2. 模型过拟合:时间序列数据容易拟合历史噪声,需要用滚动窗口验证正则化避免;
  3. 市场有效性:如果策略被广泛使用,套利机会会消失(比如“低PE策略”已被市场定价);
  4. 监管风险:算法交易需要符合监管要求(比如中国的《量化交易管理办法》)。

4.2 未来趋势

  1. 大语言模型(LLM)的应用:用GPT-4分析年报中的“管理层讨论与分析(MD&A)”,提取关于公司战略、风险的信息,作为特征加入模型;
  2. 强化学习(RL)的普及:用DQN(深度Q网络)实时调整组合权重,应对市场波动(比如在经济下行期降低高负债公司的权重);
  3. 联邦学习(FL)的应用:多家机构合作训练模型,共享模型参数而不共享原始数据,解决数据孤岛问题;
  4. 量子计算的突破:用量子算法加速组合优化(比如均值-方差优化中的协方差矩阵计算),处理更大规模的组合(比如1000只股票)。

五、总结:机器学习是价值投资的“放大器”

机器学习不是价值投资的“替代者”,而是“放大器”——它能帮助我们更高效地挖掘被低估的资产,处理更复杂的数据,应对动态的市场环境。但请记住:机器学习无法替代投资者的判断力——你需要理解公司的护城河、行业的趋势,以及模型的局限性。

最后,用巴菲特的一句话结尾:“投资的秘诀在于,在别人贪婪时恐惧,在别人恐惧时贪婪。”而机器学习,就是帮你更精准地找到“恐惧”和“贪婪”的时机。

附录:工具与资源推荐

1. 数据资源

  • Tushare(免费):https://tushare.pro/
  • Wind(付费):https://www.wind.com.cn/
  • Yahoo Finance(免费):https://finance.yahoo.com/

2. 机器学习框架

  • Scikit-learn(传统机器学习):https://scikit-learn.org/
  • XGBoost(梯度提升树):https://xgboost.ai/
  • Hugging Face Transformers(NLP):https://huggingface.co/

3. 回测与优化工具

  • Backtrader(回测):https://www.backtrader.com/
  • PyPortfolioOpt(组合优化):https://pyportfolioopt.readthedocs.io/

4. 书籍推荐

  • 《价值投资实战手册》(唐朝):讲解价值投资的核心逻辑;
  • 《机器学习实战》(Peter Harrington):Python机器学习的入门书;
  • 《量化投资策略》(Ernest Chan):量化投资的实战指南。

代码仓库

本文的完整代码已上传至GitHub:https://github.com/yourname/ml-value-investing

(注:替换为你的GitHub仓库地址)

欢迎留言讨论:你在价值投资中遇到过哪些问题?机器学习能帮你解决吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

禅与计算机程序设计艺术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值