暂无描述

CribMarketEAV2.mq5 15KB

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