diff --git a/MQLTestWorkspace/BKPS/eqm.tools.mq5 b/MQLTestWorkspace/BKPS/eqm.tools.mq5 new file mode 100644 index 0000000..c0aba13 --- /dev/null +++ b/MQLTestWorkspace/BKPS/eqm.tools.mq5 @@ -0,0 +1,346 @@ + + // + // POSITIONPACK ... + + // + // Check a Position Pack is Ready for Hedging ... + bool IsReadyForEQMHedge(XPositionPack &pack) + { + // + bool result = false; + + // + if (mMinProfitPerTrade <= 0 || + mMinProfitPerVolumeFactor <= 0) + { + return result; + } + + // + if (pack.supportPositionsCount <= 0) + { + return result; + } + + // + double profit = pack.position.profit; + double requiredProfit = + ((pack.position.volume / mMinProfitPerVolumeFactor) * + mMinProfitPerTrade) + + (-1 * pack.position.swap); + + // + for (int i = 0; i < pack.supportPositionsCount; i++) + { + // + XPosition iPosition = pack.supportPositions[i]; + + // + profit += iPosition.profit; + requiredProfit += + ((iPosition.volume / mMinProfitPerVolumeFactor) * + mMinProfitPerTrade) + + (-1 * iPosition.swap); + } + + // + result = profit >= requiredProfit; + + // + return result; + } + + // + // POSITIONMANAGEMENT ... + // + + // + // Manage Positions ... + void HandlePositionManagement() + { + // + // HandleHedgePositionPacks(); + + // + // HandleHedgePositions(); + + // + // HandleCloseOrTrailStopMinProfitPositions(); + } + + // + void HandleHedgePositions() + { + // + bool isReady = IsPositionsReadyForEQMHedge(); + if (!isReady) + { + return; + } + + // + XPosition positions[]; + int positionsCount = GetPositions(positions); + + // + string comment = "EQM Hedge Positions ..."; + + // + int closed = mTrader.ClosePositions( + positions, + comment); + bool isClosed = closed == positionsCount; + if (isClosed) + { + // + LogMessage(comment); + } + } + + // + // Close a Position Pack Wen Reached to Specific Profit ... + void HandleHedgePositionPacks() + { + // + XPosition positions[]; + int positionsCount = GetPositions(positions); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + XPositionPack iPack; + bool hasPack = mTrader.GetPositionPack( + iPosition.ticket, + iPosition.symbol, + iPosition.period, + iPack); + if (!hasPack) + { + continue; + } + + // + // Check Pack for Open Positions ... + bool isValidPack = iPack.supportPositionsCount > 0; + if (!isValidPack) + { + continue; + } + + // + // we sure a Position has Support and it's support open ... + bool isReady = IsReadyForEQMHedge(iPack); + if (!isReady) + { + continue; + } + + // + bool isClosed = HandleClosePack(iPack); + } + } + + // + // Try to Trail StopLoss or Close Posititons + // when reached Min Profit ... + void HandleCloseOrTrailStopMinProfitPositions() + { + // + // Retrieve In Profit Positions ... + XPosition positions[]; + int positionsCount = GetInProfitPositions(positions); + if (positionsCount <= 0) + { + return; + } + + // + for (int i = 0; i < positionsCount; i++) + { + // + XPosition iPosition = positions[i]; + + // + // Now we have to Calculate min Profit ... + double requiredProfit = + ((iPosition.volume / mMinProfitPerVolumeFactor) * + mMinProfitPerTrade) + + (-1 * iPosition.swap); + + // + // Now we Have to Check if Trailed Before or not ... + int trailLevel = ExtractSLTrailLevel(iPosition.comment); + if (trailLevel > 0) + { + requiredProfit *= (trailLevel + 1); + } + + // + // Check Can Trail or Close on Min Profit ... + bool conditionsPassed = iPosition.profit >= requiredProfit; + if (!conditionsPassed) + { + continue; + } + + // + // Now we have Sure iPosition is Ready for Trailing Stop or Close on Min Profit ... + bool isLong = IsLong(iPosition.type); + + // + // CASE A try to Trail Stop ... + double sl = 0; + double distance = 0; + if ((isLong && (iPosition.price > iPosition.entry && + iPosition.entry > iPosition.sl)) || + (!isLong && (iPosition.price < iPosition.entry && + iPosition.entry < iPosition.sl))) + { + // + // First Trail ... + + // + distance = isLong + ? iPosition.price - iPosition.entry + : iPosition.entry - iPosition.price; + + // + sl = iPosition.entry; + } + else if ((isLong && (iPosition.price > iPosition.sl && + iPosition.entry <= iPosition.sl)) || + (!isLong && (iPosition.price < iPosition.sl && + iPosition.entry >= iPosition.sl))) + { + // + // Trailed Before ... + + // + distance = isLong + ? iPosition.price - iPosition.entry + : iPosition.entry - iPosition.price; + + // + sl = isLong + ? iPosition.sl + distance + : iPosition.sl - distance; + } + + // + // Check Main Selected Position is Support of another Position or not ... + string params[]; + bool isSupport = ExtractSupportParams( + iPosition.comment, + params); + + // + bool isTrailed = false; + bool canTrail = !isSupport && sl > 0 && distance > 0; + if (canTrail) + { + // + string comment = PrepareSLTrailComment(iPosition.comment); + + // + isTrailed = mTrader.Modify( + iPosition.ticket, + sl, + iPosition.tp); + } + if (isTrailed) + { + // + string message = "EQM Trail Position(" + ToString(iPosition.ticket) + ")'s Stop Loss ..."; + + // + LogMessage(message); + + // + continue; + } + + // + // CASE B if not Trail, Close it in Min Profit ... + string comment = "EQM Close Min Profit ..."; + + // + // Check Position has Pack Or Not ... + // if has Pack must Close Pack ... + // if not, Close position itself ... + XPositionPack iPack; + bool hasPack = mTrader.GetPositionPack( + iPosition.ticket, + iPosition.symbol, + iPosition.period, + iPack); + if (hasPack) + { + // + HandleClosePack(iPack); + } + else + { + // + if (!isSupport) + { + // + bool isClosed = mTrader.Close( + iPosition.ticket, + comment); + if (isClosed) + { + // + string message = "EQM Close Position(" + ToString(iPosition.ticket) + ") In Min Profit: " + ToString(iPosition.profit); + + // + LogMessage(message); + } + } + } + } + } + + // + // Check Positions is Ready fro Hedging ... + bool IsPositionsReadyForEQMHedge() + { + // + bool result = false; + + // + if (mMinProfitPerTrade <= 0 || + mMinProfitPerVolumeFactor <= 0) + { + return result; + } + + // + double profit = 0; + double requiredProfit = 0; + + // + XPosition positions[]; + int positionsCount = GetPositions(positions); + if (positionsCount <= 1) + { + return result; + } + + // + profit = CalculatePositionsProfit(positions); + requiredProfit = CalculateRequiredProfitForHedge(positions); + + // + result = profit >= requiredProfit; + + // + return result; + }