void M_SM_WAIT_FVG_INVERTED_LONG() { bool BuyTakeout = stGVL.CurrentLiquidity - stGVL.Candle[0].low > stGVL.fMaxDiffTakeOut_Price && stGVL.eCurrentDirection == DIR_LONG && stGVL.fMaxDiffTakeOut_Price!=0; int LiquCrossIndex = iBarShift(_Symbol, _Period, stGVL.dtCurrentLiquidity_Time); MqlTick tick; SymbolInfoTick(_Symbol, tick); double CurrentEntryPrice = tick.ask; // ------------------------------------------------------------------------------------------------------------------------------------------------- // Takeout if(BuyTakeout) { string Message = "Buy-Liquidity got taken out " + DoubleToString(stGVL.CurrentLiquidity - stGVL.Candle[0].low); M_LogWarning(Message); stGVL.nStateMachine = SM_RESET; } // ------------------------------------------------------------------------------------------------------------------------------------------------- // Too many candles formed between Liquidity cross and entry // - 1 because the index is calced on the bar 0 (current, not closed) but we always use bar 1 (last closed bar) for calulations like cross of liquidity else if((LiquCrossIndex + 1 > nMaxCandlesLiquEntry && nMaxCandlesLiquEntry != 0) || LiquCrossIndex > 99) { string Message = "Too many candles between Liquidity cross and entry, LiquCrossIndex=" + IntegerToString(LiquCrossIndex); M_LogWarning(Message); stGVL.nStateMachine = SM_RESET; } // ------------------------------------------------------------------------------------------------------------------------------------------------- // Wigs in opposite direction else if(M_CheckWigsLastCandles(stGVL.eCurrentDirection,LiquCrossIndex) && bNoWigsInOppositeDir) { M_LogWarning("Wigs in the wrong direction detected"); stGVL.nStateMachine = SM_RESET; } // ------------------------------------------------------------------------------------------------------------------------------------------------- else if(stGVL.Candle[1].close > stGVL.LastFVGTop) // FVG got inverted { stGVL.BodyStopLoss = 0; // Reset Stoploss before searching a new one for(int i = 1; i <= LiquCrossIndex; i++) // Search for the Stoploss at the minimum body between now and liquidity cross { if(stGVL.Candle[i].close < stGVL.BodyStopLoss || stGVL.BodyStopLoss == 0) { stGVL.BodyStopLoss = stGVL.Candle[i].close; } } if(CurrentEntryPrice - stGVL.BodyStopLoss > stGVL.fMaxStopLossSize_Price && stGVL.fMaxStopLossSize_Price != 0) // Stoploss size too big { M_LogWarning("Stoploss too big, Bodystoploss=" + DoubleToString(stGVL.BodyStopLoss) + " Price=" + DoubleToString(stGVL.Candle[1].close)); stGVL.nStateMachine = SM_RESET; } else if(!M_RSIBuyAllowed(LiquCrossIndex)) // RSI filter { stGVL.nStateMachine = SM_RESET; } else if(!M_EMABuyAllowed(true)) // EMA filter { stGVL.nStateMachine = SM_RESET; } else if(!M_SpreadOK()) // Spread filter { stGVL.nStateMachine = SM_RESET; } else if(CurrentEntryPrice - stGVL.LastFVGTop > stGVL.fMaxDiffFVGEntry_Price && stGVL.fMaxDiffFVGEntry_Price!=0) { M_LogWarning("Difference FVG and Entry to big, Entry=" + DoubleToString(CurrentEntryPrice) + " FVG Top=" + DoubleToString(stGVL.LastFVGTop)); stGVL.nStateMachine = SM_RESET; } else { if(CurrentEntryPrice - stGVL.BodyStopLoss < stGVL.fMinStopLossSize_Price && stGVL.fMinStopLossSize_Price != 0) { stGVL.StopLoss = CurrentEntryPrice - stGVL.fMinStopLossSize_Price; } else { stGVL.StopLoss = stGVL.BodyStopLoss; } stGVL.Entry = CurrentEntryPrice; stGVL.TakeProfit = stGVL.Entry + (stGVL.Entry - stGVL.StopLoss) * fRiskReward; stGVL.nNumberOfPositions = 1; int SLInPoints = (stGVL.Entry - stGVL.StopLoss) / SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE); double fLot1 = M_CalculateLotSize(fRiskPerTrade, SLInPoints, 100, ORDER_TYPE_BUY); double fLot2 = 0; if(bRunnerPosition) { fLot2 = M_CalculateLotSize(fRiskPerTrade, SLInPoints, fPercentageRunner, ORDER_TYPE_BUY); fLot1 = M_CalculateLotSize(fRiskPerTrade, SLInPoints, (100 - fPercentageRunner), ORDER_TYPE_BUY); stGVL.nNumberOfPositions = stGVL.nNumberOfPositions + 1; } // Enter tradex Trade.Buy(fLot1, _Symbol, 0, stGVL.StopLoss, stGVL.TakeProfit, "Buy"); M_LogInfo("Long entered with Lot " + DoubleToString(fLot1) + " Entry=" + DoubleToString(stGVL.Entry) + " Stoploss=" + DoubleToString(stGVL.StopLoss) + " Takeprofit=" + DoubleToString(stGVL.TakeProfit)); if(bRunnerPosition && bEMAActive) { Trade.Buy(fLot2, _Symbol, 0, stGVL.StopLoss, 0, "Buy"); M_LogInfo("Long entered with Lot " + DoubleToString(fLot2) + " Entry=" + DoubleToString(stGVL.Entry) + " Stoploss=" + DoubleToString(stGVL.StopLoss) + " Takeprofit=0 -> runner position"); } stGVL.nNumberOfTrades = stGVL.nNumberOfTrades + 1; stGVL.CurrentLiquidity = 0; stGVL.dtCurrentLiquidity_Time = 0; stGVL.nStateMachine = SM_IN_TRADE; } } }