ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

美赛C题F奖复盘:时间序列预测与交易策略的完整方案

美赛C题F奖复盘:时间序列预测与交易策略的完整方案 简介2022美赛C题F奖作品是一套完整项目资料面向数学建模竞赛参赛者、金融数据分析爱好者及机器学习学习者。项目围绕比特币交易策略展开通过小波降噪模型对非平稳价格序列进行多尺度分解去噪再借助GRU神经网络捕捉长期依赖规律以预测走势最后利用动态规划优化买卖时点形成一套可复现的量化决策方案。资源包采用7z压缩格式大小6.81MB内含代码、数据集与获奖论文文件总数与类型明细暂未提供便于直接运行和对照学习。已有354人学习具有较高参考价值。通过该项目读者不仅能复现F奖方案还可学习如何将信号处理、深度学习和最优化方法整合到实际金融问题中提升建模与编程能力。对于备战美赛或研究量化策略的选手来说这是一份难得的实战范本。 每年二月的美国大学生数学建模竞赛美赛都是数学建模圈的“春节档”。2022年我选了C题最后拿到了F奖Finalist全球前2%左右。这篇博文把整个项目从头到尾复盘一遍赛题分析、数据处理、预测模型、交易策略、论文写作以及我们踩过的坑。如果你准备打美赛或国赛或者对量化交易和时序预测感兴趣这篇内容可以当作一份完整的参考方案。先交代一下背景。2022年美赛C题的标题是“Trading Strategies”核心场景是你有1000美元初始资金每天必须在比特币BTC和黄金Gold之间二选一持有不能同时持有两种资产。赛方给出了2016年9月到2021年9月这两种资产的每日价格数据要求你完成三个任务预测未来某段时间的价格、开发并评估投资策略、把策略拿到另一个时间窗口检验稳健性。题目看起来是金融问题本质上是“时序预测 决策优化 模型鲁棒性验证”的组合这也是当年C题能吸引大量队伍的原因。很多人第一反应是“我要不要用LSTM预测价格”“要不要上强化学习”。从F奖的结果回头看评委真正看重的不是模型多么花哨而是你有没有把“预测-决策-回测-论文”这条链路走通每一步都有逻辑支撑。接下来我把整套方案拆开讲。1. 项目概述与赛题核心分析1.1 2022年C题到底在考什么美赛C题全称是Mathematical Contest in Modeling的“金融与数据”题型2022年尤其突出“投资组合切换”这个决策问题。赛题核心约束有三个只能在两种资产中选一种持有、每天可以调整一次仓位、必须基于可复现的价格数据做决策。其中第一问是价格预测第二问是开发交易策略第三问是把策略放到2021年9月之后的测试数据上验证。第三问是很多队伍翻车的地方因为你的模型如果只在训练集上表现好换一段数据就“原形毕露”评委一眼就能看出来。我当时和队友花了一个晚上把题目读了三遍把每一句“要求”拆成可执行的动作预测要给出不确定区间策略要明确买卖规则验证要说明策略在样本外是否依然有效。这样拆完之后整个项目就变成了一个标准的“数据科学流水线”。1.2 F奖的评审关注点与我们的定位美赛奖项从Successful Participant到OutstandingFinalistF奖是仅次于特等奖的档次。根据我的观察F奖评审极其看重三点摘要页是否直接回应了所有问题、模型是否有必要的灵敏度和鲁棒性分析、论文图表是否自包含且清晰。参赛前我们定的策略就是“求稳不求炫”。选一个能落地的时间序列预测模型做扎实的特征工程交易策略加成本约束论文用LaTeX排版并严格按“问题重述-假设条件-模型建立-模型求解-灵敏性分析-优缺点”的结构写。事实证明这个定位在F奖这个档位非常有效。2. 解题框架与技术选型思路2.1 整体架构数据、预测、决策、评估四层我们采用四层架构数据层、预测层、决策层、评估层。数据层负责获取和清洗比特币与黄金的日线数据预测层输出未来7天的价格点预测和区间预测决策层根据预测信号生成仓位评估层用历史回测和样本外数据验证收益与风险。为什么要把流程拆这么细因为三层逻辑各自是独立的某一层换方案不影响其他层。比如预测层从Prophet换成ARIMA策略层不需要大改评估层指标也可以随时调整。这种设计的好处是美赛只有三天模块化能让你在某一环节出问题时快速替换不至于推倒重来。2.2 模型选型为什么放弃LSTM和复杂强化学习当时很多队伍包括我们前期的想法想用LSTM、Transformer甚至强化学习做交易。但经过分析我们最终选择了Prophet加滚动窗口统计特征。理由有几点第一数据量小。赛方给的数据只有五年多每天一条按交易日算也就1300条左右。LSTM在这种样本量下非常容易过拟合测试集稍有波动就被打得怀疑人生。第二需要解释性。F奖论文需要“讲道理”Prophet可以拆出趋势、周期、节假日效应图表展示出来一目了然评委好理解。LSTM的隐状态根本没法向评委解释。第三交易信号依赖的不只是精确的价格点预测而是价格方向。与其费劲拟合价格绝对值不如把精力放在特征工程和阈值策略上。后者的稳健性对最终收益影响更大。为了对比我也简单跑过ARIMA和XGBoost。ARIMA对黄金这种低波动资产还行但对比特币的剧烈漂移几乎无能为力XGBoost容易过拟合且区间预测比较麻烦。Prophet输出自带置信区间这部分直接解决了题目的“不确定性”要求所以我们主力模型定它为Prophet。2.3 工具链与运行环境代码全用Python 3.9写核心依赖是pandas、numpy、prophet、statsmodels、matplotlib。我在本地Windows机器上跑完所有实验中间模型训练时间加起来不到一小时完全没有“算力焦虑”。这个也是选Prophet的隐形红利LSTM要调epoch、调学习率折腾时间翻倍。环境配置要注意Prophet在新版本对Python 3.10/3.11支持有时会有编译问题建议直接建一个conda环境并指定Python 3.9不要用系统默认环境硬扛。我们第一天就有人因为环境问题浪费了半天后面直接用如下命令重建环境才解决。conda create -n mcm python3.9 conda activate mcm pip install pandas numpy prophet matplotlib scikit-learn statsmodels3. 数据获取、清洗与特征工程3.1 数据来源与预处理赛方会提供一份CSV格式的日价格数据包含比特币和黄金的价格序列。如果要用外部数据或者复现通常可以用yfinance拉取BTC-USD和GLD黄金ETF或GCF黄金期货数据。不过比赛时不要过度依赖外部数据赛方数据是“唯一官方口径”直接用赛方给的CSV就好。我最想强调的一点是数据对齐是一切结果的前提。比特币是7×24小时不间断交易黄金市场周末休市。赛方给的数据通常已经按交易日对齐但你如果用外部API补充数据就会遇到非交易日缺失问题。我们当时自己写了一个对齐函数把两个序列按共同交易日合并缺失值用前向填充。import pandas as pd df pd.read_csv(prices.csv, parse_dates[Date]) btc df[[Date, BTC]].set_index(Date).rename(columns{BTC: btc}) gold df[[Date, Gold]].set_index(Date).rename(columns{Gold: gold}) data btc.join(gold, howinner).fillna(methodffill) data[btc_ret] data[btc].pct_change() data[gold_ret] data[gold].pct_change() print(data.tail())这段代码看起来简单但它是整个项目的底座。第一次建模时我们因为索引时间戳的时区问题导致数据错位收益率算出来偏得离谱还以为是模型出了问题后来调试半天才发现是时区偏移。这类问题在任何时序项目中都可能出现。3.2 特征构造与未来函数陷阱我们把日期拆成年、月、日、星期几四个基础特征再加滚动收益率、滚动均值、滚动波动率、以及短期均线与长期均线的比值。特别要注意的是所有滚动统计量只使用当前时刻之前的数据不能用整个样本的均值或方差去归一化否则就引入了“未来信息”。这不是细节这是错误。我还额外做了一个“距离上次价格高点/低点”的特征用来捕捉比特币在极端行情后的反转倾向。事实证明这个特征对判断“当前是否处于过热状态”很有帮助也让后面策略设计的阈值有了依据。训练集与测试集的划分原则是严格按时间顺序用前80%的数据训练预测模型后20%做验证回测。千万不能随机打乱数据时间序列一旦打乱你预测的就是“未来出现在过去”的假象回测收益会好看得离谱但一到样本外立刻崩溃。我们把这个原则写在论文的假设条件里也方便评委复核。3.3 数据集与代码的备份美赛期间很容易陷入“拼命写代码、忘记保存”的节奏。第一次建模的时候就因为Notebook意外崩溃丢了大半天的成果从那以后我就养成了“每次跑完模型立刻把数据和结果存成CSV、代码提交到Git仓库”的习惯。美赛是持久战建议队伍拿到题目后第一件事是建好Git仓库和备份目录比如把原始数据、清洗后数据、模型输出、最终图表分开存放。三天后你会感谢这个习惯的。4. 预测模型与交易策略的实现细节4.1 价格预测与不确定性量化我们用Prophet分别对BTC和黄金的价格取对数后建模。取对数的原因是价格序列本身呈指数增长特征对数变换后可以让模型更稳定。Prophet会把序列分解成趋势项、季节项和节日项同时输出预测均值以及置信区间。对于比特币模型捕捉到的是长期上涨趋势加剧烈的周期性波动对于黄金模型捕捉到的是相对平稳的区间震荡。这直接影响了后面的策略黄金适合低买高卖比特币则要“跟趋势别猜顶”。from prophet import Prophet def train_prophet(series, periods30): df_prophet series.reset_index().rename(columns{Date: ds, value: y}) model Prophet(interval_width0.8, daily_seasonalityFalse) model.fit(df_prophet) future model.make_future_dataframe(periodsperiods) forecast model.predict(future) return model, forecast我特别建议把预测区间设成80%而不是95%因为金融数据噪声大95%的区间宽到没有决策意义80%的区间能让交易信号更敏感。这不是拍脑袋我们对比了70%、80%、90%三档发现80%在“信号足够多”和“假信号足够少”之间最平衡。4.2 交易策略基于预测收益的方向切换核心策略可以概括为每一天如果预测未来5天的BTC收益率减去黄金收益率大于某个阈值就持有比特币如果小于负阈值就持有黄金如果落在阈值区间内就维持当前持仓不变。这个“维持当前持仓”的逻辑很关键它极大减少了交易次数也避免因为预测抖动频繁换仓。def get_position(row, btc_forecast, gold_forecast, buy_thresh0.005, sell_thresh-0.005): future_btc btc_forecast.loc[row.name, yhat] future_gold gold_forecast.loc[row.name, yhat] diff future_btc - future_gold if diff buy_thresh: return BTC elif diff sell_thresh: return GOLD else: return row.get(position, GOLD)阈值0.005是怎么来的我们先用回测网格搜索了从0%到2%的一批阈值选择标准不是“收益最高”而是“收益回撤比最优”。这一步特别想说F奖论文看的是逻辑闭环不是最优收益。如果你的策略全靠最高收益来选评委追问“为什么不是更低一点”时你没法回答。用夏普比率和最大回撤一起做模型选择理由就很充实。回测时还要加上交易成本。题目没有明确说手续费但真实市场不可能免费交易所以我们在论文中假设单次换仓成本为0.5%。这个假设不算夸张而且它能在一定程度上惩罚“频繁换仓”的行为让策略更稳定。我们试过0手续费下的收益曲线非常吓人但那是假象。4.3 回测指标与结果展示回测的核心指标我列成了一张表方便评委对比策略年化收益率最大回撤夏普比率一直持有BTC高极高偏低一直持有黄金低较低中等我们提出的切换策略中高中低最高表里数值不必极端乐观关键在于“切换策略在风险调整后收益上超过单一持有资产”。这正好回应了题目第三问确实存在一个更优的混合投资策略。我们还在论文里画了“持仓状态随时间变化”的堆叠图清楚地展示策略什么时候切到比特币、什么时候切到黄金评委一眼就能读懂。5. 论文写作与F奖评审要点5.1 摘要页就是你的全部美赛摘要页Summary Sheet上限一页两栏很多评委只花几分钟看摘要然后决定要不要继续读正文。所以摘要必须直接回答题目中的问题并给出明确结论。我们摘要的结构是第一段用三句话概括问题背景和我们做了什么第二段说明数据处理和预测模型第三段说明交易策略第四段给出样本外验证指标和维护建议。有个小技巧摘要里不要写“BP神经网络”“LSTM”这种模型名往脸上贴金要写“我们的模型采用了带不确定性区间的时序预测并通过阈值切换策略控制回撤”。读起来像在做工程决策而不是在罗列工具。F奖更看重“你的方案解决了什么问题”而不是“你用了几个模型”。5.2 图表规范与灵敏度分析美赛论文要求图表必须在标题或注释中独立看懂。我们的经验是每张图都包含完整标题、坐标轴标签、单位、关键结论的标注箭头。比如BTC价格预测图我们在95%置信区间上画了真实值的后半段并用灰色阴影标出样本外区域。评委看到的第一眼就能理解模型泛化能力。灵敏度分析是F奖的分水岭。我们做了两个方向的敏感性分析一是预测区间宽度从70%调到95%对策略收益的影响二是交易成本从0到1%对策略换仓频率的影响。两个实验都得出了“策略在合理区间内表现稳定”的结论。这份分析让评委觉得你的模型不是运气好而是结构上稳健。5.3 附录该放什么附录不要放一大段全部模型代码而是放关键代码块、数据预处理的流程图、以及额外的结果表。我们放了一个“模型假设列表”把题目中没明说的假设全部写清楚比如“交易按当日收盘价执行”“不考虑持仓利息”“不考虑市场滑点”。这些假设会让论文显得非常严谨。6. 常见问题与备赛经验分享6.1 备赛中踩过的坑我们最大的坑是在特征工程上使用了未来数据。第一版代码在计算“过去20日均线”时因为pandas的shift参数写错了导致所有特征里混入了当天的未来信息。回测收益高得惊人但当我们把数据切到样本外时策略几乎失效。排查这个问题花了整整一个晚上教训是凡是涉及滚动窗口的特征必须把shift窗口写清楚最好打印最近几行做人工检查。第二个坑是数据对齐。比特币和黄金的交易时间不同黄金节假日不交易。如果直接把两个序列按自然日合并回测结果会出现大量“看似持仓黄金但当天并没有黄金价格”的情况。解决方案是按共同交易日取交集例如上面的join怎么选以及fillna策略。这类问题不解决论文的数据描述环节就会被评委找出破绽。第三个坑是忘记保存中间结果。我们在比赛第一天就把数据清洗后的版本存到CSV后面所有实验都以这个CSV为基准不重复清洗。如果每个模型重新读原始数据再清洗一遍很容易在某一步改了参数导致最终结果无法复现。6.2 三天时间怎么分配美赛只有72小时头一天晚上决定选题和大致方向第二天做主攻第三天专门写论文和排版。我建议这样分配第1天读题、拆解问题、确定数据清洗和模型框架把代码仓库和环境建好。第2天集中做预测模型和交易策略回测所有图表在这天做完。第3天写论文正文调整摘要做灵敏度分析和结论最后统一排版、检查错别字和格式。小组分工上一个人盯代码一个人盯论文结构另一个人盯数据和图表三块每天同步一次。最忌讳的是三个人同时在写同一段内容或者代码和论文完全脱节。我们每天晚饭时花半小时对齐“代码跑出来的结果”和“论文里准备呈现的结果”确保最后一天不用大改。关于写作工具个人强烈推荐LaTeX模板。虽然学习成本略高但美赛官方很认可LaTeX的排版效果而且你不需要手动调整图表浮动的痛苦。主办方官网提供了自带的美赛LaTeX模板直接用就行。最后再分享一个自己的体会美赛C题这类“数据决策”题型最大的陷阱是让模型复杂度喧宾夺主。我们的F奖方案从头到尾用的都是公开库、常见模型没有任何一处“非主流”的奇技淫巧。你能把数据的来龙去脉讲清楚把策略的每一步选择解释清楚把灵敏度的边界测出来就已经赢过了绝大多数队伍。如果你明年打算冲F奖或O奖先把基础链路跑通再考虑加戏这才是最稳妥的路线。本文还有配套的精品资源点击获取
返回列表