Ingen beskrivning

vol_shield_v5.mq5 127KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598
  1. //+------------------------------------------------------------------+
  2. //| vol_hedge_strategy_mt5.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.20"
  9. #define MaxOrders 100
  10. #include <Trade\Trade.mqh>
  11. CTrade trade;
  12. //+------------------------------------------------------------------+
  13. //| Expert initialization function |
  14. //+------------------------------------------------------------------+
  15. enum selectDay
  16. {
  17. prev, // Previous Day
  18. curr, // Current Day
  19. };
  20. struct new_trade_store
  21. {
  22. ulong buy_ticket; // Buy Ticket
  23. ulong sell_ticket; // Sell Ticket
  24. string symbol; // Symbol
  25. double price; // Price
  26. double stop_loss_buy; // StopLoss Buy
  27. double take_profit_buy; // TakeProfit Buy
  28. double stop_loss_sell; // StopLoss Sell
  29. double take_profit_sell; // TakeProfit Sell
  30. datetime start_time; // Start time
  31. datetime end_time; // End Time
  32. bool demand_level_hit; // Demand Level Hit
  33. bool buy_hit_virtual_sl; // Buy Hit Virtual StopLoss
  34. bool sell_hit_virtual_sl; // Sell Hit Virtual StopLoss
  35. new_trade_store()
  36. {
  37. buy_ticket = -1;
  38. sell_ticket = -1;
  39. price = 0;
  40. demand_level_hit = false;
  41. buy_hit_virtual_sl = false;
  42. sell_hit_virtual_sl = false;
  43. }
  44. };
  45. new_trade_store newTradeStore[MaxOrders];
  46. enum lotcalculator
  47. {
  48. fix, //Fixed Lot Size
  49. rsk, //Risk in Percentage
  50. dollar, // Risk in Dollars
  51. };
  52. sinput string string_0 = "<><><><><><> General SETTINGS <><><><><><>"; //__
  53. input string tempString = "Enter your text"; // Preset Name
  54. input int magic_no = 333; // Magic no
  55. input bool useTpSlPips = false; // Use Relative Tp/Sl in Points
  56. input double stopLoss = 1000; // Fixed Stop Loss in Points
  57. input double takeProfit = 1000; // Fixed Take Profit in Points
  58. input bool bothHitsSl = false; // Enable Topped & Tailed Pre-Demand Level
  59. input bool hitDemandFirst = false; // Hit Demand First to Check Topped & Tailed
  60. input int maxTrades = 2; // Max Concurrent Trades
  61. input int maxSlippage = 5; // Max Slippage (Points)
  62. input bool enableSpreadFilter = false; // Enable Spread Filter
  63. input double maximumSpread = 10; // Maximum Spread (Points)
  64. input string tradeComment = "Trade Placed"; // Trade Comment Prefix
  65. input string dataFileName = "vol_hedge_data.csv"; // CSV File Name
  66. input string file_name = "data_store_file.csv";// Data Store File Name
  67. input bool enableDrawLevels = false; // Draw Levels
  68. input string string_0_2 = "<><><><><><> Trailing Setting<><><><><><>"; //__
  69. input bool indivial_trailing = false; // Indiviual Trailing
  70. input double ts_sl = 150; // Trailing Start in Points
  71. input double ts = 50; // Trailing Stop in Points
  72. input string strMA14 ="<><><><><><> BreakEven Settings <><><><><><>";//_
  73. input bool UseBreakEven = false; // Use Break Even
  74. input int breakEvenPoints = 150; // BreakEven Trigger Points
  75. input int breakStopPoint = 50; // BreakEven Above OpenPrice Points
  76. input string string_1 = "<><><><><><> Lot Management<><><><><><>"; //__
  77. input lotcalculator lot_calculator = fix; // Lot Size Option
  78. input double lot_amount = 0.1; // Lot Size
  79. input double risk = 0.5; // Risk in Percentage %
  80. input double dollars = 10; // Risk in GBP
  81. input string time_setting = "<><><><><> Time Filter Settings <><><><><>"; //_
  82. input bool enableTimeFilter = false; // Enable Time Filter
  83. input string startTime = "03:00"; // Start Time Session
  84. input string endTime = "09:00"; // End Time Session
  85. input string weekFilterSettings = "<><><><><> Week Filter Settings <><><><><>"; //_
  86. input bool enableWeekFilter = false; // Enable Week Filter (true/false)
  87. input int filterMonthNumber = 9; // Month number to apply week filter (1..12)
  88. input int filterWeekNumber = 2; // Week number of month to block (1..5)
  89. input string monthFilterSettings = "<><><><><> Month Filter Settings <><><><><>"; //_
  90. input bool allowJanuary = true; // Allow Trading in January
  91. input bool allowFebruary = true; // Allow Trading in February
  92. input bool allowMarch = true; // Allow Trading in March
  93. input bool allowApril = true; // Allow Trading in April
  94. input bool allowMay = true; // Allow Trading in May
  95. input bool allowJune = true; // Allow Trading in June
  96. input bool allowJuly = true; // Allow Trading in July
  97. input bool allowAugust = true; // Allow Trading in August
  98. input bool allowSeptember = true; // Allow Trading in September
  99. input bool allowOctober = true; // Allow Trading in October
  100. input bool allowNovember = true; // Allow Trading in November
  101. input bool allowDecember = true; // Allow Trading in December
  102. // Global Variables
  103. static double tickCurrentBid = 0;
  104. double tickPreviousBid = 0;
  105. static double tickCurrentAsk = 0;
  106. double tickPreviousAsk = 0;
  107. int newYorkStartTime = 0, newYorkStartMin = 0, newYorkEndHour = 0, newYorkEndMin = 0;
  108. datetime newYorkStartTrading = 0, newYorkEndTrading = 0;
  109. int GMT_Broker_Time = +2; // GMT_Broker_Time Time of your Broker
  110. int gmt = 0; // GMT_Broker_Time Time of your Broker
  111. double levelsAre[];
  112. selectDay newYorkSessionDay = curr; // Select Day for Start Time
  113. //+------------------------------------------------------------------+
  114. //| |
  115. //+------------------------------------------------------------------+
  116. int OnInit()
  117. {
  118. //---
  119. Print(" OnInIt. ");
  120. trade.SetExpertMagicNumber(magic_no);
  121. trade.SetDeviationInPoints(maxSlippage);
  122. trade.SetTypeFilling(ORDER_FILLING_IOC);
  123. trade.LogLevel(LOG_LEVEL_ALL);
  124. trade.SetAsyncMode(false);
  125. if(!MQLInfoInteger(MQL_TESTER))
  126. {
  127. loadNewTradeStoreFile();
  128. }
  129. int filehandle = FileOpen(dataFileName, FILE_READ | FILE_CSV | FILE_COMMON | FILE_ANSI);
  130. if(filehandle != INVALID_HANDLE)
  131. {
  132. Print(" Valid Handler. ");
  133. while(!FileIsEnding(filehandle))
  134. {
  135. string orderToRead = FileReadString(filehandle);
  136. string orderData[];
  137. //Print("Data: ", OrderToRead);
  138. StringSplit(orderToRead, StringGetCharacter(",",0), orderData);
  139. Print("Array Size: ", ArraySize(orderData));
  140. Print(" Order is: ", orderToRead);
  141. for(int i = 0 ; i < ArraySize(orderData) ; i++)
  142. {
  143. Print(" Order Data: ", orderData[i], " i: ", i);
  144. }
  145. if(ArraySize(orderData) >= 8)
  146. {
  147. if(orderData[0] == Symbol())
  148. {
  149. // store into local variables first (trim if needed)
  150. ulong buy_ticket_local = (ulong)-1; // keep -1 as per your convention
  151. ulong sell_ticket_local = (ulong)-1;
  152. string symbol_local = orderData[0];
  153. double price_local = StringToDouble(orderData[1]);
  154. double sl_buy_local = StringToDouble(orderData[2]);
  155. double tp_buy_local = StringToDouble(orderData[3]);
  156. double sl_sell_local = StringToDouble(orderData[4]);
  157. double tp_sell_local = StringToDouble(orderData[5]);
  158. // if your CSV has extra fields (tp2,tp3, etc.) parse here as needed
  159. datetime start_local = StringToTime(orderData[6]);
  160. datetime end_local = StringToTime(orderData[7]);
  161. if(orderData[6] == "0" || orderData[6] == NULL)
  162. {
  163. start_local = 0;
  164. }
  165. if(orderData[7] == "0" || orderData[7] == NULL)
  166. {
  167. end_local = 0;
  168. }
  169. ArrayResize(levelsAre,ArraySize(levelsAre)+1);
  170. levelsAre[ArraySize(levelsAre) - 1] = price_local;
  171. // OPTIONAL: only add when price == 0:
  172. // if(MathAbs(price_local) > 1e-9) { Print("Skipped: price != 0"); continue; }
  173. bool buy_virtual_tp_hit = true;
  174. bool sell_virtual_tp_hit = true;
  175. bool demand_level_hit_first = true;
  176. if(bothHitsSl)
  177. {
  178. buy_virtual_tp_hit = false;
  179. sell_virtual_tp_hit = false;
  180. if(hitDemandFirst)
  181. {
  182. demand_level_hit_first = false;
  183. }
  184. }
  185. // call the single-responsibility function that writes into struct array
  186. if(!level_present(price_local))
  187. {
  188. Print(" --------------- Price: ", price_local, " Start Time: ", start_local, " End Time: ", end_local, " --------------------");
  189. addToNewTradeStore(buy_ticket_local, sell_ticket_local,
  190. symbol_local, price_local,
  191. sl_buy_local, tp_buy_local,
  192. sl_sell_local, tp_sell_local,
  193. start_local, end_local,
  194. demand_level_hit_first, buy_virtual_tp_hit, sell_virtual_tp_hit);
  195. }
  196. else
  197. {
  198. Print("Level is already Present. Level: ", price_local);
  199. }
  200. }
  201. }
  202. }
  203. FileClose(filehandle);
  204. }
  205. else
  206. {
  207. Print(" InValid Handler. Error: ", GetLastError());
  208. }
  209. struct_level_check();
  210. print_newTradeStore();
  211. string time[];
  212. StringSplit(startTime,':',time);
  213. newYorkStartTime = (int)StringToInteger(time[0]);
  214. newYorkStartMin = (int)StringToInteger(time[1]);
  215. Print("NewYork Start Time Hour: ",newYorkStartTime," Start Time Min: ",newYorkStartMin);
  216. time[0] = "";
  217. time[1] = "";
  218. StringSplit(endTime,':',time);
  219. newYorkEndHour = (int)StringToInteger(time[0]);
  220. newYorkEndMin = (int)StringToInteger(time[1]);
  221. Print("NewYork End Time Hour: ",newYorkEndHour," End Time Min: ",newYorkEndMin);
  222. StringSplit(startTime,':',time);
  223. int newYorkStartHour = (int)StringToInteger(time[0]);
  224. newYorkStartMin = (int)StringToInteger(time[1]);
  225. EventSetMillisecondTimer(500);
  226. time[0] = "";
  227. time[1] = "";
  228. StringSplit(endTime,':',time);
  229. newYorkEndHour = (int)StringToInteger(time[0]);
  230. newYorkEndMin = (int)StringToInteger(time[1]);
  231. datetime startDateTime;
  232. MqlDateTime st;
  233. TimeCurrent(st); // get current date
  234. st.hour = newYorkStartHour;
  235. st.min = newYorkStartMin;
  236. st.sec = 0;
  237. startDateTime = StructToTime(st);
  238. datetime endDateTime;
  239. MqlDateTime et;
  240. TimeCurrent(et); // get current date
  241. et.hour = newYorkEndHour;
  242. et.min = newYorkEndMin;
  243. et.sec = 0;
  244. endDateTime = StructToTime(et);
  245. datetime start_Time = 0, end_Time = 0;
  246. if(startDateTime > endDateTime)
  247. {
  248. Print(" --------------------------- Previous -------------------------------------- ");
  249. newYorkSessionDay = prev;
  250. }
  251. else
  252. {
  253. Print(" --------------------------- Current -------------------------------------- ");
  254. newYorkSessionDay = curr;
  255. }
  256. timeFilter(true);
  257. int timeDifference = (int)TimeCurrent() - (int)TimeGMT();
  258. Print("Time Difference is: ", timeDifference);
  259. if(timeDifference > 0)
  260. {
  261. GMT_Broker_Time = (int)MathRound((double)timeDifference / 3600.0);
  262. }
  263. else
  264. if(timeDifference < 0)
  265. {
  266. GMT_Broker_Time = (int)MathRound((double)timeDifference / 3600.0);
  267. }
  268. else // timeDifference == 0
  269. {
  270. GMT_Broker_Time = 0;
  271. }
  272. Print("Gmt Time: ", TimeGMT(), " Broker Gmt Time: ", GMT_Broker_Time);
  273. gmt = GMT_Broker_Time;
  274. if(enableDrawLevels)
  275. {
  276. drawLevels();
  277. }
  278. //---
  279. return(INIT_SUCCEEDED);
  280. }
  281. //+------------------------------------------------------------------+
  282. //| Expert deinitialization function |
  283. //+------------------------------------------------------------------+
  284. void OnDeinit(const int reason)
  285. {
  286. //---
  287. ObjectsDeleteAll(0, 0, OBJ_HLINE);
  288. if(!MQLInfoInteger(MQL_TESTER))
  289. {
  290. saveNewTradeStoreFile();
  291. }
  292. }
  293. //+------------------------------------------------------------------+
  294. //| Expert tick function |
  295. //+------------------------------------------------------------------+
  296. void OnTick()
  297. {
  298. mainActivity();
  299. }
  300. //+------------------------------------------------------------------+
  301. //| |
  302. //+------------------------------------------------------------------+
  303. void mainActivity()
  304. {
  305. //---
  306. if(enableDrawLevels)
  307. {
  308. drawLevels();
  309. }
  310. newBar();
  311. if(indivial_trailing)
  312. {
  313. Individual_Trailing();
  314. }
  315. if(UseBreakEven)
  316. {
  317. breakEven();
  318. }
  319. double Bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
  320. double Ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
  321. if(tickPreviousBid == 0 && tickCurrentBid == 0)
  322. {
  323. tickPreviousBid = Bid;
  324. tickCurrentBid = Bid;
  325. }
  326. else
  327. {
  328. tickPreviousBid = tickCurrentBid;
  329. tickCurrentBid = Bid;
  330. }
  331. if(tickPreviousAsk == 0 && tickCurrentAsk == 0)
  332. {
  333. tickPreviousAsk = Ask;
  334. tickCurrentAsk = Ask;
  335. }
  336. else
  337. {
  338. tickPreviousAsk = tickCurrentAsk;
  339. tickCurrentAsk = Ask;
  340. }
  341. timeFilter(false);
  342. // Comment(" Session Start = ", newYorkStartTrading, " Asian Session End = ", newYorkEndTrading);
  343. if((enableTimeFilter && TimeCurrent() >= newYorkStartTrading && TimeCurrent() <= newYorkEndTrading) || !enableTimeFilter)
  344. {
  345. removeFromStructure();
  346. if(bothHitsSl)
  347. {
  348. virtualSLHitCheck();
  349. }
  350. tradePlacingCheck();
  351. }
  352. }
  353. //+------------------------------------------------------------------+
  354. //+------------------------------------------------------------------+
  355. //| |
  356. //+------------------------------------------------------------------+
  357. bool isTradingAllowedByWeek()
  358. {
  359. if(!enableWeekFilter) // filter disabled -> allow trading
  360. return true;
  361. // validate inputs quickly
  362. if(filterMonthNumber < 1 || filterMonthNumber > 12)
  363. {
  364. PrintFormat("⚠️ filterMonthNumber out of range (%d). Week filter disabled.", filterMonthNumber);
  365. return true;
  366. }
  367. if(filterWeekNumber < 1 || filterWeekNumber > 5)
  368. {
  369. PrintFormat("⚠️ filterWeekNumber out of range (%d). Week filter disabled.", filterWeekNumber);
  370. return true;
  371. }
  372. MqlDateTime t;
  373. TimeToStruct(TimeCurrent(), t); // t.mon (1..12), t.day (1..31)
  374. // if the months don't match, week filter doesn't apply -> allow
  375. if(t.mon != filterMonthNumber)
  376. return true;
  377. // compute week of month: days 1-7 -> week 1, 8-14 -> week 2, etc.
  378. int weekOfMonth = ((t.day - 1) / 7) + 1; // yields 1..5
  379. // if current week equals the filtered week -> block trading (return false)
  380. if(weekOfMonth == filterWeekNumber)
  381. {
  382. return false; // trading NOT allowed this week of the specified month
  383. }
  384. return true; // otherwise allow trading
  385. }
  386. //+------------------------------------------------------------------+
  387. //| |
  388. //+------------------------------------------------------------------+
  389. bool isTradingAllowedByMonth()
  390. {
  391. MqlDateTime t;
  392. TimeToStruct(TimeCurrent(), t);
  393. switch(t.mon)
  394. {
  395. case 1:
  396. return allowJanuary;
  397. case 2:
  398. return allowFebruary;
  399. case 3:
  400. return allowMarch;
  401. case 4:
  402. return allowApril;
  403. case 5:
  404. return allowMay;
  405. case 6:
  406. return allowJune;
  407. case 7:
  408. return allowJuly;
  409. case 8:
  410. return allowAugust;
  411. case 9:
  412. return allowSeptember;
  413. case 10:
  414. return allowOctober;
  415. case 11:
  416. return allowNovember;
  417. case 12:
  418. return allowDecember;
  419. default:
  420. return true; // Safe fallback: allow trading if month invalid
  421. }
  422. }
  423. //+------------------------------------------------------------------+
  424. //| |
  425. //+------------------------------------------------------------------+
  426. bool newBar()
  427. {
  428. static datetime lastbar;
  429. datetime curbar = iTime(Symbol(), PERIOD_CURRENT, 0);
  430. if(lastbar != curbar)
  431. {
  432. lastbar = curbar;
  433. Print(" ---------------------- New Bar :: ---------------------- ",lastbar);
  434. return (true);
  435. }
  436. else
  437. {
  438. return (false);
  439. }
  440. }
  441. //+------------------------------------------------------------------+
  442. //| |
  443. //+------------------------------------------------------------------+
  444. void closeTrades(int type,int magicno)
  445. {
  446. Print("Total order: ",OrdersTotal());
  447. for(int i= PositionsTotal()-1; i>=0; i--)
  448. {
  449. // Print(" Selection: ",OrderSelect(i,SELECT_BY_POS)," i: ",i," OrdersTotal(): ", OrdersTotal());
  450. ulong ticket = PositionGetTicket(i);
  451. if(PositionSelectByTicket(ticket))
  452. {
  453. if(PositionGetInteger(POSITION_TYPE) == type)
  454. {
  455. if(PositionGetInteger(POSITION_MAGIC) == magicno && PositionGetString(POSITION_SYMBOL) == Symbol())
  456. {
  457. //trade.PositionClose(PositionGetInteger(POSITION_TICKET))
  458. if(!trade.PositionClose(PositionGetInteger(POSITION_TICKET)))
  459. {Print("Problem in closing order order ",PositionGetInteger(POSITION_TICKET)); }
  460. else
  461. {
  462. Print("Order Closed by closeTrades() new filter",PositionGetInteger(POSITION_TICKET));
  463. }
  464. }
  465. }
  466. }
  467. }
  468. }
  469. //+------------------------------------------------------------------+
  470. //| |
  471. //+------------------------------------------------------------------+
  472. int orderCount_1(int type,int magic)
  473. {
  474. int count1=0;
  475. for(int i= PositionsTotal()-1; i>=0; i--)
  476. {
  477. // Print(" Selection: ",OrderSelect(i,SELECT_BY_POS)," i: ",i," OrdersTotal(): ", OrdersTotal());
  478. ulong ticket = PositionGetTicket(i);
  479. if(PositionSelectByTicket(ticket))
  480. {
  481. // if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY || PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
  482. if(PositionGetInteger(POSITION_MAGIC) == magic && PositionGetString(POSITION_SYMBOL) == Symbol())
  483. {
  484. //trade.PositionClose(PositionGetInteger(POSITION_TICKET))
  485. if(PositionGetInteger(POSITION_TYPE) == type)
  486. {
  487. count1++;
  488. }
  489. }
  490. }
  491. }
  492. return count1;
  493. }
  494. //+------------------------------------------------------------------+
  495. //| |
  496. //+------------------------------------------------------------------+
  497. int orderCount(int type)
  498. {
  499. int count = 0;
  500. for(int i= PositionsTotal()-1; i>=0; i--)
  501. {
  502. ulong ticket = PositionGetTicket(i);
  503. if(PositionSelectByTicket(ticket))
  504. {
  505. if(PositionGetInteger(POSITION_MAGIC) == magic_no && PositionGetString(POSITION_SYMBOL) == Symbol())
  506. {
  507. if(PositionGetInteger(POSITION_TYPE) == type)
  508. {
  509. count++;
  510. }
  511. }
  512. }
  513. }
  514. return count;
  515. }
  516. //+------------------------------------------------------------------+
  517. //| |
  518. //+------------------------------------------------------------------+
  519. bool level_present(double priceIs)
  520. {
  521. for(int i = 0 ; i < MaxOrders ; i++)
  522. {
  523. if(newTradeStore[i].price > 0)
  524. {
  525. if(priceIs == newTradeStore[i].price)
  526. {
  527. return true;
  528. }
  529. }
  530. }
  531. return false;
  532. }
  533. //+------------------------------------------------------------------+
  534. //| |
  535. //+------------------------------------------------------------------+
  536. void struct_level_check()
  537. {
  538. for(int i = 0; i < MaxOrders; i++)
  539. {
  540. if(newTradeStore[i].price > 0)
  541. {
  542. bool found = false;
  543. for(int j = 0; j < ArraySize(levelsAre); j++)
  544. {
  545. if(newTradeStore[i].price == levelsAre[j])
  546. {
  547. found = true;
  548. break;
  549. }
  550. }
  551. if(!found)
  552. {
  553. Print("Price not found in levelsAre[] -> index:", i, " | price:", newTradeStore[i].price);
  554. newTradeStore[i].buy_ticket = (ulong)-1;
  555. newTradeStore[i].sell_ticket = (ulong)-1;
  556. bool buy_virtual_tp_hit = true;
  557. bool sell_virtual_tp_hit = true;
  558. if(bothHitsSl)
  559. {
  560. buy_virtual_tp_hit = false;
  561. sell_virtual_tp_hit = false;
  562. }
  563. newTradeStore[i].buy_hit_virtual_sl = buy_virtual_tp_hit;
  564. newTradeStore[i].sell_hit_virtual_sl = sell_virtual_tp_hit;
  565. newTradeStore[i].symbol = "";
  566. newTradeStore[i].price = 0.0;
  567. newTradeStore[i].stop_loss_buy = 0.0;
  568. newTradeStore[i].take_profit_buy = 0.0;
  569. newTradeStore[i].stop_loss_sell = 0.0;
  570. newTradeStore[i].take_profit_sell = 0.0;
  571. newTradeStore[i].start_time = 0;
  572. newTradeStore[i].end_time = 0;
  573. return;
  574. }
  575. }
  576. }
  577. return;
  578. }
  579. //+------------------------------------------------------------------+
  580. //| |
  581. //+------------------------------------------------------------------+
  582. void print_newTradeStore()
  583. {
  584. bool anyPrinted = false;
  585. Print("=== newTradeStore DUMP ===");
  586. for(int i = 0; i < MaxOrders; i++)
  587. {
  588. // only print populated slots (price > 0)
  589. if(newTradeStore[i].price > 0.0)
  590. {
  591. anyPrinted = true;
  592. // convert booleans to readable text
  593. string buyHit = newTradeStore[i].buy_hit_virtual_sl ? "true" : "false";
  594. string sellHit = newTradeStore[i].sell_hit_virtual_sl ? "true" : "false";
  595. // header line for the entry
  596. Print("---- Entry ", i, " ----");
  597. // summary line (symbol, price, times)
  598. Print(" symbol:", newTradeStore[i].symbol,
  599. " | price:", DoubleToString(newTradeStore[i].price, Digits()),
  600. " | start:", IntegerToString(newTradeStore[i].start_time),
  601. " | end:", IntegerToString(newTradeStore[i].end_time));
  602. // ticket line
  603. Print(" tickets -> buy:", newTradeStore[i].buy_ticket,
  604. " | sell:", newTradeStore[i].sell_ticket);
  605. // flags line
  606. Print(" flags -> buy_hit_virtual_sl:", buyHit,
  607. " | sell_hit_virtual_sl:", sellHit,
  608. " | bothHitsSl:", (bothHitsSl ? "true" : "false"));
  609. // SL/TP line
  610. Print(" SL/TP -> buySL:", DoubleToString(newTradeStore[i].stop_loss_buy, Digits()),
  611. " | buyTP:", DoubleToString(newTradeStore[i].take_profit_buy, Digits()),
  612. " | sellSL:", DoubleToString(newTradeStore[i].stop_loss_sell, Digits()),
  613. " | sellTP:", DoubleToString(newTradeStore[i].take_profit_sell, Digits()));
  614. }
  615. }
  616. if(!anyPrinted)
  617. Print(" (no active newTradeStore entries found)");
  618. Print("=== end dump ===");
  619. }
  620. //+------------------------------------------------------------------+
  621. //| |
  622. //+------------------------------------------------------------------+
  623. void addToNewTradeStore(ulong r_buy_ticket, ulong r_sell_ticket,
  624. string r_symbol, double r_price,
  625. double r_stop_loss_buy, double r_take_profit_buy,
  626. double r_stop_loss_sell, double r_take_profit_sell,
  627. datetime r_start_time, datetime r_end_time, bool r_demand_level_hit, bool r_buy_hit_sl, bool r_sell_hit_sl)
  628. {
  629. Print(" Tier 1. ");
  630. for(int i = 0; i < MaxOrders; i++)
  631. {
  632. // treat slot as empty when both tickets are -1 (same convention as constructor)
  633. if(newTradeStore[i].buy_ticket == -1 && newTradeStore[i].sell_ticket == -1)
  634. {
  635. if(newTradeStore[i].price == 0)
  636. {
  637. newTradeStore[i].buy_ticket = r_buy_ticket;
  638. newTradeStore[i].sell_ticket = r_sell_ticket;
  639. newTradeStore[i].symbol = r_symbol;
  640. newTradeStore[i].price = r_price;
  641. newTradeStore[i].stop_loss_buy = r_stop_loss_buy;
  642. newTradeStore[i].take_profit_buy = r_take_profit_buy;
  643. newTradeStore[i].stop_loss_sell = r_stop_loss_sell;
  644. newTradeStore[i].take_profit_sell = r_take_profit_sell;
  645. newTradeStore[i].start_time = r_start_time;
  646. newTradeStore[i].end_time = r_end_time;
  647. newTradeStore[i].demand_level_hit = r_demand_level_hit;
  648. newTradeStore[i].buy_hit_virtual_sl = r_buy_hit_sl;
  649. newTradeStore[i].sell_hit_virtual_sl = r_sell_hit_sl;
  650. Print("Stored -> idx: ", i,
  651. " | Symbol: ", newTradeStore[i].symbol,
  652. " | price: ", DoubleToString(newTradeStore[i].price, Digits()),
  653. " | Sl Buy: ", DoubleToString(newTradeStore[i].stop_loss_buy, Digits()),
  654. " | Tp Buy: ", DoubleToString(newTradeStore[i].take_profit_buy, Digits()),
  655. "\n | Sl Sell: ", DoubleToString(newTradeStore[i].stop_loss_sell, Digits()),
  656. " | Tp Sell: ", DoubleToString(newTradeStore[i].take_profit_sell, Digits()),
  657. " | start: ", TimeToString(newTradeStore[i].start_time, TIME_DATE|TIME_SECONDS),
  658. " | end: ", TimeToString(newTradeStore[i].end_time, TIME_DATE|TIME_SECONDS),
  659. " | Demand Level Hit: ", newTradeStore[i].demand_level_hit,
  660. " | Buy Virtal Sl Hit: ", newTradeStore[i].buy_hit_virtual_sl,
  661. " | Sell Virtual Sl Hit: ", newTradeStore[i].sell_hit_virtual_sl);
  662. break;
  663. }
  664. }
  665. }
  666. }
  667. //+------------------------------------------------------------------+
  668. //| |
  669. //+------------------------------------------------------------------+
  670. void tradePlacingCheck()
  671. {
  672. for(int i = 0; i < MaxOrders; i++)
  673. {
  674. if(newTradeStore[i].buy_ticket == -1 && newTradeStore[i].sell_ticket == -1)
  675. {
  676. if(newTradeStore[i].price > 0)
  677. {
  678. if((TimeCurrent() > newTradeStore[i].start_time && TimeCurrent() < newTradeStore[i].end_time) || (newTradeStore[i].start_time == 0 || newTradeStore[i].end_time == 0))
  679. {
  680. if(newTradeStore[i].buy_hit_virtual_sl == true && newTradeStore[i].sell_hit_virtual_sl == true)
  681. {
  682. double levelPriceIs = newTradeStore[i].price;
  683. if((tickPreviousBid > levelPriceIs && tickCurrentBid < levelPriceIs) ||
  684. (tickPreviousBid < levelPriceIs && tickCurrentBid > levelPriceIs))
  685. {
  686. Print(" ------------------- Level Crossed. Level is: ", levelPriceIs, " -------------------- ");
  687. if(isTradingAllowedByWeek())
  688. {
  689. if(isTradingAllowedByMonth())
  690. {
  691. if((enableSpreadFilter && spreadFilter()) || !enableSpreadFilter)
  692. {
  693. ulong buyTicket = -1, sellTicket = -1;
  694. if(countLiveTrades() < maxTrades)
  695. {
  696. buyTicket = placeBuyTrade(newTradeStore[i].stop_loss_buy, newTradeStore[i].take_profit_buy);
  697. sellTicket = placeSellTrade(newTradeStore[i].stop_loss_sell, newTradeStore[i].take_profit_sell);
  698. newTradeStore[i].buy_ticket = buyTicket;
  699. newTradeStore[i].sell_ticket = sellTicket;
  700. }
  701. }
  702. }
  703. }
  704. }
  705. }
  706. }
  707. }
  708. }
  709. }
  710. }
  711. //+------------------------------------------------------------------+
  712. //| |
  713. //+------------------------------------------------------------------+
  714. void draw_lines(string name, datetime dateTime, double price, color selectColor, long lineStyle)
  715. {
  716. if(!ObjectCreate(0, name, OBJ_HLINE, 0, dateTime, price))
  717. {
  718. Print(" Error in creating ", name," : ","line: "," ",GetLastError());
  719. }
  720. else
  721. {
  722. ObjectSetInteger(0, name, OBJPROP_COLOR, selectColor);
  723. ObjectSetInteger(0, name, OBJPROP_STYLE, lineStyle);
  724. }
  725. }
  726. //+------------------------------------------------------------------+
  727. //| |
  728. //+------------------------------------------------------------------+
  729. void drawLevels()
  730. {
  731. for(int i = 0; i < MaxOrders; i++)
  732. {
  733. if(newTradeStore[i].price > 0)
  734. {
  735. if((TimeCurrent() > newTradeStore[i].start_time && TimeCurrent() < newTradeStore[i].end_time) || (newTradeStore[i].start_time == 0 || newTradeStore[i].end_time == 0))
  736. {
  737. if(ObjectFind(0, "level" + (string)newTradeStore[i].price) < 0)
  738. {
  739. draw_lines("level" + (string)newTradeStore[i].price, TimeCurrent(), newTradeStore[i].price, clrAqua, STYLE_SOLID);
  740. }
  741. }
  742. else
  743. {
  744. if(ObjectFind(0, "level" + (string)newTradeStore[i].price) >= 0)
  745. {
  746. ObjectDelete(0, "level" + (string)newTradeStore[i].price);
  747. }
  748. }
  749. }
  750. }
  751. }
  752. //+------------------------------------------------------------------+
  753. //| |
  754. //+------------------------------------------------------------------+
  755. ulong placeBuyTrade(double stoploss, double takeprofit)
  756. {
  757. double buySL = 0, buyTp=0;
  758. //openPrice = SymbolInfoDouble(Symbol(),SYMBOL_ASK);
  759. double Ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK);
  760. double Bid = SymbolInfoDouble(Symbol(),SYMBOL_BID);
  761. if(useTpSlPips)
  762. {
  763. if(stopLoss != 0)
  764. {
  765. buySL = Ask - (stopLoss * Point());
  766. }
  767. if(takeProfit != 0)
  768. {
  769. buyTp = Ask + (takeProfit * Point());
  770. }
  771. }
  772. else
  773. {
  774. if(stoploss > 0)
  775. {
  776. buySL = stoploss;
  777. }
  778. if(takeprofit > 0)
  779. {
  780. buyTp = takeprofit;
  781. }
  782. }
  783. double distance = MathAbs((Ask - buySL) / Point());
  784. if(trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,getLot(distance),Ask,buySL,buyTp,tradeComment+" Buy"))
  785. {
  786. Print("Buy Trade Placed: ",trade.ResultOrder());
  787. return trade.ResultOrder();
  788. }
  789. else
  790. {
  791. Print("Error in placing Buy: "+Symbol()+" ",GetLastError());
  792. return -1;
  793. }
  794. return -1;
  795. }
  796. //+------------------------------------------------------------------+
  797. //| |
  798. //+------------------------------------------------------------------+
  799. ulong placeSellTrade(double stoploss, double takeprofit)
  800. {
  801. double sellSL = 0, sellTp = 0;
  802. double Ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK);
  803. double Bid = SymbolInfoDouble(Symbol(),SYMBOL_BID);
  804. if(useTpSlPips)
  805. {
  806. if(stopLoss != 0)
  807. {
  808. sellSL = Bid + (stopLoss * Point());
  809. }
  810. if(takeProfit != 0)
  811. {
  812. sellTp = Bid - (takeProfit * Point());
  813. }
  814. }
  815. else
  816. {
  817. if(stoploss > 0)
  818. {
  819. sellSL = stoploss;
  820. }
  821. if(takeprofit > 0)
  822. {
  823. sellTp = takeprofit;
  824. }
  825. }
  826. double distance = MathAbs((Bid - sellSL) / Point());
  827. if(trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,getLot(distance),Bid,sellSL,sellTp,tradeComment+ " Sell"))
  828. {
  829. Print("Sell Trade PLaced: ",trade.ResultOrder());
  830. return trade.ResultOrder();
  831. }
  832. else
  833. {
  834. Print("Error in placing Sell: "+Symbol()+" ",GetLastError());
  835. return -1;
  836. }
  837. return -1;
  838. }
  839. //+------------------------------------------------------------------+
  840. //| |
  841. //+------------------------------------------------------------------+
  842. double getLot(double stop_loss)
  843. {
  844. Print("Tick Value: ",SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE));
  845. Print("Tick Size: ",SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE));
  846. double modeTickV=SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)
  847. ,modeTickS=SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE);
  848. // Print("Pip value: ", NormalizeDouble(((SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)/(SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE)/Point))*10),2));
  849. double pipvalue = NormalizeDouble(((SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)/(SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE)/Point()))*10),2);
  850. // pipvalue=NormalizeDouble((modeTickV/modeTickS/Point()),)
  851. // pipvalue=
  852. pipvalue = pipvalue / 10;
  853. double lotSize = lot_amount;
  854. if(lot_calculator == rsk || lot_calculator == dollar) //calculating risk
  855. {
  856. double riskamount = 0;
  857. if(lot_calculator == rsk)
  858. {
  859. riskamount = (risk/100)*AccountInfoDouble(ACCOUNT_BALANCE);
  860. }
  861. if(lot_calculator == dollar)
  862. {
  863. riskamount = dollars;
  864. }
  865. double pipvalue_required=riskamount/stop_loss;
  866. lotSize = pipvalue_required/pipvalue;
  867. //sl=riskamount/pipValuelot
  868. int roundDigit=0;
  869. double step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);
  870. while(step<1)
  871. {
  872. roundDigit++;
  873. step=step*10;
  874. }
  875. Print("Round Digits:",roundDigit);
  876. lotSize = NormalizeDouble(lotSize,roundDigit);
  877. //
  878. }
  879. Print(" Before Normalizing Lot Size By Step : ",lotSize);
  880. lotSize = NormalizeLot(lotSize,SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP));
  881. Print(" After Normalizing Lot Size By Step : ",lotSize);
  882. if(lotSize > SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX))
  883. {
  884. lotSize=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
  885. }
  886. else
  887. if(lotSize<SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN))
  888. {
  889. lotSize=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
  890. }
  891. //---
  892. return lotSize;
  893. }
  894. //+------------------------------------------------------------------+
  895. //| |
  896. //+------------------------------------------------------------------+
  897. double NormalizeLot(double lot, double step)
  898. {
  899. double steps = lot / step;
  900. double rounded_steps = MathRound(steps); // round to nearest whole step
  901. double rounded_lot = rounded_steps * step;
  902. return NormalizeDouble(rounded_lot, 2); // 2 decimals for safety
  903. }
  904. //+------------------------------------------------------------------+
  905. //| |
  906. //+------------------------------------------------------------------+
  907. void timeFilter(bool onInit)
  908. {
  909. MqlDateTime sdate,edate;
  910. datetime start_Time = 0, end_Time = 0;
  911. if(newYorkSessionDay == prev)
  912. {
  913. if(onInit)
  914. {
  915. start_Time = iTime(Symbol(),PERIOD_D1,1);
  916. end_Time = iTime(Symbol(),PERIOD_D1,0);
  917. }
  918. else
  919. {
  920. start_Time = newYorkStartTrading;
  921. end_Time = newYorkEndTrading;
  922. if(TimeCurrent() >= newYorkEndTrading && newYorkEndTrading != 0)
  923. {
  924. start_Time = iTime(Symbol(),PERIOD_D1,0);
  925. end_Time = start_Time + 86400;
  926. }
  927. }
  928. }
  929. else
  930. {
  931. start_Time = iTime(Symbol(),PERIOD_D1,0);
  932. end_Time = iTime(Symbol(),PERIOD_D1,0);
  933. }
  934. if(TimeToStruct(end_Time,edate))
  935. {
  936. edate.hour = newYorkEndHour;
  937. edate.min = newYorkEndMin;
  938. edate.sec = 0;
  939. }
  940. else
  941. Print("Error in Converting Time: ",GetLastError());
  942. newYorkEndTrading = StructToTime(edate);
  943. if(TimeToStruct(start_Time,sdate))
  944. {
  945. sdate.hour = newYorkStartTime;
  946. sdate.min = newYorkStartMin;
  947. sdate.sec = 0;
  948. }
  949. else
  950. Print("Error in Converting Time: ",GetLastError());
  951. newYorkStartTrading = StructToTime(sdate);
  952. // if(onInit)
  953. //Print("NewYork Start Time ",newYorkStartTrading,"End Date: ",newYorkEndTrading);
  954. //Print("Edate: ",edate.hour," ",edate.min," Sdate: ",sdate.hour," ",sdate.min);
  955. }
  956. //+------------------------------------------------------------------+
  957. //| |
  958. //+------------------------------------------------------------------+
  959. void removeFromStructure()
  960. {
  961. for(int i = 0 ; i < MaxOrders ; i++)
  962. {
  963. bool isBuyPresent=false, isSellPresent=false;
  964. if(newTradeStore[i].buy_ticket != -1 && newTradeStore[i].sell_ticket != -1)
  965. {
  966. for(int j = PositionsTotal()-1; j>=0; j--)
  967. {
  968. ulong ticket = PositionGetTicket(j);
  969. if(PositionSelectByTicket(ticket))
  970. {
  971. if(ticket == newTradeStore[i].buy_ticket)
  972. {
  973. isBuyPresent=true;
  974. }
  975. }
  976. }
  977. for(int j = PositionsTotal()-1; j>=0; j--)
  978. {
  979. ulong ticket = PositionGetTicket(j);
  980. if(PositionSelectByTicket(ticket))
  981. {
  982. if(ticket == newTradeStore[i].sell_ticket)
  983. {
  984. isSellPresent = true;
  985. }
  986. }
  987. }
  988. if(!isBuyPresent && !isSellPresent)
  989. {
  990. Print("Buy/Sell Ticket is closed so removed from struct. Buy Ticket: ", newTradeStore[i].buy_ticket, " Sell Ticket: ", newTradeStore[i].sell_ticket);
  991. newTradeStore[i].buy_ticket = (ulong)-1;
  992. newTradeStore[i].sell_ticket = (ulong)-1;
  993. bool buy_virtual_tp_hit = true;
  994. bool sell_virtual_tp_hit = true;
  995. bool demand_level_hit_value = true;
  996. if(bothHitsSl)
  997. {
  998. buy_virtual_tp_hit = false;
  999. sell_virtual_tp_hit = false;
  1000. demand_level_hit_value = false;
  1001. }
  1002. newTradeStore[i].buy_hit_virtual_sl = buy_virtual_tp_hit;
  1003. newTradeStore[i].sell_hit_virtual_sl = sell_virtual_tp_hit;
  1004. newTradeStore[i].demand_level_hit = demand_level_hit_value;
  1005. //newTradeStore[i].symbol = "";
  1006. //newTradeStore[i].price = 0.0;
  1007. //newTradeStore[i].stop_loss = 0.0;
  1008. //newTradeStore[i].take_profit = 0.0;
  1009. //newTradeStore[i].start_time = 0;
  1010. //newTradeStore[i].end_time = 0;
  1011. }
  1012. }
  1013. }
  1014. }
  1015. //+------------------------------------------------------------------+
  1016. //| |
  1017. //+------------------------------------------------------------------+
  1018. void virtualSLHitCheck()
  1019. {
  1020. for(int i = 0 ; i < MaxOrders ; i++)
  1021. {
  1022. if(newTradeStore[i].buy_ticket == -1 && newTradeStore[i].sell_ticket == -1)
  1023. {
  1024. if(TimeCurrent() > newTradeStore[i].start_time && TimeCurrent() < newTradeStore[i].end_time)
  1025. {
  1026. if(!newTradeStore[i].demand_level_hit)
  1027. {
  1028. double levelPriceIs = newTradeStore[i].price;
  1029. if((tickPreviousBid > levelPriceIs && tickCurrentBid < levelPriceIs) ||
  1030. (tickPreviousBid < levelPriceIs && tickCurrentBid > levelPriceIs))
  1031. {
  1032. newTradeStore[i].demand_level_hit = true;
  1033. Print(" Demand Level Hit. newTradeStore[i].demand_level_hit: ", newTradeStore[i].demand_level_hit, " Order Price is: ", newTradeStore[i].price, " Time Demand Hit is: ", TimeCurrent());
  1034. }
  1035. }
  1036. if(newTradeStore[i].demand_level_hit)
  1037. {
  1038. double buy_sl = 0, sell_sl = 0;
  1039. if(!useTpSlPips)
  1040. {
  1041. buy_sl = newTradeStore[i].stop_loss_buy;
  1042. sell_sl = newTradeStore[i].stop_loss_sell;
  1043. }
  1044. else
  1045. {
  1046. buy_sl = stopLoss != 0 ? newTradeStore[i].price - (stopLoss * Point()) : 0;
  1047. sell_sl = stopLoss != 0 ? newTradeStore[i].price + (stopLoss * Point()) : 0;
  1048. }
  1049. if(newTradeStore[i].buy_hit_virtual_sl == false)
  1050. {
  1051. if((tickPreviousBid > buy_sl && tickCurrentBid <= buy_sl))
  1052. {
  1053. newTradeStore[i].buy_hit_virtual_sl = true;
  1054. Print(" Buy Virtual Sl Hit. newTradeStore[i].buy_hit_virtual_sl: ", newTradeStore[i].buy_hit_virtual_sl, " Order Price is: ", newTradeStore[i].price, " Stop Loss Price is: ", buy_sl, " Time Virtual Sl Hit is: ", TimeCurrent());
  1055. }
  1056. }
  1057. if(newTradeStore[i].sell_hit_virtual_sl == false)
  1058. {
  1059. if((tickPreviousAsk < sell_sl && tickCurrentAsk >= sell_sl))
  1060. {
  1061. newTradeStore[i].sell_hit_virtual_sl = true;
  1062. Print(" Sell Virtual Sl Hit. newTradeStore[i].sell_hit_virtual_sl: ", newTradeStore[i].sell_hit_virtual_sl, " Order Price is: ", newTradeStore[i].price, " Stop Loss Price is: ", sell_sl, " Time Virtual Sl Hit is: ", TimeCurrent());
  1063. }
  1064. }
  1065. }
  1066. }
  1067. }
  1068. }
  1069. }
  1070. //+------------------------------------------------------------------+
  1071. //| |
  1072. //+------------------------------------------------------------------+
  1073. int countLiveTrades()
  1074. {
  1075. int count = 0;
  1076. for(int i = 0; i < PositionsTotal(); i++)
  1077. {
  1078. ulong ticket = PositionGetTicket(i);
  1079. if(PositionSelectByTicket(ticket))
  1080. {
  1081. if(PositionGetInteger(POSITION_MAGIC) == magic_no)
  1082. {
  1083. if(PositionGetString(POSITION_SYMBOL) == Symbol())
  1084. {
  1085. if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY || PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
  1086. {
  1087. count++;
  1088. }
  1089. }
  1090. }
  1091. }
  1092. }
  1093. return count;
  1094. }
  1095. //+------------------------------------------------------------------+
  1096. //| |
  1097. //+------------------------------------------------------------------+
  1098. bool spreadFilter()
  1099. {
  1100. long spreadIs = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD);
  1101. if(spreadIs > maximumSpread)
  1102. {
  1103. return false;
  1104. }
  1105. return true;
  1106. }
  1107. //+------------------------------------------------------------------+
  1108. //| |
  1109. //+------------------------------------------------------------------+
  1110. void breakEven()
  1111. {
  1112. for(int i = PositionsTotal()-1; i>=0; i--)
  1113. {
  1114. ulong ticket = PositionGetTicket(i);
  1115. string symbol=PositionGetSymbol(i);
  1116. double mySL = 0,newSL = 0;
  1117. double SymbolTickSize = SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE);
  1118. ////Print("ticket ",ticket," Symbol : ",symbol);
  1119. if(PositionSelectByTicket(ticket))
  1120. {
  1121. if(PositionGetString(POSITION_SYMBOL)==Symbol() && PositionGetInteger(POSITION_MAGIC) == magic_no)
  1122. {
  1123. if(isCounterpartOpen(ticket))
  1124. {
  1125. // counterpart still open -> skip trailing for this position
  1126. continue;
  1127. }
  1128. //========================================================Buy Condition=========================================================================
  1129. if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
  1130. {
  1131. mySL = PositionGetDouble(POSITION_PRICE_OPEN) + (breakEvenPoints * SymbolTickSize);
  1132. if(SymbolInfoDouble(Symbol(),SYMBOL_BID) >= mySL && PositionGetDouble(POSITION_PRICE_OPEN) > PositionGetDouble(POSITION_SL))
  1133. {
  1134. newSL= PositionGetDouble(POSITION_PRICE_OPEN) + (breakStopPoint * SymbolTickSize);
  1135. if(trade.PositionModify(ticket,newSL,PositionGetDouble(POSITION_TP)))
  1136. {
  1137. Print("Buy Order BreakEven Successfully ");
  1138. }
  1139. else
  1140. {
  1141. Print("Error in BreakEven Buy Position ",GetLastError());
  1142. }
  1143. }
  1144. }
  1145. //=======================================================Sell condition ===============================================================
  1146. if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
  1147. {
  1148. mySL = PositionGetDouble(POSITION_PRICE_OPEN) - (breakEvenPoints * SymbolTickSize);
  1149. if(SymbolInfoDouble(Symbol(),SYMBOL_ASK) <= mySL && PositionGetDouble(POSITION_SL) > PositionGetDouble(POSITION_PRICE_OPEN))
  1150. {
  1151. newSL = PositionGetDouble(POSITION_PRICE_OPEN) - (breakStopPoint * SymbolTickSize);
  1152. if(trade.PositionModify(ticket,newSL,PositionGetDouble(POSITION_TP)))
  1153. {
  1154. Print("Order Sell BreakEven Successfully ");
  1155. }
  1156. else
  1157. {
  1158. Print("Error in BreakEven Sell Position ",GetLastError());
  1159. }
  1160. }
  1161. }
  1162. }
  1163. }
  1164. }
  1165. }
  1166. //+------------------------------------------------------------------+
  1167. //| |
  1168. //+------------------------------------------------------------------+
  1169. bool isCounterpartOpen(ulong ticket)
  1170. {
  1171. // scan stored pairs
  1172. for(int k=0; k<MaxOrders; k++)
  1173. {
  1174. // check if this ticket is the buy side in the pair
  1175. if(newTradeStore[k].buy_ticket == ticket)
  1176. {
  1177. ulong other = newTradeStore[k].sell_ticket;
  1178. if(other <= 0)
  1179. return false; // no counterpart recorded -> treat as closed
  1180. // check if counterpart ticket exists in current positions
  1181. for(int p = PositionsTotal()-1; p >= 0; p--)
  1182. {
  1183. ulong t = PositionGetTicket(p);
  1184. if(t == other)
  1185. return true; // counterpart still open
  1186. }
  1187. return false; // counterpart not found -> closed
  1188. }
  1189. // check if this ticket is the sell side in the pair
  1190. if(newTradeStore[k].sell_ticket == ticket)
  1191. {
  1192. ulong other = newTradeStore[k].buy_ticket;
  1193. if(other <= 0)
  1194. return false; // no counterpart recorded -> treat as closed
  1195. for(int p = PositionsTotal()-1; p >= 0; p--)
  1196. {
  1197. ulong t = PositionGetTicket(p);
  1198. if(t == other)
  1199. return true; // counterpart still open
  1200. }
  1201. return false; // counterpart not found -> closed
  1202. }
  1203. }
  1204. // ticket not found in the stored pairs -> treat as no counterpart open
  1205. return false;
  1206. }
  1207. //+------------------------------------------------------------------+
  1208. //| |
  1209. //+------------------------------------------------------------------+
  1210. void Individual_Trailing()
  1211. {
  1212. int openedpositions;
  1213. double mySL,myResult;
  1214. openedpositions=PositionsTotal();
  1215. if((openedpositions>0))
  1216. {
  1217. int totalorders=PositionsTotal();
  1218. for(int i=0; i<totalorders; i++) // scan all orders and positions. ..
  1219. {
  1220. ulong ticket = PositionGetTicket(i);
  1221. if(PositionSelectByTicket(ticket))
  1222. {
  1223. if(PositionGetString(POSITION_SYMBOL)==Symbol() && PositionGetInteger(POSITION_MAGIC) == magic_no) // only look if mygrid and symbol. ..
  1224. {
  1225. if(isCounterpartOpen(ticket))
  1226. {
  1227. // counterpart still open -> skip trailing for this position
  1228. continue;
  1229. }
  1230. double SymbolAsk = SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_ASK);
  1231. double SymbolBid = SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_BID);
  1232. int SymbolDigits = (int)SymbolInfoInteger(PositionGetString(POSITION_SYMBOL), SYMBOL_DIGITS);
  1233. double SymbolTickSize = SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_TRADE_TICK_SIZE);
  1234. int type= (int)PositionGetInteger(POSITION_TYPE);
  1235. if(type==POSITION_TYPE_BUY) // its a long position
  1236. {
  1237. mySL=NormalizeDouble(SymbolAsk-(ts*SymbolTickSize),Digits()); // new SL
  1238. double startSl=PositionGetDouble(POSITION_PRICE_OPEN)+(ts_sl*SymbolTickSize);
  1239. if(PositionGetDouble(POSITION_SL) != mySL)
  1240. if(mySL>PositionGetDouble(POSITION_SL) && SymbolAsk>=startSl)
  1241. {
  1242. myResult=trade.PositionModify(ticket,mySL,PositionGetDouble(POSITION_TP)); //OrderModify(OrderTicket(),OrderOpenPrice(),mySL,OrderTakeProfit(),0,clrGreen);
  1243. if(!myResult)
  1244. {
  1245. Print(" Buy Trade Trailing Error: ",GetLastError());
  1246. }
  1247. }
  1248. }
  1249. if(type==POSITION_TYPE_SELL)
  1250. {
  1251. mySL=NormalizeDouble(SymbolBid+(ts*SymbolTickSize),Digits()); // new SL
  1252. double startSlSell=PositionGetDouble(POSITION_PRICE_OPEN)-(ts_sl*SymbolTickSize);
  1253. if(PositionGetDouble(POSITION_SL) != mySL)
  1254. if(((mySL<PositionGetDouble(POSITION_SL)) || (PositionGetDouble(POSITION_SL)<SymbolTickSize)) && SymbolBid<=startSlSell)
  1255. {
  1256. myResult=trade.PositionModify(ticket,mySL,PositionGetDouble(POSITION_TP)); //OrderModify(OrderTicket(),OrderOpenPrice(),mySL,OrderTakeProfit(),0,clrRed);
  1257. if(!myResult)
  1258. {
  1259. Print(" Sell Trade Trailing Error: ",GetLastError());
  1260. }
  1261. }
  1262. }
  1263. }
  1264. }
  1265. }
  1266. }
  1267. }
  1268. //+------------------------------------------------------------------+
  1269. //| |
  1270. //+------------------------------------------------------------------+
  1271. void saveNewTradeStoreFile()
  1272. {
  1273. // don't run in strategy tester
  1274. if(MQLInfoInteger(MQL_TESTER))
  1275. return;
  1276. int fileHandle = FileOpen(file_name,
  1277. FILE_WRITE | FILE_CSV | FILE_COMMON |
  1278. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_READ);
  1279. if(fileHandle == INVALID_HANDLE)
  1280. {
  1281. PrintFormat("saveNewTradeStoreFile() -> Cannot open file '%s'. Error: %d", file_name, GetLastError());
  1282. return;
  1283. }
  1284. // header (optional) - comment out if you don't want header
  1285. //string header = "buy_ticket,sell_ticket,symbol,price,stop_loss,take_profit,start_time,end_time,buy_hit_virtual_sl,sell_hit_virtual_sl\r\n";
  1286. //FileWriteString(fileHandle, header);
  1287. for(int i = 0; i < MaxOrders; i++)
  1288. {
  1289. // if(newTradeStore[i].buy_ticket != -1 && newTradeStore[i].sell_ticket != -1)
  1290. {
  1291. // decide whether this slot has useful data:
  1292. // you can tweak this condition as you prefer (symbol != "" is simple)
  1293. bool slotPopulated = (StringLen(newTradeStore[i].symbol) > 0)
  1294. || (newTradeStore[i].price != 0.0)
  1295. || (newTradeStore[i].start_time != 0);
  1296. if(!slotPopulated)
  1297. continue;
  1298. // convert values to strings
  1299. string buyTicketStr = IntegerToString((long)newTradeStore[i].buy_ticket);
  1300. string sellTicketStr = IntegerToString((long)newTradeStore[i].sell_ticket);
  1301. string priceStr = DoubleToString(newTradeStore[i].price, Digits());
  1302. string slBuyStr = DoubleToString(newTradeStore[i].stop_loss_buy, Digits());
  1303. string tpBuyStr = DoubleToString(newTradeStore[i].take_profit_buy, Digits());
  1304. string slSellStr = DoubleToString(newTradeStore[i].stop_loss_sell, Digits());
  1305. string tpSellStr = DoubleToString(newTradeStore[i].take_profit_sell, Digits());
  1306. string startTimeStr = (newTradeStore[i].start_time != 0) ? TimeToString(newTradeStore[i].start_time, TIME_DATE|TIME_SECONDS) : "";
  1307. string endTimeStr = (newTradeStore[i].end_time != 0) ? TimeToString(newTradeStore[i].end_time, TIME_DATE|TIME_SECONDS) : "";
  1308. string buyHitStr = ""; // IntegerToString(newTradeStore[i].buy_hit_virtual_sl ? 1 : 0);
  1309. string sellHitStr = ""; // IntegerToString(newTradeStore[i].sell_hit_virtual_sl ? 1 : 0);
  1310. string demandHitStr = "";
  1311. if(newTradeStore[i].buy_hit_virtual_sl == true)
  1312. {
  1313. buyHitStr = "true";
  1314. }
  1315. else
  1316. {
  1317. buyHitStr = "false";
  1318. }
  1319. if(newTradeStore[i].sell_hit_virtual_sl == true)
  1320. {
  1321. sellHitStr = "true";
  1322. }
  1323. else
  1324. {
  1325. sellHitStr = "false";
  1326. }
  1327. if(newTradeStore[i].demand_level_hit == true)
  1328. {
  1329. demandHitStr = "true";
  1330. }
  1331. else
  1332. {
  1333. demandHitStr = "false";
  1334. }
  1335. // build CSV line and write
  1336. string line = buyTicketStr + "," + sellTicketStr + "," +
  1337. newTradeStore[i].symbol + "," +
  1338. priceStr + "," + slBuyStr + "," + tpBuyStr + "," +
  1339. slSellStr + "," + tpSellStr + "," +
  1340. startTimeStr + "," + endTimeStr + "," +
  1341. demandHitStr + "," + buyHitStr + "," + sellHitStr + "\r\n";
  1342. FileWriteString(fileHandle, line);
  1343. }
  1344. }
  1345. FileClose(fileHandle);
  1346. PrintFormat("saveNewTradeStoreFile() -> saved to '%s'.", file_name);
  1347. }
  1348. //+------------------------------------------------------------------+
  1349. //| |
  1350. //+------------------------------------------------------------------+
  1351. void loadNewTradeStoreFile()
  1352. {
  1353. if(MQLInfoInteger(MQL_TESTER))
  1354. return;
  1355. int fileHandle = FileOpen(file_name,
  1356. FILE_READ | FILE_CSV | FILE_COMMON |
  1357. FILE_SHARE_READ | FILE_SHARE_WRITE);
  1358. if(fileHandle == INVALID_HANDLE)
  1359. {
  1360. Print("loadNewTradeStoreFile() -> Cannot open file '", file_name, "'. Error: ", GetLastError());
  1361. return;
  1362. }
  1363. // reset defaults
  1364. for(int j = 0; j < MaxOrders; j++)
  1365. {
  1366. newTradeStore[j].buy_ticket = (ulong)-1;
  1367. newTradeStore[j].sell_ticket = (ulong)-1;
  1368. newTradeStore[j].symbol = "";
  1369. newTradeStore[j].price = 0.0;
  1370. newTradeStore[j].stop_loss_buy = 0.0;
  1371. newTradeStore[j].take_profit_buy = 0.0;
  1372. newTradeStore[j].stop_loss_sell = 0.0;
  1373. newTradeStore[j].take_profit_sell = 0.0;
  1374. newTradeStore[j].start_time = 0;
  1375. newTradeStore[j].end_time = 0;
  1376. newTradeStore[j].demand_level_hit = false;
  1377. newTradeStore[j].buy_hit_virtual_sl = false;
  1378. newTradeStore[j].sell_hit_virtual_sl = false;
  1379. }
  1380. int idx = 0;
  1381. while(!FileIsEnding(fileHandle) && idx < MaxOrders)
  1382. {
  1383. string line = FileReadString(fileHandle);
  1384. if(StringLen(line) == 0)
  1385. continue;
  1386. string tokens[];
  1387. int total = StringSplit(line, ',', tokens);
  1388. if(total >= 13)
  1389. {
  1390. // if((ulong)tokens[0] != -1 && (ulong)tokens[1] != -1)
  1391. {
  1392. newTradeStore[idx].buy_ticket = (ulong)tokens[0];
  1393. newTradeStore[idx].sell_ticket = (ulong)tokens[1];
  1394. newTradeStore[idx].symbol = tokens[2];
  1395. newTradeStore[idx].price = StringToDouble(tokens[3]);
  1396. newTradeStore[idx].stop_loss_buy = StringToDouble(tokens[4]);
  1397. newTradeStore[idx].take_profit_buy = StringToDouble(tokens[5]);
  1398. newTradeStore[idx].stop_loss_sell = StringToDouble(tokens[6]);
  1399. newTradeStore[idx].take_profit_sell = StringToDouble(tokens[7]);
  1400. string sStart = tokens[8];
  1401. string sEnd = tokens[9];
  1402. newTradeStore[idx].start_time = (StringLen(sStart) > 0) ? StringToTime(sStart) : 0;
  1403. newTradeStore[idx].end_time = (StringLen(sEnd) > 0) ? StringToTime(sEnd) : 0;
  1404. bool bHit = false;
  1405. bool sHit = false;
  1406. bool dHit = false;
  1407. if(tokens[10] == "true")
  1408. {
  1409. dHit = true;
  1410. }
  1411. else
  1412. {
  1413. dHit = false;
  1414. }
  1415. if(tokens[11] == "true")
  1416. {
  1417. bHit = true;
  1418. }
  1419. else
  1420. {
  1421. bHit = false;
  1422. }
  1423. if(tokens[12] == "true")
  1424. {
  1425. sHit = true;
  1426. }
  1427. else
  1428. {
  1429. sHit = false;
  1430. }
  1431. if(bothHitsSl == false)
  1432. {
  1433. newTradeStore[idx].buy_hit_virtual_sl = true;
  1434. newTradeStore[idx].sell_hit_virtual_sl = true;
  1435. newTradeStore[idx].demand_level_hit = true;
  1436. }
  1437. if(bothHitsSl == true)
  1438. {
  1439. newTradeStore[idx].buy_hit_virtual_sl = bHit;
  1440. newTradeStore[idx].sell_hit_virtual_sl = sHit;
  1441. if(hitDemandFirst)
  1442. {
  1443. newTradeStore[idx].demand_level_hit = dHit;
  1444. }
  1445. else
  1446. {
  1447. newTradeStore[idx].demand_level_hit = true;
  1448. }
  1449. }
  1450. // --- simple Print instead of PrintFormat ---
  1451. Print(
  1452. "Loaded newTradeStore[", idx, "]:",
  1453. " buy_ticket=", newTradeStore[idx].buy_ticket,
  1454. " sell_ticket=", newTradeStore[idx].sell_ticket,
  1455. " symbol=", newTradeStore[idx].symbol,
  1456. " price=", DoubleToString(newTradeStore[idx].price, Digits()),
  1457. " \n sl buy=", DoubleToString(newTradeStore[idx].stop_loss_buy, Digits()),
  1458. " tp buy=", DoubleToString(newTradeStore[idx].take_profit_buy, Digits()),
  1459. " sl sell=", DoubleToString(newTradeStore[idx].stop_loss_sell, Digits()),
  1460. " tp sell=", DoubleToString(newTradeStore[idx].take_profit_sell, Digits()),
  1461. " start=", (newTradeStore[idx].start_time != 0 ? TimeToString(newTradeStore[idx].start_time, TIME_DATE|TIME_SECONDS) : ""),
  1462. " end=", (newTradeStore[idx].end_time != 0 ? TimeToString(newTradeStore[idx].end_time, TIME_DATE|TIME_SECONDS) : ""),
  1463. " demandHit=", newTradeStore[idx].demand_level_hit,
  1464. " buyHit=", newTradeStore[idx].buy_hit_virtual_sl,
  1465. " sellHit=", newTradeStore[idx].sell_hit_virtual_sl
  1466. );
  1467. idx++;
  1468. }
  1469. }
  1470. else
  1471. {
  1472. Print("loadNewTradeStoreFile(): skipping malformed line (tokens=", total, "): ", line);
  1473. }
  1474. }
  1475. FileClose(fileHandle);
  1476. Print("loadNewTradeStoreFile() -> loaded ", idx, " entries from '", file_name, "'.");
  1477. }
  1478. //+------------------------------------------------------------------+
  1479. //| |
  1480. //+------------------------------------------------------------------+
  1481. //+------------------------------------------------------------------+