KNN股市预测源码全解析:从特征工程到回测避坑指南

发布时间:2026/10/1 10:34:34
KNN股市预测源码全解析:从特征工程到回测避坑指南 简介利用k近邻算法实现股市预测的Python源代码包面向已有基础Python语法、正接触机器学习的开发者和量化分析爱好者通过历史行情数据进行走势预测直观展示kNN分类与回归思路在金融场景中的应用。压缩包共2个文件含一个.py核心脚本和一份.md说明文档整体大小仅2KB结构清晰、便于快速阅读。代码基于pandas、tushare、numpy、scipy、fastdtw等库完成股票数据获取、时间序列对齐及距离度量用户只需在交互式命令行调用main并传入股票代码与k值即可获得预测结果若将ktype设为‘W’还能切换到周线维度进行长周期分析。配套说明文档重点介绍了库的配置、脚本运行方式并反复提示k值的改变会直接影响准确率与估计结果建议多次试验以找到最优参数同时注意数据归一化和异常值处理帮助减少偏差。已有121人学习源码与文档组合适合在真实数据上边改边测既能体会数据预处理到模型评估的完整流程也能为后续更复杂的股市预测研究提供参考。1. 用KNN做股市预测为什么一个“不学习”的算法值得你先跑一遍如果你刚拿到一份“Python基于KNN算法实现的股市预测源代码”第一反应多半是怀疑KNN既没有梯度下降也没有权重更新甚至连训练过程都谈不上把一个不学习的算法用在股市预测上靠谱吗实际上KNN在量化入门场景里是最适合先跑通的原型算法之一——它把历史上所有K线形态直接当作“记忆库”新行情出现时检索最相似的若干个历史片段看看它们之后怎么走。你不需要GPU不需要深度学习方法那样的大样本一个普通笔记本配合Python环境就能完成从数据拉取到回测的全流程。这篇文章会顺着这套源代码最常见的落地路径把数据怎么取、特征怎么造、参数怎么调、回测怎么做、哪些地方必然翻车讲清楚适合想用手头源码验证技术指标有效性、又不想一上来就碰深度学习的量化入门者。2. 先想清楚再写代码KNN为什么能用于股市预测边界在哪里2.1 KNN的决策机制靠“查历史相似片段”而不是学函数KNNK-Nearest NeighborsK近邻算法本质上是非参数方法它不拟合任何函数而是把全部训练样本保存下来等到预测时再去“翻旧账”。对于每一个待预测样本它计算该样本与所有历史样本在特征空间中的距离选出距离最近的K个邻居然后用这K个邻居的标签进行投票或者取均值。这套机制放在股市预测里对应的直觉是如果今天这支股票的涨跌幅、均线关系、成交量特征和历史上某几个交易日非常相似那么这几个交易日之后几天的走势大概率能给我们一些参考。这个直觉并非毫无根据。技术分析的核心假设之一就是“历史会重演”而KNN是把这个假设执行得最彻底的算法——它不做任何泛化直接拿相似的历史片段说事。和线性回归相比KNN不需要假设涨跌与特征之间存在线性关系实际行情中同样的均线形态在不同市场环境下可能指向完全相反的后续走势这种非线性关系正是KNN的用武之地。和决策树、随机森林相比KNN也没有特征重要性排序的概念它保留了所有特征的综合距离信息因此对特征工程质量要求更高但好处是模式更接近“整体形态匹配”而不是单看某几个指标。2.2 为什么日线行情对KNN相对友好局部平稳性KNN有效的前提是相似的特征向量在统计上大概率导向相似的标签。这个条件在股市日线数据上并不是天然成立的它依赖一个隐含假设——局部平稳性。所谓的局部平稳指的是在样本覆盖的时间范围内市场的“游戏规则”没有发生剧烈变化相似的K线形态之后仍然会走出相似的行情。日线级别为什么勉强满足这个条件因为K线形态本身已经浓缩了很多信息。一段缩量横盘后的放量突破无论发生在哪一年后续几日的短线动量效应通常都存在一段连续暴涨后的高位滞涨短线回调的概率也大概率偏高。这些都是短期统计规律它们不依赖宏观基本面判断因此KNN在1到5天的预测周期上比在长周期上表现更稳定。但你必须清楚它的边界一旦市场进入系统性风格切换——比如从趋势行情转为长期阴跌或者出现流动性冲击——历史上那些相似形态的“参考答案”就失效了。KNN没有外推能力它只能回答“历史上像这样的时候后来怎么样了”回答不了“这次不一样怎么办”。2.3 与主流模型对比什么时候该选KNN以及最小可行配置如果你正在线性回归、决策树和KNN之间做选型可以按下面的思路来判断。线性回归适合特征与预测目标关系相对稳定的场景但股市里这种稳定性很少。决策树和随机森林对噪声有更强的容忍度但需要较多的调参工作且树模型的预测结果不容易解释“为什么是这几个邻居影响了判断”。KNN的优势是三条实现门槛最低预测结果可解释直接把最近的邻居日期打印出来看以及在小样本上不容易出现过拟合——因为它根本没有训练参数。最小可行配置建议如下表这也是我读这份源代码时建议你心里先有的默认值配置项建议值说明预测目标未来3日累计涨跌幅是否超过3%预测“明天涨不涨”噪声太大拉长周期更符合KNN模式匹配的习惯数据频率日线分钟线噪声更大且数据量对KNN的检索开销不友好特征数量58个过少区分度不够过多会引入无关维度稀释距离历史样本量15002500个交易日约610年日线兼顾行情风格覆盖与计算效率K值815日线噪声大K太小容易被单日异常行情带偏评估指标预测准确率 单笔盈亏比 累计收益曲线只看准确率会被类不平衡骗到后面第5章会展开这个配置的核心是把问题从“预测明天的价格”降维成“识别历史上相似的行情片段”。想清楚这一点你就知道后面所有代码都是围绕“构造特征向量、计算距离、找邻居、投票”四步展开的。3. 数据获取与特征工程把K线变成KNN能吃的特征向量3.1 用akshare拉取日K数据前复权、样本量、列名对齐KNN股市预测源代码的第一步基本都是获取历史行情数据。常见做法是用akshare或者yfinance拉取日K线考虑到国内A股数据的可获取性我一般用akshare。下面是最小可用的数据拉取脚本# fetch_data.py import akshare as ak import pandas as pd # 拉取浦发银行sh600000的日K线qfq表示前复权 df ak.stock_zh_a_daily(symbolsh600000, adjustqfq) # akshare返回的列名是英文统一重命名并只保留需要的字段 df df.rename(columns{ date: date, open: open, high: high, low: low, close: close, volume: volume }) df df[[date, open, high, low, close, volume]] # 截取最近2000个交易日足够覆盖8年左右的行情 df df.tail(2000).reset_index(dropTrue) df.to_csv(data.csv, indexFalse) print(f共获取 {len(df)} 条日线数据区间 {df[date].iloc[0]} 至 {df[date].iloc[-1]})这段代码里有两个参数需要重点说明。第一个是adjustqfq前复权的作用是消除分红送股造成的价格跳空。如果不复权除权日当天K线会出现一个向下的“坑”KNN会把这种非交易行为造成的价格断裂误认为是行情异动找出来的邻居就会失真。第二个是tail(2000)样本量不建议贪多——拉十年以上的数据虽然可行但时间跨度拉的过长早期行情的交易规则和参与者结构都和现在差别很大反而污染相似度计算。3.2 构造特征工程把均线差、RSI、量比与波动率做成向量KNN对特征工程的要求比树模型更高因为距离计算是“全维度综合评估”一个无关特征就会把距离拉偏。所以特征要精心挑方向上只选那些技术分析里被反复验证过的量价指标。下面是特征构建代码# features.py import pandas as pd import numpy as np df pd.read_csv(data.csv, parse_dates[date]) # 今日收益率相邻两日收盘价的变化率 df[ret] df[close].pct_change() # 均线偏离度短期均线相对长期均线的位置量化“多头/空头排列”的强度 df[ma5] df[close].rolling(5).mean() df[ma20] df[close].rolling(20).mean() df[ma_gap] df[ma5] / df[ma20] - 1 # RSI(14)衡量近期涨跌动能的强弱KNN需要一个“动量感”特征 delta df[close].diff() gain delta.clip(lower0).rolling(14).mean() loss (-delta.clip(upper0)).rolling(14).mean() rs gain / loss df[rsi14] 100 - 100 / (1 rs) # 量比当日成交量与最近5日均量的比值捕捉放量或缩量 df[volume_ratio] df[volume] / df[volume].rolling(5).mean() # 波动率最近10日收益率的标准差衡量当前行情处于平静期还是剧烈期 df[volatility] df[ret].rolling(10).std() # ATR平均真实波幅用来刻画单日价格波动幅度 tr pd.concat([ df[high] - df[low], (df[high] - df[close].shift()).abs(), (df[low] - df[close].shift()).abs() ], axis1).max(axis1) df[atr] tr.rolling(14).mean() # 丢弃前20行因为均线、RSI等指标需要足够的历史窗口才能计算 df df.dropna().reset_index(dropTrue) feature_cols [ret, ma_gap, rsi14, volume_ratio, volatility, atr] print(df[feature_cols].describe())为什么选这6个特征ret表示最近一天的状态ma_gap表达趋势位置rsi14给出超买超卖信息volume_ratio反映资金参与度volatility和atr则刻画波动环境。这六者组合起来基本覆盖了“位置、动量、量能、波动”四个维度没有明显冗余也不会过度稀释距离。特征之间相关性低这一点很重要——如果atr和volatility几乎完全线性相关就相当于给波动率加了两倍权重。3.3 标签与数据切分预测的是“未来3日累计涨跌”不是明天接下来是标签的构造这一步最容易埋雷。这里选择将未来3日累计涨幅超过3%视为正样本也就是1否则为0# label.py # 标签未来3日累计收益率是否大于3% df[future_ret] df[close].pct_change(3).shift(-3) df[label] (df[future_ret] 0.03).astype(int) # 删除最后3行它们没有完整的未来3日数据标签是残缺的 df df.dropna(subset[future_ret]).reset_index(dropTrue) X df[feature_cols] y df[label] print(f正样本未来3日涨超3%占比: {y.mean():.2%}) print(f总共 {len(df)} 个有效交易日特征维度 {X.shape[1]})标签构造里的shift(-3)是关键逻辑。pct_change(3)计算的是当日相对3天前的涨跌幅shift(-3)把结果向上平移3行让每一行对应的标签变成“从当天开始往后3天的收益率”。这样训练时模型看到的是第t天的特征标签是第t到t3天的实际结果时序上完全合理。需要注意dropna(subset[future_ret])必须执行否则最后三行的标签是不完整数据会让回测虚高。正样本占比如果太低比如低于15%说明3%的阈值在当前股票上定高了可以适当降到2%。4. 训练、预测与回测把你的KNN股市预测源码包跑通4.1 KNN模型在scikit-learn里的三个必调参数在scikit-learn中KNeighborsClassifier的构造参数不多真正影响股市预测效果的主要是n_neighbors、weights和p。先看代码# train_knn.py from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import StandardScaler from sklearn.model_selection import TimeSeriesSplit from sklearn.metrics import accuracy_score, classification_report import numpy as np # 数据切分前70%训练后30%测试按时间顺序切分 train_size int(len(X) * 0.7) X_train, X_test X.iloc[:train_size], X.iloc[train_size:] y_train, y_test y.iloc[:train_size], y.iloc[train_size:] # 标准化一定要先在训练集上fit再transform训练集和测试集 scaler StandardScaler().fit(X_train) X_train_scaled scaler.transform(X_train) X_test_scaled scaler.transform(X_test) # KNN模型K10距离加权曼哈顿距离 model KNeighborsClassifier( n_neighbors10, weightsdistance, p1, metricminkowski ) model.fit(X_train_scaled, y_train) y_pred model.predict(X_test_scaled) y_prob model.predict_proba(X_test_scaled)[:, 1] print(f测试集准确率: {accuracy_score(y_test, y_pred):.2%}) print(classification_report(y_test, y_pred, target_names[不涨, 涨]))三个参数各自有讲究。n_neighbors10取的是经验中值日线上小于5会让模型被单日噪音支配大于20又会把几年前风格完全不同的行情拉进来参与投票8到15是一个经得起交叉验证的区间。weightsdistance意味着距离更近的邻居对投票的贡献更大“历史上越像今天的行情参考价值越高”这个逻辑比均匀投票更贴合直觉。p1对应曼哈顿距离它在高维特征空间中比欧氏距离对异常值更稳健——股市数据里经常出现单日极端波动曼哈顿距离不会因为某一个维度偏离过远而完全主导整体距离。4.2 预测结果的可读输出概率、方向与准确率分类器的输出除了方向之外predict_proba给出的概率信息更值得关注。上面的代码已经把概率保存到y_prob。这个概率的价值在于它本身就是“历史相似片段的上涨比例”可以直接作为信号强度使用。比如y_prob等于0.62相当于在距离最近的10个历史交易日里有6到7个在随后3天涨超3%。我建议把预测结果合并回行情数据方便肉眼查验模型到底在什么行情下会给出什么判断# inspect_prediction.py result df.iloc[train_size:].copy() result[pred_label] y_pred result[prob_up] y_prob # 打印最近几条预测尤其关注预测上涨的样本 print(result[[date, close, ma_gap, volume_ratio, prob_up, pred_label, label]].tail(10)) # 统计一下预测概率高于0.6的样本里实际涨的比例有多高 high_confidence result[result[prob_up] 0.6] print(f高置信区间样本数: {len(high_confidence)}, 实际上涨占比: {high_confidence[label].mean():.2%})这段代码不是必需的训练步骤但我强烈建议每次调参后都跑一遍。KNN算法的特点是“黑匣子程度低”你可以把预测上涨的样本对应的邻居日期打印出来直接查看那些历史相似日子的K线形态。如果发现高置信预测中实际涨的比例并没有明显提升说明特征集里还缺关键信息或者标签阈值设置不合理。4.3 简易回测记录“信号—持仓—权益曲线”有了预测方向还需要一个能评估“按这个策略交易到底赚不赚钱”的回测框架。下面的回测做了适当简化——忽略手续费和滑点目的是先验证模型本身有没有统计优势# backtest.py import numpy as np import pandas as pd # 约定预测label1时次日开盘买入持有3天后卖出 # 信号在第t天收盘后产生第t1天执行 signals pd.Series(indexresult.index, data0) signals[result[prob_up] 0.5] 1 # 默认阈值为0.5后面会调 equity 1.0 position 0 entry_price 0 hold_days 0 records [] for i in range(len(result) - 3): date result[date].iloc[i] close_price result[close].iloc[i] next_open result[open].iloc[i 1] if signals.iloc[i] 1 and position 0: # 买入使用第二天开盘价 position 1 entry_price next_open hold_days 0 if position 1: hold_days 1 if hold_days 3: # 卖出使用当天收盘价 exit_price close_price ret exit_price / entry_price - 1 equity * (1 ret) records.append({date: date, ret: ret, entry: entry_price, exit: exit_price}) position 0 hold_days 0 # 计算累计收益率和最大回撤 total_ret equity - 1 print(f累计收益率: {total_ret:.2%}) # 最大回撤权益曲线的峰值到谷值最大跌幅 equity_curve [1.0] cur 1.0 for r in records: cur * (1 r[ret]) equity_curve.append(cur) peak np.maximum.accumulate(equity_curve) drawdown equity_curve / peak - 1 print(f最大回撤: {drawdown.min():.2%}) # 交易胜率与盈亏比 rets [r[ret] for r in records] win_rate sum(1 for r in rets if r 0) / len(rets) avg_win np.mean([r for r in rets if r 0]) if any(r 0 for r in rets) else 0 avg_loss np.mean([r for r in rets if r 0]) if any(r 0 for r in rets) else 0 print(f交易次数: {len(rets)}, 胜率: {win_rate:.2%}, 平均盈利: {avg_win:.2%}, 平均亏损: {avg_loss:.2%}) print(f盈亏比: {abs(avg_win / avg_loss):.2f})回测逻辑里有一个多数新手会忽视的细节信号在第t天收盘后产生但买入要等到第t1天开盘。这是因为收盘价数据在收盘那一刻才能确认如果你用当天的收盘价买入就是用了未来数据。上面的代码用next_open作为入场价严格规避了这一点。回测结果里最重要的不是累计收益率而是胜率和盈亏比的组合。如果胜率低于50%但盈亏比大于1.5策略仍然可能是正期望的反之如果胜率70%但赚小钱亏大钱策略大概率是负期望。4.4 使用说明文档里必须写清的三个设置项既然标题里带了“使用说明”这里补充一下这类源码包落地时需要注意的三个配置项。第一是数据源的可替换性——代码里硬编码的股票代码和akshare接口属于示例实际使用时应保证data.csv的列名与你本地数据一致否则特征工程会直接报错。第二是标签阈值的可配置化——3%和3日窗口是示例值换股票换周期时这两个参数往往需要重新验证。第三是预测结果的输出方式——无论源码里是直接打印还是写文件你拿到预测结果后都要先人工核对几条对照K线图看模型预测上涨时的历史形态是否真的相似。核对通过后再进入回测可以避免后续调参变成对噪声的过度拟合。5. 避坑KNN在股市预测里最容易翻车的五个点5.1 未来函数回测90%实盘翻车现象回测结果漂亮得惊人准确率接近90%累计收益曲线一路向上但拿到模拟盘上就变脸连续亏损。原因典型的未来函数污染。常见写法是构造特征时用了shift(-1)——比如把“当天成交量相对明天成交量的变化”算进去或者标签与特征之间发生了错位模型在训练时“偷看”了未来信息。KNN这种记忆型模型对数据泄漏尤其敏感因为它会直接把未来的相似片段当作邻居检索到。解决把特征和标签的生成逻辑分开审查。每个特征只允许使用当日及之前的数据rolling窗口向右不能跨过当天。标签统一用shift(-n)前移删除末尾没有完整未来数据的所有行。你可以用一句口诀自查第t行特征里出现任何带t1信息的字段就是未来函数。5.2 特征量纲不统一距离被成交量绑架现象不管怎么调K值预测结果几乎不变并且模型的判断依据主要落在成交量这一个字段上。把成交量特征去掉之后准确率反而提升了。原因KNN的距离计算是逐维度累加的。成交量数值动辄几十万手收益率只有0.01级别欧氏距离计算时成交量一个维度的差值就能盖过其他五个维度之和。如果没有做标准化等于是让模型只按成交量一个维度找邻居。解决先标准化再进模型而且要严格遵守“训练集上fit测试集上transform”的流程。如果你用了StandardScaler().fit_transform(X)一次性处理好整个数据集测试集的均值和方差就被训练过程看到了回测结果依然会偏乐观。5.3 类别不平衡永远预测“不涨”也能拿到70%准确率现象准确率有70%以上看详细报告却发现预测的“涨”类样本F1值低得可怜模型基本把所有样本都判成了“不涨”。原因正样本占比常常只有20%30%如果阈值默认0.5模型只需要把一切预测为负类就能获得70%以上的准确率。准确率这个指标在类别不平衡的数据集上严重失真。解决换评估指标重点关注正样本的召回率和精确率。操作层面有两个常用手段一是把预测阈值从0.5提高到0.6或0.65只交易高置信信号牺牲交易频率换取胜率二是调整标签阈值把正样本定义从“涨超3%”改成“涨超2%”让正样本占比回升到30%以上。需要提醒的是KNeighborsClassifier没有class_weight参数不要在这上面浪费时间直接调阈值最有效。5.4 K值选太小把单日噪声当成了规律现象K从3调到5再到10预测结果每次都大变样回测累计收益也随之剧烈波动。翻看预测上涨的样本对应的邻居日期里混着几根异常长阴线。原因K过小时模型被少数极端交易日的特征完全主导。股市日线数据里噪声占比很高一根因突发利空砸出的长阴线其特征向量和正常行情差异巨大K3时只要距离最近的三天里有这么一根它就直接改变了投票结果。解决K的下限建议不低于8。确定K值时不看测试集表现而是用TimeSeriesSplit在训练集内部交叉验证画一条K从3到30的准确率曲线取曲线平稳段的中值。K值不是越大越好过大会把行情风格完全不同时期的数据也拉进来但宁可稍大也不能让两根异常K线主导投票。5.5 风格切换期失灵KNN没有外推能力现象模型在2015年和2020年这种趋势行情里表现不错但在2018年单边下跌或者2022年震荡阴跌期间预测准确率掉到50%以下回撤明显放大。原因KNN属于“记忆型”模型它只能回答历史上相似部分怎么走。当市场进入历史中没有对应模式的阶段——比如流动性收缩期的普跌行情——历史相似片段的参考价值急剧下降。这不是参数问题是算法边界。解决在预测层做行情过滤只在指数20日均线之上时才允许开仓或者加入“市场状态”作为特征维度。更简单的做法是缩短持仓周期把预测目标从“3日涨跌”改成“1日涨跌”并降低收益阈值让模型在更短的统计窗口内寻找规律。接受KNN不是万能的——它适合抓取熟悉的短线形态不适合做牛熊转折的判断。6. 把KNN预测做稳的最后一步滚动窗口与信号过滤6.1 用滚动窗口代替一次性切分接近真实交易节奏一次性按70%切分训练集和测试集虽然简单但它有一个问题模型只用2000行历史里的前1400行做记忆库后600行的每个预测样本都依赖一段“固定不变”的记忆。真实交易里你的知识库应该随新数据不断滚动更新。这里推荐用手动滚动训练代替TimeSeriesSplit——它更适合评估策略稳定性但实际交易时你需要每产生一个新交易日的数据就重新训练一次。滚动窗口的核心代码量不大每次用最近500个交易日的特征向量作为记忆库预测下一天的涨跌概率然后窗口整体后移一天。如下所示# rolling_knn.py def rolling_predict(X_scaled, y, start_idx, lookback500): 滚动预测每个交易日只使用最近lookback条历史数据作为记忆库。 返回预测概率序列和实际标签序列。 preds [] for t in range(start_idx, len(X_scaled)): # 记忆库t之前的lookback条样本 X_train X_scaled[t - lookback:t] y_train y.iloc[t - lookback:t] X_test X_scaled[t:t1] model KNeighborsClassifier(n_neighbors10, weightsdistance, p1) model.fit(X_train, y_train) prob model.predict_proba(X_test)[0, 1] preds.append(prob) return np.array(preds)lookback500大约覆盖两年交易日这个长度既保证记忆库里有足够丰富的行情形态又不会让五年前的陈旧模式干扰当前判断。滚动训练的计算开销比一次性训练大不少但对于日线级别的股票数量来说单机运行完全在可接受范围内。你会注意到滚动窗口下的准确率通常比一次性切分略低——这是正常的说明之前的结果里确实有一部分是模型“记住了测试期附近样本”带来的虚高。6.2 用预测概率做信号过滤只做高置信交易KNN模型的输出概率天然适合作为仓位控制的依据。当10个邻居里有7个都在后续3天上涨预测概率0.7这时出手的胜率直觉上应该高于概率0.52的情况。把predict_proba的置信度直接当信号强度使用是这类源码最值得改的一处逻辑。# filter_signal.py prob_up result[prob_up] # 只在预测概率高于0.6时开仓其余持币观望 signal (prob_up 0.6).astype(int) # 比较不同阈值下的交易次数与胜率 for th in [0.5, 0.55, 0.6, 0.65, 0.7]: s (prob_up th).astype(int) trades s.sum() if trades 0: continue # 统计这些信号对应位置的实际上涨占比 win_rate result.loc[s 1, label].mean() print(f阈值{th}: 信号数{trades}, 实际上涨占比{win_rate:.2%})从0.5开始逐步提高阈值你会发现一个规律交易次数下降但信号质量上升。阈值定在多少合适取决于你对资金使用效率的容忍度。我的习惯是选择“信号数不低于全年30个”的最低阈值——太激进容易过度拟合太保守则一年都开不了几次仓。注意这个阈值选择过程本身也是一种过拟合来源所以选定之后就不要频繁改动让它在新的样本上接受检验。6.3 与MACD、均线做信号投票一个低成本的风控增强如果你希望进一步提升稳健性可以把KNN信号和技术指标做一个最简单的投票融合。这里不需要复杂的模型堆叠只需要一个布尔表决当KNN给出上涨信号、MACD柱线为正、收盘价在20日均线之上三个条件同时满足时才买入。如果KNN的预测概率已经降到0.6附近而MACD和均线方向相反这一笔交易就不做。# vote_signal.py df[macd_positive] (df[close].ewm(span12).mean() - df[close].ewm(span26).mean()) 0 df[above_ma20] df[close] df[ma20] result[knn_signal] (result[prob_up] 0.6).astype(int) result[macd_signal] df.loc[result.index, macd_positive].astype(int) result[ma_signal] df.loc[result.index, above_ma20].astype(int) # 三个信号相加等于3时才开仓 result[final_signal] (result[knn_signal] result[macd_signal] result[ma_signal] 3).astype(int)这个做法的本质是给KNN加了一层趋势过滤。KNN擅长识别局部形态但对整体市场状态缺乏感知均线和MACD恰好能补足这一点。融合后的信号数量会明显减少但单笔交易的期望收益通常更稳定。整套流程跑完你已经把最初那份源码从“能跑”进化成了“能评估、能调参、能控制风险”的完整量化原型。我自己在跑这类项目时养成的习惯是固定一组参数跑够三个月记录每一次改动和对应的回测差异再决定要不要调整。这样做的理由是KNN的预测结果对参数敏感如果你边看回测边调参最后调出来的往往不是规律而是对历史行情的精确记忆。希望这套从数据到回测再到融合过滤的路径能帮你在KNN股市预测这个方向上少走一段弯路。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询