每到日前申报截止前十分钟我都要对着报价单发一会儿呆。同样的机组、同样的成本、同样的预测负荷昨天报了350元今天要不要报380元多留20兆瓦给实时市场还是全部锁在日前这些问题刚接触电力交易时我基本靠拍脑袋后来被实时的价格波动教育了几次才慢慢把电力市场中的两阶段市场投标策略做成一套可以计算、可以复盘、可以持续优化的决策流程。这篇文字就把我踩过的坑和现在在用的框架整理出来给做发电侧交易、售电公司结算或者刚入行研究电力市场的朋友一个参考。很多新手以为投标策略就是报个价等出清但两阶段市场的真正玩法是在两个不同时间尺度、不同价格信号的市场之间做“电量分配”。你的每一段报价本质上都是一道选择题这段电量今天在日前市场锁定还是等几个小时后的实时市场再碰运气。搞清楚这件事报价就不是玄学而是可以量化求解的优化问题。1. 两阶段市场的结构与结算逻辑先搞清楚你在跟谁做选择1.1 两阶段到底指哪两个阶段国内目前的现货市场普遍采用“日前实时”的两阶段出清架构这是由电力系统的物理运行特征决定的。日前市场要提前一天确定机组开停计划和大致出力水平相当于餐厅晚上打烊前先把第二天要用的菜备好、菜单定好。实时市场则是在真正出力前几分钟到几小时根据最新的负荷、新能源出力预测和电网故障情况做最后一轮调整相当于客人临时加菜或者后厨发现食材不够时的紧急调配。这两个市场不是孤立的它们共用一套电网模型和报价信息但解决的决策层级完全不同。日前市场解决的是“哪些机组开、开到多少”实时市场解决的是“实际运行时跟计划差多少、谁来补”。因为两阶段紧耦合所以报价策略不能只看日前或只看实时必须站在两个市场的交界处统一决策。1.2 结算规则决定了报价行为的底层逻辑两阶段现货市场的结算规则可以用一句话概括日前中标电量按日前节点电价结算实际发用电量与日前中标量的偏差电量按实时节点电价结算。这句话是整个报价策略的“牛顿定律”。举个例子。你有一台100兆瓦机组日前报价全部中标日前出清价400元/兆瓦时实际上网电量也是100兆瓦时那你的现货收益就是100乘以(400减去边际成本)。但如果日前只中标了60兆瓦而实际发了100兆瓦多出来的40兆瓦就要按实时价格结算。实时价500元你多赚实时价300元你可能白忙活一场。反过来如果你日前中标了100兆瓦实际因为设备故障只发了80兆瓦少发的20兆瓦就要按实时价或者考核规则从市场上买回来等于把日前锁定的高价吐出去一部分。这个规则给交易员的启示非常直接报价表填的不是“我希望以什么价格卖”而是“在什么价格条件下我选择把电量锁定在日前市场在什么价格条件下我选择把电量暴露给实时市场”。所有关于两阶段投标策略的建模、情景分析、风险控制都是围绕这个选择展开的。1.3 中长期合约是叠加在这套逻辑上的另一层约束这里要澄清一个容易混淆的点。很多人聊“两阶段市场”时指的是中长期市场和现货市场那是一个更大的话题。我这里重点拆解的是现货市场内部的日前实时两阶段但中长期合约会作为一个硬约束参与到报价决策里。中长期合约已经锁定了未来的量和价。合同分解到每一天后的曲线会形成你的持仓底仓。这部分电量在日前市场必须足额申报否则会有偏差考核。所以你真正能在两阶段之间自由腾挪的是中长期持仓以外的“敞口电量”。换句话说中长期合约越多你在两阶段报价里的自由度和风险暴露就越小中长期合约越少报价策略对价格预测和风险偏好的依赖就越强。做策略时先把手里的持仓曲线摊开再看敞口怎么分配这个顺序千万别搞反。2. 报价前最重要的工作把日前与实时价差预期算清楚2.1 价差从哪里来实时市场为什么波动更大实时价格和日前价格的偏差本质上来自“预测的世界”和“真实的世界”之间的差距。日前出清时用的负荷预测是提前一天的新能源出力预测那时候也还没收敛等到实时运行天气变了、风机出力变了、某条线路意外检修了这些信息都会集中在实时价格里兑现。所以大多数现货市场里实时价的波动幅度要显著大于日前价。最典型的就是光伏大发的中午时段日前可能还报出200元的价格到实时阶段因为预测外的云层减少、光照猛增价格直接砸到0附近甚至负价。反过来晚高峰如果出现一台大机组临时跳机实时价可能从日前300元飙到800元以上。理解价差来源是为了判断一个问题你面对的两阶段市场里实时价相对日前价是系统性偏高、系统性偏低还是忽高忽低但均值接近。这个判断直接决定报价曲线的整体位置是往高里抬还是往下压。2.2 构建价差预期的实用方法我见过不少团队花大价钱买机器学习模型最后发现报价格局还是靠拍脑袋。真正可用的价差预期其实可以分三步搭起来。第一步按运行时段把历史日前价和实时价拉出来做对比。国内现货市场通常按96个点或288个点出清那就是把每个时段当成一个独立样本统计过去90天或一年的价差分布。不需要太复杂的模型先看各时段价差的中位数、25%分位数、75%分位数你就能知道哪些时段容易出现系统性偏差哪些时段价差接近零。第二步把负荷预测偏差、新能源出力预测偏差、检修计划等因子跟价差做相关性分析。比如某个时段如果新能源实际出力比预测高500兆瓦历史对应的实时价往往比日前价低多少。这种条件化分析比笼统的分位数更贴近当天行情。第三步用滚动预测持续修正。昨天预测今天的价差不代表今天真实如此每天早上的最新气象预报、电网检修公告、省间送受电计划都会改变价差预期。我习惯的做法是每天早上更新一次预测基准在日前申报截止前再刷新一轮。做价差预期还有一个容易忽略的点要用机组所在节点的价格而不是系统均价。省间联络线功率变化、局部输电阻塞都会让节点价差跟系统均价差出一大截。反正做交易员节点电价数据必须落到自己的现货收益计算里。2.3 别只用期望值要把整个分布摊开看价差预期最容易犯的错就是只盯着期望值比如预计实时价比日前价平均高20块于是把所有电量都留到实时阶段结果当天实时价暴跌全盘皆输。期望值只是所有情景的加权平均它不告诉你有多少概率会走到极端情形。实际做决策时我会把预测价差拆成几个典型情景不同概率下对应不同价差。比如“实时低100块”“实时持平”“实时高150块”三个情景概率分别是0.3、0.4、0.3期望是0.3乘以负100加0.4乘以0加0.3乘以150等于15块。只看期望你会觉得实时略优但0.3概率的负100块情景是必须正视的尾部风险。报价策略里必须有对这种风险的度量而不是被期望值拖着走。这也引出了后文的核心——两阶段随机规划框架为什么要被引入到报价决策里。3. 两阶段投标策略的建模框架与量化方法3.1 核心直觉报价线就是在划“锁量边界”在报量报价的现货市场中机组的申报曲线通常由多段量价对组成每个价格段对应一个电量段。市场出清时报价段价格低于或等于出清价的电量会在日前中标高于出清价的电量不会在日前成交简化理解。这意味着你在某个价格段上填的申报价实际上就是一道门槛日前出清价过不过这道门槛决定这段电量是被锁在日前还是流向实时。这个视角非常重要。报价线抬高相当于你更挑剔门槛更高只有日前出清价足够高时才愿意锁定电量反过来报价线压低等于你不挑食出清价低也愿意先锁定求一个确定性。两阶段投标策略的本质就是给每段电量找到一道能够匹配市场概率分布和风险偏好的门槛。这个框架能覆盖从56段报价、两段报价到任何分段形式的市场规则。3.2 从期望收益最大化到两阶段随机规划我们看这个问题时不能只看单情景下的收益因为日前报价那一刻实时价格是随机的。严谨的做法是建一个两阶段随机规划模型。第一阶段决策变量是各电量段的报价曲线参数第二阶段假设市场按给定规则出清在每一组可能的日前价和实时价情景下计算机组的现货收益然后对情景概率加权求期望收益。目标函数是最大化期望收益再加上风险约束或风险惩罚项。约束条件除了报价段本身的单调性限制电量段价格从低到高排列还要把机组最小出力、爬坡速率、最小开停机时间这类物理约束折算进去。用数学语言写简化形式就是目标函数max 其中下标代表情景代表日前中标电量代表实际出力是情景概率。这个模型看起来复杂但落到实际程序里本质就是“枚举每段报价金属线算出所有情景下的收益再做加权求和”。很多团队用Gurobi、CBC这类求解器来做更灵活的做法是直接做情景枚举反正机组报价段就那么多穷举也没多大计算量。3.3 风险控制从期望收益单指标到CVaR约束只用期望收益做决策等于默认你是风险中性的这在电力市场里并不适用。电力现货收益波动非常大一次极端行情可能把几个月的利润吃掉。所以两阶段投标策略必须引入风险度量目前业界最常用的就是CVaR条件风险价值。CVaR可以通俗理解为“最差的那部分情景下的平均收益”。比如你有100个价差情景95%的CVaR就是把收益排序后最差的5%情景取平均。CVaR约束要求这个尾部平均不能低于某个阈值等价于在优化模型里增加风险约束我们既要赚钱也不能让极端行情把底裤亏掉。实际操作中我的经验是把风险约束做成可调参数。交易团队可以开会定一个目标极端尾部收益不低于某个水平比如每时段不低于负5000元。模型在满足这个约束的前提下再去最大化期望收益。这样报出来的曲线是“风险约束下的最优解”而不是拍脑袋的激进策略。3.4 一个最小的Python情景枚举示例为了不空谈模型我用一个极简示例演示两阶段报价的计算逻辑。假设机组100兆瓦、边际成本300元/兆瓦时预计日前出清有两个可能价格实时出清也有两个可能价格组合成4个情景import pandas as pd scenarios pd.DataFrame([ {da_price: 340, rt_price: 300, prob: 0.3}, {da_price: 340, rt_price: 420, prob: 0.3}, {da_price: 400, rt_price: 300, prob: 0.2}, {da_price: 400, rt_price: 420, prob: 0.2}, ]) # 报价线为360时 bid_price 360 scenarios[hit] (scenarios[da_price] bid_price).astype(int) scenarios[profit] ( scenarios[hit] * 100 * (scenarios[da_price] - 300) (1 - scenarios[hit]) * 100 * (scenarios[rt_price] - 300) ) expected_profit (scenarios[profit] * scenarios[prob]).sum() print(f报价线 {bid_price} 元的期望收益: {expected_profit:.0f} 元) scenarios[profit].min() # 最差情景收益这个代码把“报价线”变成一道二值门槛简化处理了近日出清等于报价线时的边际出清细节但核心逻辑跟真实市场一致。实际策略系统里把二值门槛换成多段阶梯申报把“从成本价到预测极端价”的报价区间按段位细分枚举每段量价的组合再用求解器跑一遍就是一个可落地的两阶段报价优化器。4. 实测案例一台100兆瓦机组今天该怎么报4.1 案例参数与情景设置回到开头的场景。一台100兆瓦燃机边际成本300元/兆瓦时没有启停约束和爬坡约束简化假设只运行一个现货时段。根据历史价差数据交易员给出了如下情景判断情景日前出清价实时出清价概率情境含义13403000.3日前价格尚可实时仍回落至成本线23404200.3日前低估晚高峰需求实时冲高34003000.2日前紧张但实时供需缓解44004200.2整个系统保持高电价这四个情景可以覆盖最常见的价差模式实时低于日前、实时高于日前、全时段高价、全时段低价。概率加总为1。4.2 四类代表性策略的收益对比策略A100兆瓦全部报价300元等于闭着眼睛把全部电量锁在日前市场。策略B100兆瓦全部报750元等于把所有电量留给实时市场赌实时高价。策略C100兆瓦全部报360元等于设一道门槛日前出清超过360元才锁定。策略E40兆瓦报300元、60兆瓦报360元等于先给40兆瓦买一份“保底”剩下60兆瓦再搏一搏。把上一节的计算逻辑展开可以得到这个收益对比表策略期望收益最差情景收益风险特征A全部锁日前6400元4000元收益稳完全放弃实时机会B全部留实时6000元0元期望不算差但有两成概率白忙C全部报360元7600元0元期望最高尾部风险也最高E40MW保底60MW门槛7120元1600元期望中上最差仍有一定利润4.3 结果解读报价线的移动方向藏着所有决策逻辑看到这张表很多人第一个疑问是为什么C期望最高却风险最差因为报价线360这个位置正好卡在情景1和情景2的日前出清价340之上。如果最终日前价是340全部电量留到实时此时实时价300就是白干但反过来如果实时价420就吃到12000元的高价。等于用大概率白干换小概率吃大肉。这就是把报价线抬高到预测价附近的效果。策略E相比策略A把40兆瓦用300元保底电价锁定另外60兆瓦才参与“门槛筛选”。在情景1这种低落差情况下保底段还能贡献1600元利润其他情景也不会错过太多。这个折中方案适合大多数风险厌恶的发电企业。真正的决策流程就是先把各时段的历史价差分布拉出来结合当天预测生成情景表然后对你手里的每一个策略跑一遍期望收益和尾部风险最后根据公司设定的CVaR阈值挑一条报价曲线。不要临场发挥把这个过程固化到每次申报前的工作流里去。5. 报价落地中的常见坑与排查心得5.1 误区报价线等于我的心理预期价这个坑几乎每个新入行的交易员都踩过。有人觉得预期价格是380元于是成本段、利润段全填380结果出清价350机组没中标眼睁睁看着别的机组用330元成本价成交自己留到实时被价格教育。报价线不等于心理预期价。除了预期价你还得考虑实时价格分布、自身风险承受能力、中长期持仓等。还是那句话报价线是“锁量边界”不是“目标价”。把这两件事分开报价逻辑就会清晰很多。5.2 物理约束没申报进报价曲线现货市场里的机组不可能像教学案例那样想发多少就发多少。最小技术出力、爬坡速率、最小开停机时间、最短运行时长全都约束着实际出力。常见的问题是把某段电量报得很高结果日前中标了但实际运行到那个时段时机组还处于停机状态或爬坡爬不到指定出力只能去实时市场高价买回来或者承受偏差考核。这类损失往往一次就吃掉几个月的优化收益。我踩过这个坑之后的做法是把物理约束先做成一个“可行出力区间”在报价优化之前直接削掉不可行的电量段。报价曲线里根本不允许出现超出物理可行域的组合从源头上避免“纸上中标、现场翻车”。5.3 市场力监控红线这里必须强调一点两阶段投标策略是应对价格波动的优化问题不是操纵市场的投机游戏。绝大多数市场都设有市场力监控机制包括报价阈值、市场力缓解措施、集中度指标等。你可以在规则边界内优化申报但不要试图通过抬高报价曲线营造人为稀缺。我见过不止一个团队因为报价曲线形状异常被监管约谈。本来是想多赚一点结果被套上“策略性报价”的帽子不仅收益被没收还影响了整个公司的履约信用。做交易第一要务是合规。优化模型里必须加一道“合规过滤器”把明显高于边际成本数倍、或者与历史正常报价形态偏差过大的报价方案直接丢弃。5.4 数据没有滚动更新两阶段报价做得再精细如果输入数据是三天前的等于用去年地图开今天的车。负荷预测更新了、新能源出力变了、联络线计划调整了这些信息都必须在报价截止前反映到情景生成里。我现在的工作流是每天早上抓最新预测数据生成早盘情景临近截止前一小时再刷新一轮如果出现重大价格信号变化就快速重跑优化。这套流程不需要多昂贵的系统一批数据脚本、一个优化脚本、一张申报校验表就能搭起来。电力市场里赚钱的不是最聪明的人而是信息更新最快、流程最规范的人。5.5 储能和售电公司的两阶段逻辑略有不同如果是储能电站参与现货市场它跟火电的报价逻辑不太一样储能的“发电成本”是充电成本两阶段报价要在日前同时决策充电曲线和放电曲线再结合实时价差决定实际充放策略。售电公司则是面对中长期合约和现货偏差原理一样但要把用户负荷的不确定性当成主要风险源。虽然主体不同但“把电量分配看成两阶段决策”这个底层思维是通的模型框架可以平移过去只需要把成本项、约束项和价格情景换成自己的数据。我个人这几年做下来最大的体会是两阶段投标策略不是一个“今天填什么数”的问题而是一套持续运转的决策系统。价格预测要滚动刷新情景要跟着负荷、新能源出力和阻塞变化走每次报价之后都要把实际出清结果拉回来做复盘看看预判的价格方向有没有偏移概率设置需不需要校准。报价单上那些数字本质上就是这套系统对不确定性的一次表态。把拍脑袋变成计算把事后后悔变成事前演练你才算真正找到了进入电力市场交易的入口。最后再分享一个小技巧每次报价前把策略对比表打印出来贴在工位上就盯着期望收益和最差情景两列看今天到底选保守还是选激进一眼就能定下来。