折腾EA仓位计算与资金管理代码半天,终于搞明白了

较热35.2
登录发帖
Exness 推荐平台

入金门槛低,出金到账快,支持多种账户类型

FSA(塞舌尔)/FCA(英国) / CySEC(塞浦路斯) · 最低入金 $130
tgb720
tgb720 楼主 2026-8-27 11:08:15 浏览 132 回复 8 阅读 1 分钟
Lv.1 新手汇友 等级 Lv.1 主题 3 帖数 9 积分 2007 汇币 1756
1楼
搞了三个晚上,总算把EA里那套仓位计算的逻辑捋顺了。之前写马丁格尔策略的时候,回测曲线漂亮得像教科书,结果丢到demo跑了两周就爆仓,问题全出在仓位管理模块上——不是算错手数就是风控触发条件写死,今天把踩过的坑和对比方案整理出来,给还在折腾的朋友省点时间。
先说最常见的固定手数方案,代码就一行 `OrderSend(Symbol(), OP_BUY, 0.1, ...)`,优点是逻辑简单,回测参数好调,但缺点也很致命:账户净值从1万跌到5千时,0.1手对应的风险敞口直接翻倍,遇到欧美那种单日150点波动,浮亏能让你心态先崩。我后来改成固定分数法,也就是每次用净值的2%去算手数,公式是 `RiskAmount = AccountBalance() * 0.02`,再除以止损点数乘每点价值。这里有个坑,止损距离必须用OrderSend之前动态计算,不能写死,否则行情波动一变,实际风险敞口就偏离预设值了。
但固定分数法也有问题,它假设账户余额是连续变化的,可MT4的OrderSend是逐单执行,如果EA同时开了多单,比如欧美和镑美各一单,每单都按当前余额算2%,实际总风险就是4%了。我试过用`AccountEquity()`代替`AccountBalance()`,但回撤时净值波动太剧烈,导致手数忽大忽小,反而放大风险。后来查了论坛里汇友分享的经验,改成在EA的`init()`里设一个全局变量记录初始余额,然后每单计算时用 `(初始余额 - 当前浮亏) * 0.02`,这样至少能控制组合层面的总风险。
再说说更进阶的凯利公式变体,我见过有人直接用 `f = (bp - q) / b` 算最优仓位,但外汇市场的胜率和盈亏比是动态的,用历史回测参数去套未来行情,基本就是过拟合。我试过把盈亏比设成1.5,胜率按最近50单滚动统计,算出来的手数经常超过0.5手,点差和滑点一吃,实际收益还不如0.2手稳。所以我的建议是,凯利公式最多用来做仓位上限,实际下单手数要再乘个0.3的衰减系数,别真按理论值梭哈。
最后对比一下三种方案的实测数据,我用EURUSD M15跑了2023年整年回测,初始资金1万美金,固定手数0.1手年化收益8.2%,最大回撤14%;固定分数法2%风险年化12.6%,回撤9.8%;凯利衰减版年化15.1%,但回撤也到11.3%。考虑到实盘滑点和隔夜利息,我最终选了固定分数法,但把风险系数从2%降到1.5%,同时加了账户净值低于初始值90%时强制停止开新单的保护逻辑。代码里用`AccountInfoDouble(ACCOUNT_MARGIN_LEVEL)`监控保证金水平,低于200%直接平掉亏损单,这个条件一定要写在`OnTick()`最前面,别放在开仓逻辑后面,否则行情剧烈时可能来不及触发。
踩过最大的坑是MT4的`OrderSend`返回值判断,我一开始只检查是否大于0,后来发现如果因止损距离过小被拒单,返回-1但`GetLastError()`是130,这时候如果继续循环重试,可能瞬间连发几十单。正确做法是每次下单前用`MarketInfo(Symbol(), MODE_STOPLEVEL)`检查最小止损距离,再加上一个重试次数上限,比如最多3次,每次间隔500毫秒。另外,如果你用VPS挂EA,建议把日志写到文件里,不然MT4的专家日志滚动太快,出问题根本找不到线索。
现在这套逻辑跑了两个月demo,欧美和镑美同时开单,最大回撤控制在6%以内,但有个新问题想请教:当两个品种相关性高时(比如欧美和镑美同向波动),组合风险还是偏高,有没有人试过用协方差矩阵动态调整每单的仓位权重?我看了些对冲账户的配置思路,但MT4原生不支持跨品种风险计算,只能靠外部脚本算完再喂给EA,感觉有点绕,想听听大家的做法。

忘了说,demo跑的时候记得把滑点和手续费也模拟进去,不然回测和实盘的仓位偏差能差出好几个百分点。
2 回复 众裁0 复制
#1
老李头开饭了
老李头开饭了 #9· 2026-10-2 22:49:03
9楼
加仓单那个问题,我EA里是分品种单独记基准的,不是用总浮亏,不然欧美和镑美会互相干扰。K线收盘重算一次比tick级稳,阿伟哥说的这点我踩过坑
赞 回复 众裁0 复制
2026-10-2 22:49:03 #9
点差萌新
点差萌新 #8· 2026-9-13 10:00:47
8楼
楼主说用 `(初始余额 - 当前浮亏) * 0.02` 算手数,我有个疑问:如果这单是加仓单,浮亏是按所有持仓算还是只算当前货币对?我EA同时挂欧美和镑美加仓时,基准老是算混,手数忽大忽小,求指点🙏
赞 回复 众裁0 复制
2026-9-13 10:00:47 #8
RainyMoodx
RainyMoodx #7· 2026-9-1 16:10:05
7楼
我也在调马丁的仓位模块,楼主说止损距离不能写死这点太对了,我之前就是写死导致镑美滑点大直接超风险。我自己也用固定分数法,但多单并发确实头疼,凯利那段点醒我了,胜率滚动统计容易过拟合,还是得加个手数上限保险。😅
赞 回复 众裁0 复制
2026-9-1 16:10:05 #7
rfv117
rfv117 #6· 2026-8-31 10:00:16
6楼
楼主提到马丁回测漂亮但demo爆仓那段太真实了,我当初也是被回测曲线骗过,后来发现仓位管理里止损距离动态计算这步,很多人忽略的是不同品种点差差异对止损距离的影响。我自己在镑日上就吃过亏,动态止损算出来是50点,结果实际下单时点差突然拉到8个点,风险敞口直接偏了。另外关于固定分数法多单并发的问题,我用过一个笨办法,就是每单开仓前先遍历一遍当前持仓手数总和,再按剩余额度去分配,虽然代码丑了点但至少不会超总风险。
赞 回复 众裁0 复制
2026-8-31 10:00:16 #6
山间溪客
山间溪客 #5· 2026-8-30 22:24:04
5楼
搞明白仓位计算的核心是组合敞口控制,楼主这个初始余额减浮亏的思路比单纯盯单笔风险强。补充一点,多品种并发时建议按货币对波动率分配风险权重,别均分2%,否则镑美和欧美同时开单,波动差异会让实际敞口失衡。另外凯利公式那段,手数上限硬限制必须有,不然点差一放大直接穿仓。
赞 回复 众裁0 复制
2026-8-30 22:24:04 #5
阿伟哥
阿伟哥 #4· 2026-8-29 22:59:05
4楼
楼上说的初始余额减浮亏思路确实稳,不过我觉得关键在K线收盘重算基准这步,tick级触发容易来回跳,我demo就吃过这亏。
赞 回复 众裁0 复制
2026-8-29 22:59:05 #4
暮色
暮色 #3· 2026-8-29 09:50:04
3楼
楼主核心问题是多单并发时固定分数法会重复计算敞口,以及动态止损与净值波动的矛盾。补充一下,凯利公式那段说的过拟合很真实,建议加个手数上限硬限制,比如单笔不超过净值5%。另外用初始余额减浮亏的思路可行,但记得每根K线收盘时重算基准,别用tick级频率。
赞 回复 众裁0 复制
2026-8-29 09:50:04 #3
保守党666
保守党666 #2· 2026-8-28 14:52:03
2楼
固定分数法那个坑我深有体会,止损距离动态计算确实关键,我之前写死导致欧美单子风险翻倍。我自己也用AccountEquity试过,净值波动大反而手数不稳,后来改成初始余额加浮亏修正才稳。👍
赞 回复 众裁0 复制
2026-8-28 14:52:03 #2
THE END
本帖内容仅供学习交流,不构成任何投资建议。外汇交易存在高风险,请谨慎参与。
← 上一帖 MT4图表不显示怎么解决,有人遇到过吗? 下一帖 → 聊聊MT5深度市场工具使用指南的真实体验