Ei kuvausta

CribMarketEAV2.mq5 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. //+------------------------------------------------------------------+
  2. //| CribMarketEA.mq5 |
  3. //| Copyright 2025, MQL Development |
  4. //| https://www.mqldevelopment.com/ |
  5. //+------------------------------------------------------------------+
  6. #property copyright "Copyright 2025, MQL Development"
  7. #property link "https://www.mqldevelopment.com/"
  8. #property version "1.00"
  9. #include <Trade\Trade.mqh>
  10. CTrade trade;
  11. #define MaxOrders 10000
  12. struct new_trade_store
  13. {
  14. ulong buyTicket; // Buy Ticket
  15. ulong sellTicket; // Sell Ticket
  16. string buySymbol; // Buy Symbol Name
  17. string sellSymbol; // Sell Symbol Name
  18. new_trade_store()
  19. {
  20. buyTicket = -1;
  21. sellTicket = -1;
  22. }
  23. };
  24. new_trade_store newTradeStore[MaxOrders];
  25. input string Settings = " ------------- General Settings ------------- "; //_
  26. input int magicNo = 333; // Magic no
  27. input double lotSize = 0.01; // Lot Size
  28. input bool enableBasketTP = true; // Enable Basket TP
  29. input double basketTakeProfit = 1.0; // Basket Take Profit
  30. input int maxOpenPositions = 3; // Maximum number of open positions
  31. string goldPairs[];
  32. int totalGoldPairs = 0;
  33. //+------------------------------------------------------------------+
  34. //| Expert initialization function |
  35. //+------------------------------------------------------------------+
  36. int OnInit()
  37. {
  38. //---
  39. trade.SetExpertMagicNumber(magicNo);
  40. trade.SetDeviationInPoints(10);
  41. trade.SetTypeFilling(ORDER_FILLING_IOC);
  42. trade.LogLevel(LOG_LEVEL_ALL);
  43. trade.SetAsyncMode(false);
  44. getSymbolsFromMarketWatch();
  45. // if(enableBasketTP == true)
  46. // {
  47. // checkBasketTakeProfit();
  48. // }
  49. //
  50. // string symbolToBuy = getSymbolWithLowestAsk();
  51. // string symbolToSell = getSymbolWithHighestBid();
  52. ////Print(" Symbol to Buy is: ", symbolToBuy, " Symbol to Sell: ", symbolToSell);
  53. //
  54. // if(noOfActiveOrdersOfType(POSITION_TYPE_BUY) < maxOpenPositions)
  55. // {
  56. // if(symbolToBuy != NULL && symbolToBuy != "")
  57. // {
  58. // placeBuyTrade(symbolToBuy);
  59. // }
  60. // }
  61. //
  62. // if(noOfActiveOrdersOfType(POSITION_TYPE_SELL) < maxOpenPositions)
  63. // {
  64. // if(symbolToSell != NULL && symbolToSell != "")
  65. // {
  66. // placeSellTrade(symbolToSell);
  67. // }
  68. // }
  69. //--- create timer
  70. EventSetMillisecondTimer(1000);
  71. //---
  72. return(INIT_SUCCEEDED);
  73. }
  74. //+------------------------------------------------------------------+
  75. //| Expert deinitialization function |
  76. //+------------------------------------------------------------------+
  77. void OnDeinit(const int reason)
  78. {
  79. //---
  80. EventKillTimer();
  81. }
  82. //+------------------------------------------------------------------+
  83. //| Expert tick function |
  84. //+------------------------------------------------------------------+
  85. void OnTick()
  86. {
  87. //---
  88. }
  89. //+------------------------------------------------------------------+
  90. //| |
  91. //+------------------------------------------------------------------+
  92. void OnTimer()
  93. {
  94. //---
  95. removeFromStruct();
  96. if(enableBasketTP == true)
  97. {
  98. checkBasketTakeProfit();
  99. }
  100. string symbolToBuy = getSymbolWithLowestAsk();
  101. string symbolToSell = getSymbolWithHighestBid();
  102. //Print(" Symbol to Buy is: ", symbolToBuy, " Symbol to Sell: ", symbolToSell);
  103. if(noOfActiveOrdersOfType(POSITION_TYPE_BUY) < maxOpenPositions)
  104. {
  105. if(symbolToBuy != NULL && symbolToBuy != "")
  106. {
  107. placeBuyTrade(symbolToBuy);
  108. }
  109. }
  110. if(noOfActiveOrdersOfType(POSITION_TYPE_SELL) < maxOpenPositions)
  111. {
  112. if(symbolToSell != NULL && symbolToSell != "")
  113. {
  114. placeSellTrade(symbolToSell);
  115. }
  116. }
  117. }
  118. //+------------------------------------------------------------------+
  119. //| |
  120. //+------------------------------------------------------------------+
  121. bool newBar()
  122. {
  123. static datetime lastbar;
  124. datetime curbar = iTime(Symbol(), PERIOD_CURRENT, 0);
  125. if(lastbar != curbar)
  126. {
  127. lastbar = curbar;
  128. Print(" ---------------------- New Bar :: ---------------------- ",lastbar);
  129. return (true);
  130. }
  131. else
  132. {
  133. return (false);
  134. }
  135. }
  136. //+------------------------------------------------------------------+
  137. //| |
  138. //+------------------------------------------------------------------+
  139. void placeBuyTrade(string symbol)
  140. {
  141. double ask = SymbolInfoDouble(symbol, SYMBOL_ASK);
  142. double buySL = 0, buyTP = 0;
  143. if(trade.PositionOpen(symbol, ORDER_TYPE_BUY, lotSize, ask, buySL, buyTP, "Buy Trade Placed"))
  144. {
  145. Print("Buy Trade Placed on ", symbol, ": ", trade.ResultOrder());
  146. }
  147. else
  148. {
  149. Print("Error in placing Buy on ", symbol, ": ", GetLastError());
  150. }
  151. }
  152. //+------------------------------------------------------------------+
  153. //| |
  154. //+------------------------------------------------------------------+
  155. void placeSellTrade(string symbol)
  156. {
  157. double bid = SymbolInfoDouble(symbol, SYMBOL_BID);
  158. double sellSL = 0, sellTP = 0;
  159. if(trade.PositionOpen(symbol, ORDER_TYPE_SELL, lotSize, bid, sellSL, sellTP, "Sell Trade Placed"))
  160. {
  161. Print("Sell Trade Placed on ", symbol, ": ", trade.ResultOrder());
  162. }
  163. else
  164. {
  165. Print("Error in placing Sell on ", symbol, ": ", GetLastError());
  166. }
  167. }
  168. //+------------------------------------------------------------------+
  169. //| |
  170. //+------------------------------------------------------------------+
  171. void getSymbolsFromMarketWatch()
  172. {
  173. int totalSymbols = SymbolsTotal(true);
  174. ArrayResize(goldPairs, 0);
  175. totalGoldPairs = 0;
  176. for(int i = 0; i < totalSymbols; i++)
  177. {
  178. string symbolName = SymbolName(i, true);
  179. //if(StringFind(symbolName, "GOLD") != -1 || StringFind(symbolName, "XAU") != -1)
  180. {
  181. ArrayResize(goldPairs, totalGoldPairs + 1);
  182. if(totalGoldPairs < ArraySize(goldPairs))
  183. {
  184. goldPairs[totalGoldPairs] = symbolName;
  185. totalGoldPairs++;
  186. }
  187. else
  188. {
  189. Print("Error: Array resize failed for symbol ", symbolName);
  190. }
  191. }
  192. }
  193. Print("Found ", totalGoldPairs, " Symbol pairs in Market Watch");
  194. }
  195. //+------------------------------------------------------------------+
  196. //| |
  197. //+------------------------------------------------------------------+
  198. string getSymbolWithLowestAsk()
  199. {
  200. if(totalGoldPairs == 0)
  201. return NULL;
  202. string lowestSymbol = "";
  203. //double lowestAsk = INT_MAX; // SymbolInfoDouble(lowestSymbol, SYMBOL_ASK);
  204. double lowestAsk = DBL_MAX;
  205. for(int i = 0; i < totalGoldPairs; i++)
  206. {
  207. double currentAsk = SymbolInfoDouble(goldPairs[i], SYMBOL_ASK);
  208. Print("Pair:",goldPairs[i]," Price Ask:",currentAsk);
  209. if(currentAsk < lowestAsk)
  210. {
  211. lowestAsk = currentAsk;
  212. lowestSymbol = goldPairs[i];
  213. }
  214. }
  215. Print("Lowest Ask Pair: ", lowestSymbol, " Lowest Ask: ", lowestAsk);
  216. return lowestSymbol;
  217. }
  218. //+------------------------------------------------------------------+
  219. //| |
  220. //+------------------------------------------------------------------+
  221. string getSymbolWithHighestBid()
  222. {
  223. if(totalGoldPairs == 0)
  224. return NULL;
  225. string highestSymbol = "";
  226. //double highestBid = INT_MIN; // SymbolInfoDouble(highestSymbol, SYMBOL_BID);
  227. double highestBid = 0;
  228. for(int i = 0; i < totalGoldPairs; i++)
  229. {
  230. double currentBid = SymbolInfoDouble(goldPairs[i], SYMBOL_BID);
  231. Print("Pair:",goldPairs[i]," Price Bid:",currentBid);
  232. if(currentBid > highestBid)
  233. {
  234. highestBid = currentBid;
  235. highestSymbol = goldPairs[i];
  236. }
  237. }
  238. Print("Highest Bid Pair: ", highestSymbol, " Highest Bid: ", highestBid);
  239. return highestSymbol;
  240. }
  241. //+------------------------------------------------------------------+
  242. //| |
  243. //+------------------------------------------------------------------+
  244. int noOfActiveOrdersOfType(ENUM_POSITION_TYPE type)
  245. {
  246. int count = 0;
  247. for(int i= PositionsTotal()-1; i>=0; i--)
  248. {
  249. ulong ticket = PositionGetTicket(i);
  250. if(PositionSelectByTicket(ticket))
  251. {
  252. if(PositionGetInteger(POSITION_MAGIC) == magicNo
  253. && (PositionGetInteger(POSITION_TYPE) == type)
  254. && isGoldPair(PositionGetString(POSITION_SYMBOL)))
  255. {
  256. count++;
  257. }
  258. }
  259. }
  260. return count;
  261. }
  262. //+------------------------------------------------------------------+
  263. //| |
  264. //+------------------------------------------------------------------+
  265. void checkBasketTakeProfit()
  266. {
  267. double netProfit = 0;
  268. for(int i = PositionsTotal() - 1; i >= 0; i--)
  269. {
  270. ulong ticket = PositionGetTicket(i);
  271. if(PositionSelectByTicket(ticket))
  272. {
  273. if(isGoldPair(PositionGetString(POSITION_SYMBOL)) &&
  274. PositionGetInteger(POSITION_MAGIC) == magicNo)
  275. {
  276. netProfit += PositionGetDouble(POSITION_PROFIT)+PositionGetDouble(POSITION_SWAP);
  277. }
  278. }
  279. }
  280. if(netProfit >= basketTakeProfit)
  281. {
  282. Print("Basket TP hit: Closing all trades. Profit = ", netProfit);
  283. closeAllActiveOrders();
  284. }
  285. }
  286. //+------------------------------------------------------------------+
  287. //| |
  288. //+------------------------------------------------------------------+
  289. void closeAllActiveOrders()
  290. {
  291. for(int i=PositionsTotal()-1; i >=0 ; i--)
  292. {
  293. ulong ticket = PositionGetTicket(i);
  294. if(PositionSelectByTicket(ticket))
  295. {
  296. if(PositionGetInteger(POSITION_MAGIC) == magicNo &&
  297. isGoldPair(PositionGetString(POSITION_SYMBOL)))
  298. {
  299. if(trade.PositionClose(ticket))
  300. {
  301. Print("Position closed ", ticket);
  302. }
  303. else
  304. {
  305. Print("Cannot close order: ",GetLastError());
  306. }
  307. }
  308. }
  309. }
  310. }
  311. //+------------------------------------------------------------------+
  312. //| |
  313. //+------------------------------------------------------------------+
  314. bool isGoldPair(string symbol)
  315. {
  316. for(int i = 0; i < totalGoldPairs; i++)
  317. {
  318. //Print("Total Gold pairs: ", totalGoldPairs, " Array: ", goldPairs[i], " Symbol: ", symbol);
  319. if(goldPairs[i] == symbol)
  320. return true;
  321. }
  322. return false;
  323. }
  324. //+------------------------------------------------------------------+
  325. //| |
  326. //+------------------------------------------------------------------+
  327. void addToStructure(ulong r_buyTicket,ulong r_sellTicket, string r_buySymbol, string r_sellSymbol)
  328. {
  329. for(int i=0; i<MaxOrders; i++)
  330. {
  331. if(newTradeStore[i].buyTicket==-1 && newTradeStore[i].sellTicket==-1)
  332. {
  333. newTradeStore[i].buyTicket = r_buyTicket;
  334. newTradeStore[i].sellTicket = r_sellTicket;
  335. newTradeStore[i].buySymbol = r_buySymbol;
  336. newTradeStore[i].sellSymbol = r_sellSymbol;
  337. Print("Stored new ticket in structure. Buy Ticket: ", newTradeStore[i].buyTicket, " Sell Ticket: ", newTradeStore[i].sellTicket,
  338. " Buy Symbol: ", newTradeStore[i].buySymbol, " Sell Symbol: ", newTradeStore[i].sellSymbol);
  339. break;
  340. }
  341. }
  342. }
  343. //+------------------------------------------------------------------+
  344. //| |
  345. //+------------------------------------------------------------------+
  346. void removeFromStruct()
  347. {
  348. for(int i = 0 ; i < MaxOrders ; i++)
  349. {
  350. bool buyPresent = false;
  351. bool sellPresent = false;
  352. if(newTradeStore[i].buyTicket !=-1 || newTradeStore[i].sellTicket !=-1)
  353. {
  354. for(int j = PositionsTotal()-1; j>=0; j--)
  355. {
  356. ulong ticket = PositionGetTicket(j);
  357. if(PositionSelectByTicket(ticket))
  358. {
  359. if(ticket == newTradeStore[i].buyTicket)
  360. {
  361. buyPresent = true;
  362. }
  363. if(ticket == newTradeStore[i].sellTicket)
  364. {
  365. sellPresent = true;
  366. }
  367. }
  368. }
  369. for(int j = OrdersTotal()-1; j>=0; j--)
  370. {
  371. ulong ticket = OrderGetTicket(j);
  372. if(OrderSelect(ticket))
  373. {
  374. if(ticket == newTradeStore[i].buyTicket)
  375. {
  376. buyPresent = true;
  377. }
  378. if(ticket == newTradeStore[i].sellTicket)
  379. {
  380. sellPresent = true;
  381. }
  382. }
  383. }
  384. if(!buyPresent)
  385. {
  386. Print("Buy ticket closed: ", newTradeStore[i].buyTicket);
  387. newTradeStore[i].buyTicket = -1;
  388. newTradeStore[i].buySymbol = "";
  389. }
  390. if(!sellPresent)
  391. {
  392. Print("Sell ticket closed: ", newTradeStore[i].sellTicket);
  393. newTradeStore[i].sellTicket = -1;
  394. newTradeStore[i].sellSymbol = "";
  395. }
  396. }
  397. }
  398. }
  399. //+------------------------------------------------------------------+
  400. //| |
  401. //+------------------------------------------------------------------+
  402. //+------------------------------------------------------------------+