说个让我头疼了三天的破事。我写了个EA,只打算让它盯着市场报价里的五个货币对做交易。代码写完跑起来,一查日志发现它在扫描八个品种。过一会儿再看,变成十二个。到最后干脆把所有品种全扫了一遍。
我第一反应是自己代码写崩了。把枚举品种的循环重写了三遍,加了各种打印语句排查,死活找不到问题出在哪。
后来翻到一个老掉牙的MQL5论坛帖子,MetaQuotes的开发人员stringo直接甩了句话:"这不是bug,是特意设计的行为" 。底下有个交易员也遇到了完全一样的情况,EA本来只扫五个品种,结果越跑越多。
这套逻辑你在MQL4官方文档里根本找不到。实际情况是这样的:当你的EA在计算持仓盈亏或者保证金需求的时候,MT4会自动把参与计算的那些品种加到市场报价列表里。哪怕你从来没手动添加过它们。MetaQuotes官方的解释是,"隐式添加参与盈亏和保证金计算的品种"就是他们想要的效果 。
这对你的EA意味着什么
设想一下这个场景:你的EA持仓里有AUDCHF和NZDUSD两个单子,然后你的代码用
SymbolsTotal()循环扫描市场报价来获取交易信号。本来只想看五个品种,结果MT4自动给你塞了一堆相关的品种进来,你的EA就开始扫五十个品种了。执行效率拖慢不说,策略逻辑也跟着乱套。更恶心的一点是,MT4压根没有提供函数让你判断某个品种到底是用户主动添加的还是系统偷偷加进来的。论坛里有用户提过这个需求,MetaQuotes认了有这个限制,但至今没给解决方案 。
我的解决方案
被这玩意儿折磨够了之后,我摸索出一套管用的办法:
SymbolsTotal()去读市场报价都有什么,自己维护一个品种清单,用输入参数或者CSV文件配置。SymbolSelect()确认品种存在。</strong> 这样你可以主动把需要的品种加进去,不受自动添加逻辑的影响。SymbolSelect(symbol, false)就能移除。下面这段代码救了我的命:
``
mql4
// 别再用SymbolTotal()瞎扫了
string targetSymbols[5] = {"EURUSD", "GBPUSD", "USDJPY", "AUDUSD", "USDCAD"};
for(int i = 0; i < ArraySize(targetSymbols); i++) {
if(SymbolSelect(targetSymbols[i], true)) {
// 品种已经加到市场报价里了,开扫
double bid = MarketInfo(targetSymbols[i], MODE_BID);
// ... 你的交易逻辑
}
}
``参考来源
本文首发于FXEAR.com,原创内容,未经授权禁止转载