寻求改进MQL5账户本位币止损现金亏损计算EA的方案
问题:账户本位币现金亏损计算EA的交叉盘适配优化
我正在开发一款计算账户本位币现金亏损的EA,这是风控型多币种交易EA的核心模块。目前完成的初始代码仅在含USD的货币对(如EURUSD)上计算准确,非USD交叉对(如EURGBP、AUDJPY)的计算结果错误。后续计划添加NetLossPerOnePrecentLotPerPoint功能,但当前优先解决交叉盘计算逻辑问题,附上现有代码,求改进思路。
现有代码
#property copyright "Gerald Mann (P. Ghasemi)" #property version "1.00" void OnTick() { if (PositionsTotal() > 0) { double ContractSize = SymbolInfoDouble(Symbol(), SYMBOL_TRADE_CONTRACT_SIZE); // Check Handle if(!PositionSelect(_Symbol)) { PrintFormat("PositionSelect(%s) failed. Error %d",_Symbol, GetLastError()); return; } ResetLastError(); long ticket=PositionGetInteger(POSITION_TICKET); //Check ticket if(ticket==0) { PrintFormat("Failed to get %s position ticket. Error %d", _Symbol, GetLastError()); return; } // Position info double EntryPrice = PositionGetDouble(POSITION_PRICE_OPEN); double Price = PositionGetDouble(POSITION_PRICE_OPEN); double StopLossLevel = PositionGetDouble(POSITION_SL); double LotSize = PositionGetDouble(POSITION_VOLUME); //Calculations double Spent = LotSize * ContractSize; double Distance = MathAbs(Price - StopLossLevel); double PositionSlLossValueInCurrencyBaseValue = -(Spent * Distance); Print("EntryPrice:", EntryPrice); Print("StopLossLevel:", StopLossLevel); Print("Spent:", Spent); Print("PositionSlLossValueInCurrencyBaseValue:", PositionSlLossValueInCurrencyBaseValue); } }
问题分析
现有代码的核心缺陷:
- 计算出的
PositionSlLossValueInCurrencyBaseValue是交易品种基准货币的亏损额,而非账户本位币 - 仅当交易品种的基准货币与账户本位币一致(或通过USD间接关联)时结果看似正确,但交叉盘下基准货币与账户本位币无直接关联,缺少汇率转换步骤
改进思路与修正代码
要实现账户本位币的准确计算,需添加基准货币到账户本位币的汇率转换逻辑,步骤如下:
- 获取账户本位币
- 区分多空方向计算止损与入场价的点数差
- 优先用MT5内置接口获取已转换为账户本位币的点值,失败则手动计算交叉汇率
- 最终计算账户本位币的止损亏损额
修正后的代码:
#property copyright "Gerald Mann (P. Ghasemi)" #property version "1.01" void OnTick() { if (PositionsTotal() == 0) return; // 1. 获取账户与品种基础信息 string accountCurrency = AccountInfoString(ACCOUNT_CURRENCY); string symbol = _Symbol; string baseCurrency = SymbolInfoString(symbol, SYMBOL_CURRENCY_BASE); double contractSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_CONTRACT_SIZE); double point = SymbolInfoDouble(symbol, SYMBOL_POINT); // 2. 验证持仓有效性 if(!PositionSelect(symbol)) { PrintFormat("PositionSelect(%s) failed. Error %d", symbol, GetLastError()); return; } long ticket = PositionGetInteger(POSITION_TICKET); if(ticket == 0) { PrintFormat("Failed to get %s position ticket. Error %d", symbol, GetLastError()); return; } // 3. 获取持仓核心数据 double entryPrice = PositionGetDouble(POSITION_PRICE_OPEN); double stopLoss = PositionGetDouble(POSITION_SL); double lotSize = PositionGetDouble(POSITION_VOLUME); ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); // 4. 计算止损点数差(区分多空方向) double pointDistance = 0.0; if(posType == POSITION_TYPE_BUY) { pointDistance = MathMax(0, entryPrice - stopLoss) / point; } else if(posType == POSITION_TYPE_SELL) { pointDistance = MathMax(0, stopLoss - entryPrice) / point; } if(pointDistance == 0) { Print("Stop loss not set or invalid."); return; } // 5. 计算每手每点的账户本位币价值 double perLotPerPointValue = SymbolInfoDouble(symbol, SYMBOL_POINT_VALUE); // 内置接口失败时手动计算汇率转换 if(perLotPerPointValue == 0) { string conversionSymbol = baseCurrency + accountCurrency; if(!SymbolSelect(conversionSymbol, true)) { // 尝试反向货币对 conversionSymbol = accountCurrency + baseCurrency; if(!SymbolSelect(conversionSymbol, true)) { PrintFormat("Failed to find conversion symbol between %s and %s", baseCurrency, accountCurrency); return; } perLotPerPointValue = (contractSize * point) / SymbolInfoDouble(conversionSymbol, SYMBOL_BID); } else { perLotPerPointValue = contractSize * point * SymbolInfoDouble(conversionSymbol, SYMBOL_BID); } } // 6. 计算账户本位币的止损亏损额 double accountLoss = -(lotSize * pointDistance * perLotPerPointValue); // 输出结果 Print("Entry Price: ", entryPrice); Print("Stop Loss: ", stopLoss); Print("Lot Size: ", lotSize); Print("Point Distance: ", pointDistance); Print("Account Currency Loss: ", accountLoss); }
关键优化点
- 区分多空方向计算点数差,避免反向止损的错误计算
- 优先使用MT5内置的
SYMBOL_POINT_VALUE,保证点值转换的准确性 - 内置接口失败时自动尝试直接/反向货币对获取交叉汇率,覆盖所有币种组合
- 增加止损有效性判断,避免无止损时的无效计算
内容的提问来源于stack exchange,提问作者Peiman Ghasemi
相关产品推荐
相关产品推荐

