//+------------------------------------------------------------------+ //| CribMarketEA.mq5 | //| Copyright 2025, MQL Development | //| https://www.mqldevelopment.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2025, MQL Development" #property link "https://www.mqldevelopment.com/" #property version "1.00" #include CTrade trade; input string Settings = " ------------- General Settings ------------- "; //_ input int magicNo = 333; // Magic no input double lotSize = 0.1; // Lot Size input bool enableBasketTP = false; // Enable Basket TP input double basketTakeProfit = 150.0; // Basket Take Profit string goldPairs[]; int totalGoldPairs = 0; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- trade.SetExpertMagicNumber(magicNo); trade.SetDeviationInPoints(10); trade.SetTypeFilling(ORDER_FILLING_IOC); trade.LogLevel(LOG_LEVEL_ALL); trade.SetAsyncMode(false); getGoldPairsFromMarketWatch(); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- if(enableBasketTP == true) { checkBasketTakeProfit(); } string symbolToBuy = getSymbolWithLowestAsk(); string symbolToSell = getSymbolWithHighestBid(); if(noOfActiveOrdersOfType(POSITION_TYPE_BUY) == 0) { if(symbolToBuy != NULL) { placeBuyTrade(symbolToBuy); } } if(noOfActiveOrdersOfType(POSITION_TYPE_SELL) == 0) { if(symbolToSell != NULL) { placeSellTrade(symbolToSell); } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool newBar() { static datetime lastbar; datetime curbar = iTime(Symbol(), PERIOD_CURRENT, 0); if(lastbar != curbar) { lastbar = curbar; Print(" ---------------------- New Bar :: ---------------------- ",lastbar); return (true); } else { return (false); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void placeBuyTrade(string symbol) { double ask = SymbolInfoDouble(symbol, SYMBOL_ASK); double buySL = 0, buyTP = 0; if(trade.PositionOpen(symbol, ORDER_TYPE_BUY, lotSize, ask, buySL, buyTP, "Buy Trade Placed")) { Print("Buy Trade Placed on ", symbol, ": ", trade.ResultOrder()); } else { Print("Error in placing Buy on ", symbol, ": ", GetLastError()); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void placeSellTrade(string symbol) { double bid = SymbolInfoDouble(symbol, SYMBOL_BID); double sellSL = 0, sellTP = 0; if(trade.PositionOpen(symbol, ORDER_TYPE_SELL, lotSize, bid, sellSL, sellTP, "Sell Trade Placed")) { Print("Sell Trade Placed on ", symbol, ": ", trade.ResultOrder()); } else { Print("Error in placing Sell on ", symbol, ": ", GetLastError()); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void getGoldPairsFromMarketWatch() { int totalSymbols = SymbolsTotal(true); ArrayResize(goldPairs, 0); totalGoldPairs = 0; for(int i = 0; i < totalSymbols; i++) { string symbolName = SymbolName(i, true); if(StringFind(symbolName, "GOLD") != -1 || StringFind(symbolName, "XAU") != -1) { ArrayResize(goldPairs, totalGoldPairs + 1); if(totalGoldPairs < ArraySize(goldPairs)) { goldPairs[totalGoldPairs] = symbolName; totalGoldPairs++; } else { Print("Error: Array resize failed for symbol ", symbolName); } } } Print("Found ", totalGoldPairs, " gold pairs in Market Watch"); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ string getSymbolWithLowestAsk() { if(totalGoldPairs == 0) return NULL; string lowestSymbol = ""; double lowestAsk = SymbolInfoDouble(lowestSymbol, SYMBOL_ASK); for(int i = 0; i < totalGoldPairs; i++) { double currentAsk = SymbolInfoDouble(goldPairs[i], SYMBOL_ASK); if(currentAsk < lowestAsk) { lowestAsk = currentAsk; lowestSymbol = goldPairs[i]; } } //Print("Lowest Ask Pair: ", lowestSymbol, " Lowest Ask: ", lowestAsk); return lowestSymbol; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ string getSymbolWithHighestBid() { if(totalGoldPairs == 0) return NULL; string highestSymbol = ""; double highestBid = SymbolInfoDouble(highestSymbol, SYMBOL_BID); for(int i = 0; i < totalGoldPairs; i++) { double currentBid = SymbolInfoDouble(goldPairs[i], SYMBOL_BID); if(currentBid > highestBid) { highestBid = currentBid; highestSymbol = goldPairs[i]; } } //Print("Highest Bid Pair: ", highestSymbol, " Highest Bid: ", highestBid); return highestSymbol; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int noOfActiveOrdersOfType(ENUM_POSITION_TYPE type) { int count = 0; for(int i= PositionsTotal()-1; i>=0; i--) { ulong ticket = PositionGetTicket(i); if(PositionSelectByTicket(ticket)) { if(PositionGetInteger(POSITION_MAGIC) == magicNo && (PositionGetInteger(POSITION_TYPE) == type) && isGoldPair(PositionGetString(POSITION_SYMBOL))) { count++; } } } return count; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void checkBasketTakeProfit() { double netProfit = 0; for(int i = PositionsTotal() - 1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(PositionSelectByTicket(ticket)) { if(isGoldPair(PositionGetString(POSITION_SYMBOL)) && PositionGetInteger(POSITION_MAGIC) == magicNo) { netProfit += PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_SWAP); } } } if(netProfit >= basketTakeProfit) { Print("Basket TP hit: Closing all trades. Profit = ", netProfit); closeAllActiveOrders(); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void closeAllActiveOrders() { for(int i=PositionsTotal()-1; i >=0 ; i--) { ulong ticket = PositionGetTicket(i); if(PositionSelectByTicket(ticket)) { if(PositionGetInteger(POSITION_MAGIC) == magicNo && isGoldPair(PositionGetString(POSITION_SYMBOL))) { if(trade.PositionClose(ticket)) { Print("Position closed ", ticket); } else { Print("Cannot close order: ",GetLastError()); } } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool isGoldPair(string symbol) { for(int i = 0; i < totalGoldPairs; i++) { //Print("Total Gold pairs: ", totalGoldPairs, " Array: ", goldPairs[i], " Symbol: ", symbol); if(goldPairs[i] == symbol) return true; } return false; } //+------------------------------------------------------------------+