成交与费用

一张限价单分几次成交,手续费该怎么算?

限价单部分成交时,按每笔成交价、数量、maker/taker 身份和扣费资产核算,再处理撤单余量、BNB 抵扣与导出去重。

一张限价单分几次成交,手续费该怎么算?

订单页显示“一张限价单”,成交明细却有三行,手续费也跟着出现三笔。核账时应以每一笔实际成交为起点:成交多少、按什么价格成交、这一笔是 maker 还是 taker、实际扣了哪种资产,逐行记录后再按订单汇总。订单总额适合核数量,不能替代成交明细计算手续费。

本文只讨论中心化交易所的现货订单簿,不延伸到 DEX 的 Gas、链上路由,也不套用股票券商的最低佣金。文中的币种、价格和费率都是教学假设,不代表真实交易或平台当前收费。平台费率、优惠和取整规则会调整,最终应以账户在成交时留下的手续费记录为准。

先把订单与成交分成两层

限价委托表达的是“最多买到什么价格”或“最低卖到什么价格”,订单簿撮合后才形成成交。一张买入 10 枚 XCOIN 的委托,可能先成交 2 枚,几分钟后成交 3 枚,最后再成交 5 枚;也可能只成交 4 枚,余下 6 枚被用户取消。手续费跟着已发生的成交产生,不跟着未成交的委托数量产生。

因此,核账要同时保留两层记录:

层级 主要回答的问题 适合核对的内容 不宜单独据此判断
订单 这次委托想买卖多少,当前状态是什么 委托数量、累计成交数量、未成交余量、取消状态 每一笔的实际费率、扣费资产和逐笔取整
成交 订单具体怎样被撮合 成交价、成交量、maker/taker、手续费、扣费资产、成交时间 原订单还剩多少未成交

限价单也不等于 maker 单。若限价买单进入市场时,价格足以与卖盘中的现有挂单立即成交,立即成交的部分拿走了流动性,可能按 taker 计费;剩余部分进入订单簿后,日后被别的订单成交,才可能按 maker 计费。币安的官方说明也明确举出一张 GTC 订单同时产生 taker 与 maker 成交的情况。若产品提供 Post Only,它可以用于避免订单立即作为 taker 成交,但对账仍应读取实际成交标记,而不是根据下单意图猜测。

同一订单号只是把成交归在一起的线索,不能把几笔成交压成一个虚构的“统一费率”。

逐笔手续费如何计算

教学核算可以写成:

单笔理论手续费 = 该笔计费基数 × 该笔适用费率

难点在三个“该笔”。计费基数要取这一笔实际成交的数量或金额;费率要取成交当时针对该交易对、账户等级和流动性身份适用的费率;扣费资产及换算要以实际记录为准。买入与卖出时默认收到的资产不同,启用 BNB 抵扣后扣费资产还可能改变,所以不能永远假设手续费用 USDT 表示。

账表应同时放“理论手续费”和“实际手续费”。理论列用于解释费率,实际列用于财务汇总。若平台逐笔按其精度规则处理,先把多笔未取整理论值相加再取整,可能与每笔实际扣费相加不同;不能为了让总数好看而改写原始 commission

三笔 0.84 示例

先看成交价格相同、流动性身份不同的教学数据。假设某 XCOIN/USDT 买单分三次成交,第一笔为 taker,假设费率 0.10%;后两笔为 maker,假设费率 0.08%。为单独说明 maker/taker 混合,三笔成交价都设为 100 USDT。表中的手续费暂以 USDT 作为教学记账单位,不代表真实平台一定这样扣费。

下表价格、成交额和费用的单位为 USDT。吃单对应 taker,挂单对应 maker。

成交 数量 × 价格 费用计算
A 吃单 2 × 100 200 × 0.10% = 0.20
B 挂单 3 × 100 300 × 0.08% = 0.24
C 挂单 5 × 100 500 × 0.08% = 0.40

三笔共成交 10 枚,成交额为 200 + 300 + 500 = 1,000 USDT;手续费为 0.20 + 0.24 + 0.40 = 0.84 USDT。以教学记账单位计算的综合费率为 0.84 ÷ 1,000 = 0.084%。0.084% 是三笔结果的加权值,不是平台另设的一档费率。若用 0.08% 套整单,会少算第一笔;若用 0.10% 套整单,又会多算后两笔。

成交价格也变化的示例

再看更接近日常导出的情况。假设一张买入 5 枚 YCOIN 的限价单设为 101 USDT,进入订单簿时立即吃掉 98.00 和 99.20 两档卖单,因此 D、E 两笔是 taker;剩余数量以 101.00 挂在订单簿,后来成交的 F 是 maker。费率仍是纯教学参数,手续费继续用统一记账单位展示,以便先练习逐行计算。

价格、成交额和费用继续用 USDT 表示。

成交 数量 × 价格 费用计算
D 吃单 1.50 × 98.00 147.00 × 0.10% = 0.14700
E 吃单 2.25 × 99.20 223.20 × 0.10% = 0.22320
F 挂单 1.25 × 101.00 126.25 × 0.08% = 0.10100

总成交额是 147.00 + 223.20 + 126.25 = 496.45,总手续费是 0.14700 + 0.22320 + 0.10100 = 0.47120。数量加权平均成交价是 496.45 ÷ 5 = 99.29,但不能再用 99.29 乘一个统一费率倒推出原手续费,因为三笔的流动性身份不同。按总成交额观察,教学综合费率约为 0.47120 ÷ 496.45 = 0.09491%;这个结果仍只是复核指标。

核对成交数量与净到账

前面的两个例子把手续费暂时放在统一记账单位中,适合练习 maker/taker 加权。真正核钱包余额时,还要处理“成交数量”和“净收到数量”的差别。币安官方现货资料说明,常规情况下手续费通常从交易中收到的资产收取:买入时收到基础资产,卖出时收到报价资产。启用且满足 BNB 抵扣条件时,扣费资产可能改为 BNB。无论采用哪一种,都应以成交明细的 commissionAsset 为准。

假设某买单以 25.00 USDT 限价委托买入 8 枚 ACOIN,进入订单簿时先吃掉 24.80 和 24.90 两档卖单,剩余数量挂在 25.00;最后成交 6 枚,余下 2 枚取消。三笔教学记录如下;费率不是平台当前费率,并假设都从买入后收到的 ACOIN 中扣除。

下表数量为 ACOIN,价格为 USDT;费用从 ACOIN 数量中计算扣除。

成交 数量 × 价格 扣费计算(ACOIN)
T101 吃单 2 × 24.80 2 × 0.10% = 0.0020
T102 吃单 3 × 24.90 3 × 0.10% = 0.0030
T103 挂单 1 × 25.00 1 × 0.08% = 0.0008

成交数量合计为 2 + 3 + 1 = 6 ACOIN,报价成交额为 49.60 + 74.70 + 25.00 = 149.30 USDT,ACOIN 手续费为 0.0020 + 0.0030 + 0.0008 = 0.0058 ACOIN。在这个假设里,净收到数量是 6 - 0.0058 = 5.9942 ACOIN。订单的未成交余量仍是 8 - 6 = 2 ACOIN,它不会进入成交额,也不会产生这一订单的现货成交手续费。

这组数量核对可以解释一种常见误会:订单页显示买到 6 枚,钱包可用余额却只增加 5.9942 枚,并不自动意味着少成交了 0.0058 枚。先查看实际手续费是否正好以 ACOIN 扣除。若明细显示手续费资产是 BNB,理论上的净到账数量应重新按 BNB 路径核对,不能继续从 6 枚 ACOIN 中减费。

卖出时也按成交额核对净到账。若成交明细显示卖出 6 ACOIN、报价成交额 149.30 USDT、手续费 0.1493 USDT,那么教学条件下净收到报价资产是 149.30 - 0.1493 = 149.1507 USDT。这只是说明账表关系;实际费用数量、资产和精度全部取成交记录。

为了避免把仓位成本算乱,可在账表中把“成交数量”“手续费资产”“手续费数量”“净入账数量”分开。以后计算平均持仓成本时,选择用成交前数量还是扣费后的净数量,必须在整本账中采用同一规则并写进说明,不能只在出现差异的订单上临时换算法。

部分成交后撤单如何核对

订单状态为“已取消”不代表整张订单没有成交,也不代表此前手续费应退回。应先核累计成交量,再算未成交余量:

未成交余量 = 委托数量 - 累计成交数量

假设限价买入 10 枚 ZCOIN,其中 4 枚以 50 USDT 成交,余下 6 枚随后取消。已成交金额是 4 × 50 = 200 USDT。若为了教学假设这一笔的记账费率为 0.10%,理论手续费为 200 × 0.10% = 0.20 USDT。取消的 6 枚没有形成现货成交,不能把 10 × 50 = 500 USDT 当手续费基数,也不能因为最终状态是取消就把已成交的 0.20 抹掉。

核对这类订单,可使用下面的数量关系:

项目 教学数量
原始委托数量 10
成交明细数量合计 4
取消时未成交余量 6
数量恒等式 4 + 6 = 10

若订单页的累计成交为 4,而导出里只找到 3,首先怀疑成交导出缺行或筛选范围不完整;若导出合计为 5,则检查是否重复导入。不要通过新增一行“平衡数”强行对平,因为那会失去成交编号、扣费资产和时间证据。

扣费资产不同怎么汇总

币安现货资料说明,常规现货手续费通常按交易中收到的资产收取;启用 BNB 手续费抵扣后,符合条件的费用会换算成 BNB。真正对账时仍以每笔 commissionAsset 为准,因为买卖方向、功能开关、余额和具体活动都可能让扣费资产不同。

例如,同一订单的三笔实际记录分别为 0.00012 BNB0.00011 BNB0.08 USDT。正确的原币汇总是:

  • BNB 手续费:0.00012 + 0.00011 = 0.00023 BNB
  • USDT 手续费:0.08 USDT

不能写成“总手续费 0.08023”,因为 BNB 与 USDT 不是同一计量单位。如果管理账需要统一折成 USDT,应新增估值价格、估值时点和折算值三列,同时保留原始手续费数量。这样才能区分“平台实际扣了多少币”和“这笔币在某个时点值多少 USDT”。

BNB 抵扣余额不足

打开 BNB 抵扣开关也不等于每笔一定按 BNB 折扣扣费。币安官方说明写明,现货账户需要持有足够 BNB;余额不足时,会按费用与交易概览页列示的原始手续费收取。官方页面同时提醒,下单界面的预计手续费只供参考,最终费用取决于实际成交。

因此,若前两笔扣 BNB、后一笔突然改扣收到的资产,不要先把它认定为重复收费,也不要自行假设系统会把剩余 BNB 用完后仅补差额。更稳妥的处理是逐笔检查:成交时间、BNB 可用余额、抵扣开关状态、commissioncommissionAsset,以及当时的实际费率记录。账表只记录已发生的扣费;对余额不足原因没有账户证据时,标成“待核”,不要把推测写成结论。

导出缺行与重复如何排查

合并网页导出、分月 CSV 和 API 结果时,最容易出现两类错误:筛选窗口漏掉一段,以及同一笔成交被导入两次。处理顺序应先保全原文件,再在工作副本中标准化。

查缺行

  1. 先按账户范围、现货市场和交易对固定范围,记录导出的开始时间、结束时间与时区。
  2. 用订单页的累计成交数量,对比同一 orderId 下所有 qty 之和;再用订单成交额对比 quoteQty 之和。
  3. 检查时间边界。按月导出时,UTC 月末与本地月初可能落在不同文件;毫秒时间戳应保留到原始精度。
  4. 若使用 API,记录每次查询参数和返回条数,按文档允许的时间或成交编号方式连续取数。一次返回达到上限或仍有后续记录时,继续分页,不能把单次响应当作完整历史。
  5. 若订单数量能对上而手续费对不上,检查是否遗漏 commissionAsset 列,或表格软件把很小的数显示为 0。

查重复

建议用“账户范围 + 市场 + 交易对 + 成交编号”作为账表中的复合去重键,订单编号作为复核列。同一个订单号对应多笔不同成交编号是正常情况,不能按 orderId 去重;相同时间、价格和数量也可能是两笔真实成交,不能仅凭这三列删除。

若同一复合键在网页导出和 API 文件中各出现一次,保留一笔,并在“来源文件”列同时记录两个来源。若关键字段不一致,先保留两行、标记冲突,再回到官方成交历史核对;不要任意选择手续费较小的一行。

可复制的逐笔账表

每笔成交应该保留哪些字段

网页、CSV 和 API 的中文列名可能不同,先把字段含义统一,后续才能合并。币安现货账户成交接口返回的核心字段包括 symbolidorderIdpriceqtyquoteQtycommissioncommissionAssettimeisMaker。其中 id 是成交编号,orderId 是订单编号;两者不能互换。

账表列与接口字段 用来核对什么
账户范围(自行记录) 区分主账户、子账户或其他账本,不同账户的数字编号不能混着去重
市场(自行记录) 本文固定为现货,不把杠杆、合约流水混入
交易对 symbol 确定基础资产与报价资产,不跨交易对仅凭数字编号去重
成交编号 id 定位一笔成交,连同账户范围、市场和交易对使用
订单编号 orderId 汇总一张委托,一个订单号出现多行通常是分批成交
成交时间 time 排序、分账期、核对费率时点,统一时区并保留原始毫秒时间戳
成交价 price 计算实际成交金额,不用订单限价代替
成交数量 qty 这一笔实际成交的基础资产数量,不用原始委托数量代替
报价成交额 quoteQty 可用价格乘数量复核,实际返回值优先
成交身份 isMaker 区分挂单或吃单,同一订单可以有两种身份
手续费数量 commission 保留实际原值,不先折算或四舍五入
扣费资产 commissionAsset 确认费用以什么资产收取,不同资产分组汇总

如果只做手工对账,最少也要留下交易对、成交编号、订单编号、时间、成交价、数量、成交额、maker/taker、手续费和扣费资产。缺少成交编号时,先回到更完整的原始导出补字段;用“同一分钟、同价格、同数量”拼成替代编号,容易误删两笔真实成交。

原始字段旁边可以增加解释列,但不要覆盖原值。比如网页把 isMaker=true 显示为“挂单方”,工作表可另建“身份中文”列;时间戳可另建“本地时间”列;quoteQty 可另建“计算成交额”列进行交叉检查。若两列不一致,保留差异并回查精度,而不是把接口返回值改成手算值。价格和数量也应按文本或足够的小数位导入,避免表格软件自动转成科学计数法或截断末尾精度。对账文件一旦交给别人复核,原始列、转换列与汇总列分开,才看得出差异是在交易记录里,还是在导入和计算过程中产生。

下面这组表头可以直接粘贴到表格软件。金额列不要预先设置成两位小数,以免小额手续费被显示精度掩盖。

账户范围,市场,交易对,成交编号,订单编号,成交时间UTC,成交价,成交数量,报价成交额,isMaker,实际手续费,扣费资产,成交时费率依据,理论手续费,估值时点,估值价格,统一计价成本,来源文件,去重键,核对状态,备注

汇总表则保持简单:

订单编号,交易对,委托数量,成交数量合计,未成交余量,成交额合计,maker成交额,taker成交额,手续费资产,该资产手续费合计,统一计价成本,差异状态

同一订单有两种扣费资产时,在汇总表中写两行,不要把资产名称塞进一个单元格后直接求和。推荐的公式关系是:

  • 成交数量合计等于该订单所有唯一成交编号的 qty 之和;
  • 未成交余量等于委托数量减成交数量合计;
  • 成交额合计等于所有唯一成交编号的 quoteQty 之和;
  • 某资产手续费合计只汇总 commissionAsset 等于该资产的 commission
  • 统一计价成本等于各原币手续费乘各自明确记录的估值价格,不能反推覆盖原币数据。

这张表也能与资金费用对账分开:现货逐笔手续费用成交编号归集,永续合约资金费用则围绕结算事件和资金流水核对。把两类成本放在同一个总账没有问题,但来源键和计算公式不能混用。

账期与估值规则怎样固定

逐笔数据对上后,月度报表仍可能因为账期和估值方式不同而出现差异。先在工作簿首页写明账期时区、起止时间是否包含、手续费原币的估值时点和价格来源。比如采用 UTC 月度账期时,可以把 9 月定义为 2026-09-01 00:00:00 UTC(含)至 2026-10-01 00:00:00 UTC(不含)。这样,一笔发生在新加坡时间 10 月 1 日清晨的成交仍可能属于 UTC 9 月,分类依据清楚可复查。

估值也要与原币汇总分开。假设 9 月手续费合计为 0.004 BNB,月报选择每笔成交时的换算价,就逐笔折算后再汇总;若管理报表选择月末价,则整月统一用月末价。两种方法可能得到不同的 USDT 估值,但原始成本始终是 0.004 BNB。账表应标注所选方法,不能用某个更接近订单页显示值的价格反复试算,直到数字“看起来对了”。

需要重跑报表时,从未改动的原始导出重新生成工作表,并保存导入文件名、生成时间和筛选条件。手工修正应放在单独的调整表,写清原成交编号、调整原因和证据链接;不要直接覆盖 commissioncommissionAsset 或成交时间。这样,即使平台后来改变显示格式,也能从原始字段还原当时的计算。

年度或跨平台汇总时,先在各平台内部完成去重,再转成统一列名。不同平台的成交编号规则未必相同,不能把某个平台的数字 ID 当成全局 ID。平台名称、账户范围和市场类型都应成为复合键的一部分;这也能防止现货成交与同名合约成交被错误合并。

差异仍未消失时查什么

完成逐笔加总后仍有差异,按下面的证据顺序排查:

  1. 范围:账户、现货市场、交易对、起止时间和时区是否一致。
  2. 完整性:成交数量合计能否与订单累计成交量对应,API 是否取完全部页。
  3. 重复:是否将网页、CSV 和 API 中的同一成交编号重复导入。
  4. 费率身份:每笔 isMaker 是否与所用费率一致,是否误把整张限价单都当 maker。
  5. 扣费资产:是否把 BNB、基础资产和报价资产直接相加,或漏掉余额不足后的非 BNB 扣费。
  6. 历史条件:是否拿今天的费率等级、促销或开关状态重算过去的成交。
  7. 精度:是否用显示值代替原始精度,或先汇总理论值再统一取整。

向平台客服提交问题时,准备订单编号、成交编号、交易对、UTC 时间、实际手续费和扣费资产即可形成可定位的证据包。API 密钥、密码、2FA 恢复信息都不属于对账材料。

资料来源与核验日期

本文于 2026-09-11 核验。下列官方资料用于核对流动性身份、成交字段和 BNB 抵扣情况,实际费率仍以账户成交时记录为准。

作者:Tradecost 编辑部