Без опису

Pulse EA.mq5 128KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843
  1. //+------------------------------------------------------------------+
  2. //| Pulse_EA_project_MT5.mq5 |
  3. //| Copyright 2024, MQL Development |
  4. //| https://www.mqldevelopment.com/ |
  5. //+------------------------------------------------------------------+
  6. #property copyright "Copyright 2024, MQL Development"
  7. #property link "https://www.mqldevelopment.com/"
  8. #property version "1.00"
  9. #include <Trade\Trade.mqh>
  10. CTrade trade;
  11. #define global "var"
  12. #define MaxOrders 10000
  13. struct new_trade_store
  14. {
  15. int trade_ticket;
  16. int trade_type;
  17. int trade_magic_no;
  18. double trade_open_price;
  19. double trade_close_price;
  20. datetime trade_open_time;
  21. datetime trade_close_time;
  22. double trade_sl;
  23. double trade_tp;
  24. double trade_lot;
  25. double trade_profit;
  26. new_trade_store()
  27. {
  28. trade_ticket = -1;
  29. trade_type = -1;
  30. trade_magic_no = -1;
  31. trade_open_price = -1;
  32. trade_close_price = -1;
  33. trade_open_time = -1;
  34. trade_close_time = -1;
  35. trade_sl = -1;
  36. trade_tp = -1;
  37. trade_lot = -1;
  38. trade_profit = -1;
  39. }
  40. };
  41. new_trade_store od[MaxOrders];
  42. struct trade_sync
  43. {
  44. ulong sim_trade_ticket;
  45. ulong live_trade_ticket;
  46. trade_sync()
  47. {
  48. sim_trade_ticket = -1;
  49. live_trade_ticket = -1;
  50. }
  51. };
  52. trade_sync od_sync[MaxOrders];
  53. enum trade_typ
  54. {
  55. buy, // Buy
  56. reverse, // Reverse
  57. };
  58. enum EA_TYPE
  59. {
  60. Tally_Sim, // Tally Sim
  61. Tally_Trade, // Tally Trade
  62. };
  63. input string gnrlsettings = " ================ General Settings =================== ";//_
  64. input EA_TYPE eaType = Tally_Sim; // EA Option
  65. input double tpPips = 20; // Tp Pips
  66. input double slPips = 20; // SL Pips
  67. input double lot = 0.1; // Lot Size
  68. input string gnrlesettings = " ================ Tally Sim Settings =================== ";//_
  69. trade_typ ordTyp = buy; // Order Type (Tally Sim)
  70. input int magicNo = 123; // Magic #
  71. input string fileName = "TradeDataFile"; // File Name (Tally Sim)
  72. input string grlesettings = " ================ Tally Trade Settings =================== ";//_
  73. input trade_typ tradesDirection = buy; // Order Type (Tally Trade)
  74. input int magicNo1 = 1; // Copy Trade Magic #
  75. input bool CopyTallyTrade = true; // Enable Copy Trade
  76. input double glTp = 20; // Copy Take Profit
  77. input double glSl = 10; // Copy Stop Loss
  78. input bool useMovingAVG = true; // Use moving average filter
  79. input string Settings6 = "------------- Display Settings -------------"; //_
  80. input int tradeLineThickness = 2; // Trade Line Thickness
  81. input int dollarFontSize = 10; // Dollar Text Font Size
  82. input color dollarFontColor = clrAqua; // Dollar Text Font Colour
  83. input string horizontalLineName = "close"; // Horizontal Line Name
  84. input string Settings5 = "------------- Time Filter Settings -------------"; //_
  85. input bool enableTimeFilter = false; // Enable Time Filter
  86. input string startTime = "22:00"; // Start Time
  87. input string endTime = "01:00"; // End Time
  88. input bool useFridayClose = false; // Use Friday Close
  89. input string closeFriday = "23:00"; // Friday Close Time
  90. input bool useMondayOpen = false; // Use Monday Open
  91. input string mondayOpen = "01:00"; // Monday Open Time
  92. input string Settings25 = "------------- Daily Draw Limit Settings -------------"; //_
  93. input bool UseDailyDrawdownLimit = true; // Enable Daily Draw Down
  94. input double DailyDrawdownAmount = 2000; // $2000 limit
  95. input string DrawdownResetTime = "05:00"; // Enable Trading At
  96. input string indSettings = " ================ Indicator Settings =================== ";//_
  97. input color Dot_Color = clrOrangeRed;
  98. input double StartingBalance = 10000;
  99. input string MagicNumbers = "123";
  100. input int MA_Period = 5;
  101. input ENUM_MA_METHOD MA_Method = MODE_SMA;
  102. input string fileName1 = "TradeDataFile"; // File Name
  103. input int historyTrades = 50;
  104. bool tpSlHit = false;
  105. static int ticketAssigner = 1;
  106. int handler;
  107. double bufferData[];
  108. ushort u_sep; // The code of the separator character
  109. string sep = ":"; // A separator as a character
  110. string result1[];
  111. datetime startTradingTime = 0, endTradingTime = 0, dailyDrawDownTime = 0;
  112. datetime mondayTradingStart = 0, fridayTradingClose = 0;
  113. datetime eaStartTime; // Store EA start time
  114. double g_dailyStartBalance;
  115. bool enableTradingDaily = true;
  116. int prevOrderCount = 0;
  117. //+------------------------------------------------------------------+
  118. //| |
  119. //+------------------------------------------------------------------+
  120. string filename = fileName + Symbol() + ".csv";
  121. //+------------------------------------------------------------------+
  122. //| Expert initialization function |
  123. //+------------------------------------------------------------------+
  124. int OnInit()
  125. {
  126. //---
  127. if(!GlobalVariableCheck(global)) //for creating
  128. {
  129. GlobalVariableSet(global,0);
  130. // 0 means Free
  131. // 1 means busy
  132. }
  133. if(eaType == Tally_Sim)
  134. {
  135. FileDelete(filename,FILE_WRITE|FILE_CSV|FILE_COMMON|FILE_END);
  136. int filehandle = FileOpen(filename,FILE_WRITE|FILE_CSV|FILE_COMMON|FILE_END,",");
  137. if(filehandle != INVALID_HANDLE)
  138. {
  139. FileClose(filehandle);
  140. }
  141. }
  142. else
  143. {
  144. // prevOrderCount = orderCount();
  145. }
  146. string typ = eaType == 0 ? "Tally Sim" :"Tally Trade";
  147. Comment(" Current Mode: ",typ);
  148. tpSlHit = false;
  149. ticketAssigner = 1;
  150. if(eaType == Tally_Trade)
  151. {
  152. ArrayInitialize(bufferData,0.0);
  153. handler = iCustom(Symbol(),PERIOD_CURRENT,"Pulse Balance Indicator Sim",Dot_Color,StartingBalance,MagicNumbers,MA_Period,MA_Method,fileName1,historyTrades);
  154. ArraySetAsSeries(bufferData,true);
  155. }
  156. trade.SetExpertMagicNumber(magicNo1);
  157. trade.SetDeviationInPoints(10);
  158. trade.SetTypeFilling(ORDER_FILLING_IOC);
  159. trade.LogLevel(LOG_LEVEL_ALL);
  160. trade.SetAsyncMode(false);
  161. setStart_EndTime_modify(true,startTime,endTime,startTradingTime,endTradingTime);
  162. setStart_EndTime(true,startTime,endTime,startTradingTime,endTradingTime);
  163. g_dailyStartBalance = AccountInfoDouble(ACCOUNT_BALANCE);
  164. enableTradingDaily = true;
  165. eaStartTime = TimeCurrent(); // Track EA start time
  166. double balance = AccountInfoDouble(ACCOUNT_BALANCE);
  167. int magic = 123456;
  168. int maPeriod = 50;
  169. bool useMA = true;
  170. bool ddReached = false;
  171. CreateInfoLabels(balance, magic, maPeriod, useMA, ddReached);
  172. //---
  173. return(INIT_SUCCEEDED);
  174. }
  175. //+------------------------------------------------------------------+
  176. //| Expert deinitialization function |
  177. //+------------------------------------------------------------------+
  178. void OnDeinit(const int reason)
  179. {
  180. //---
  181. GlobalVariableSet(global,0);
  182. if(eaType == Tally_Sim)
  183. {
  184. deleteObjects();
  185. }
  186. ObjectDelete(0,"lbl_drawdown");
  187. ObjectDelete(0,"lbl_use_ma");
  188. ObjectDelete(0,"lbl_ma");
  189. ObjectDelete(0,"lbl_magic");
  190. ObjectDelete(0,"lbl_balance");
  191. Comment("");
  192. }
  193. //+------------------------------------------------------------------+
  194. //| Expert tick function |
  195. //+------------------------------------------------------------------+
  196. void OnTick()
  197. {
  198. //---
  199. if(CopyBuffer(handler, 0, 0, 1, bufferData) < 0)
  200. {
  201. // Print("Error in copying Buffer data ", GetLastError());
  202. }
  203. double balance = bufferData[0];
  204. if(CopyBuffer(handler, 1, 0, 1, bufferData) < 0)
  205. {
  206. // Print("Error in copying Buffer data ", GetLastError());
  207. }
  208. double MA = bufferData[0];
  209. if(balance != EMPTY_VALUE)
  210. {
  211. ObjectSetString(0, "lbl_balance", OBJPROP_TEXT,
  212. "Balance = " + DoubleToString(balance, 2));
  213. }
  214. else
  215. {
  216. ObjectSetString(0, "lbl_balance", OBJPROP_TEXT,
  217. "Balance = " + DoubleToString(0, 2));
  218. }
  219. if(MA != EMPTY_VALUE)
  220. {
  221. ObjectSetString(0, "lbl_ma", OBJPROP_TEXT,
  222. "Moving Average = " + DoubleToString(MA, _Digits));
  223. }
  224. else
  225. {
  226. ObjectSetString(0, "lbl_ma", OBJPROP_TEXT,
  227. "Moving Average = " + DoubleToString(0, _Digits));
  228. }
  229. timeConversion();
  230. CheckDailyDrawdown();
  231. if(TimeCurrent() >= dailyDrawDownTime && enableTradingDaily == false)
  232. {
  233. enableTradingDaily = true;
  234. g_dailyStartBalance = AccountInfoDouble(ACCOUNT_BALANCE);
  235. }
  236. if(eaType == Tally_Trade)
  237. {
  238. markClosedOrder(eaStartTime);
  239. checkVirtualTicketClosed(); // check if virtual trade closed so close Active Trade as well
  240. }
  241. if(eaType == Tally_Sim)
  242. {
  243. checkTPSLHit();
  244. }
  245. newBar();
  246. MqlDateTime dt;
  247. TimeToStruct(TimeCurrent(), dt);
  248. if(useMondayOpen)
  249. {
  250. // Print(" Week == ",dt.day_of_week," Start Time = ",mondayTradingStart);
  251. if(dt.day_of_week == 1 && TimeCurrent() < mondayTradingStart) // it's Monday
  252. {
  253. return;
  254. }
  255. }
  256. if(useFridayClose)
  257. {
  258. // Print(" Week == ",dt.day_of_week," End Time = ",fridayTradingClose);
  259. if(dt.day_of_week == 5 && TimeCurrent() >= fridayTradingClose) // it's Friday
  260. {
  261. closeAllActiveOrders();
  262. closeAllVirtualTrades();
  263. return;
  264. }
  265. }
  266. setStart_EndTime_modify(false,startTime,endTime,startTradingTime,endTradingTime);
  267. setStart_EndTime(false,startTime,endTime,startTradingTime,endTradingTime);
  268. if(enableTimeFilter && TimeCurrent() >= startTradingTime && TimeCurrent() < endTradingTime)
  269. {
  270. return;
  271. }
  272. placeTrade();
  273. }
  274. //+------------------------------------------------------------------+
  275. //| |
  276. //+------------------------------------------------------------------+
  277. bool newBar()
  278. {
  279. static datetime lastbar;
  280. datetime curbar = iTime(Symbol(), PERIOD_CURRENT, 0);
  281. if(lastbar != curbar)
  282. {
  283. lastbar = curbar;
  284. Print(" ---------------------- New Bar :: ---------------------- ",lastbar);
  285. return (true);
  286. }
  287. else
  288. {
  289. return (false);
  290. }
  291. }
  292. //+------------------------------------------------------------------+
  293. //| |
  294. //+------------------------------------------------------------------+
  295. bool newDayBar()
  296. {
  297. static datetime lastbar1;
  298. datetime curbar1 = iTime(Symbol(), PERIOD_D1, 0);
  299. if(lastbar1 != curbar1)
  300. {
  301. lastbar1 = curbar1;
  302. Print(" ---------------------- New Day Bar :: ---------------------- ",lastbar1);
  303. return (true);
  304. }
  305. else
  306. {
  307. return (false);
  308. }
  309. }
  310. //+------------------------------------------------------------------+
  311. //| |
  312. //+------------------------------------------------------------------+
  313. void closeAllActiveOrders()
  314. {
  315. for(int i=PositionsTotal()-1; i >=0 ; i--)
  316. {
  317. ulong ticket = PositionGetTicket(i);
  318. if(PositionSelectByTicket(ticket))
  319. {
  320. if(PositionGetInteger(POSITION_MAGIC) == magicNo &&
  321. PositionGetString(POSITION_SYMBOL) == Symbol())
  322. {
  323. if(trade.PositionClose(ticket))
  324. {
  325. Print("Closing All Active Orders");
  326. Print("Position closed ", ticket);
  327. }
  328. else
  329. {
  330. Print("Cannot close order: ",GetLastError());
  331. }
  332. }
  333. }
  334. }
  335. }
  336. //+------------------------------------------------------------------+
  337. //| |
  338. //+------------------------------------------------------------------+
  339. void timeConversion()
  340. {
  341. MqlDateTime date1, date_1,date_2;
  342. TimeToStruct(iTime(Symbol(),PERIOD_CURRENT,0),date1);
  343. u_sep=StringGetCharacter(sep,0);
  344. StringSplit(mondayOpen,u_sep,result1);
  345. date1.hour = (int)StringToInteger(result1[0]);
  346. date1.min = (int)StringToInteger(result1[1]);
  347. mondayTradingStart = StructToTime(date1);
  348. TimeToStruct(iTime(Symbol(),PERIOD_CURRENT,0),date_1);
  349. StringSplit(closeFriday,u_sep,result1);
  350. date_1.hour = (int)StringToInteger(result1[0]);
  351. date_1.min = (int)StringToInteger(result1[1]);
  352. fridayTradingClose = StructToTime(date_1);
  353. TimeToStruct(iTime(Symbol(),PERIOD_CURRENT,0),date_2);
  354. StringSplit(DrawdownResetTime,u_sep,result1);
  355. date_2.hour = (int)StringToInteger(result1[0]);
  356. date_2.min = (int)StringToInteger(result1[1]);
  357. dailyDrawDownTime = StructToTime(date_2);
  358. }
  359. //+------------------------------------------------------------------+
  360. //| |
  361. //+------------------------------------------------------------------+
  362. void placeTrade()
  363. {
  364. if(tpSlHit == false || eaType == Tally_Trade)
  365. {
  366. if(ordTyp == buy)
  367. {
  368. placeBuyTrade();
  369. }
  370. if(ordTyp == reverse)
  371. {
  372. placeSellTrade();
  373. }
  374. tpSlHit = true;
  375. }
  376. }
  377. //+------------------------------------------------------------------+
  378. //| |
  379. //+------------------------------------------------------------------+
  380. void placeBuyTrade()
  381. {
  382. double buySl = 0,buyTp=0;
  383. double Ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK);
  384. if(slPips != 0)
  385. {
  386. buySl = Ask - (slPips * Point() * 10);
  387. }
  388. if(tpPips != 0)
  389. {
  390. buyTp = Ask + (tpPips * Point() * 10);
  391. }
  392. if(eaType == Tally_Sim)
  393. {
  394. AddToStructure(ticketAssigner,0,magicNo,Ask,0,TimeCurrent(),0,buySl,buyTp,lot,0);
  395. ticketAssigner++;
  396. DrawVirtualBuyOpen(Ask);
  397. }
  398. else
  399. {
  400. if(GlobalVariableGet(global) == 0)
  401. {
  402. int count = orderCount();
  403. if(prevOrderCount != count && count != -1)
  404. {
  405. for(int k = prevOrderCount + 1;k <= count;k++)
  406. {
  407. if(getTicketByNumber(k,buySl,buyTp) != -1)
  408. {
  409. if(enableTradingDaily == true)
  410. {
  411. if(eaType == Tally_Trade && CopyTallyTrade)
  412. {
  413. if(CopyBuffer(handler, 0, 0, 4, bufferData) < 0)
  414. {
  415. Print("Error in copying Buffer data ", GetLastError());
  416. }
  417. double balance = bufferData[1];
  418. if(CopyBuffer(handler, 1, 0, 4, bufferData) < 0)
  419. {
  420. Print("Error in copying Buffer data ", GetLastError());
  421. }
  422. double MA = bufferData[1];
  423. Print(" Balance = ",balance," MA = ",MA);
  424. if(balance != EMPTY_VALUE)
  425. {
  426. ObjectSetString(0, "lbl_balance", OBJPROP_TEXT,
  427. "Balance = " + DoubleToString(balance, 2));
  428. }
  429. else
  430. {
  431. ObjectSetString(0, "lbl_balance", OBJPROP_TEXT,
  432. "Balance = " + DoubleToString(0, 2));
  433. }
  434. if(MA != EMPTY_VALUE)
  435. {
  436. ObjectSetString(0, "lbl_ma", OBJPROP_TEXT,
  437. "Moving Average = " + DoubleToString(MA, _Digits));
  438. }
  439. else
  440. {
  441. ObjectSetString(0, "lbl_ma", OBJPROP_TEXT,
  442. "Moving Average = " + DoubleToString(0, _Digits));
  443. }
  444. if(tradesDirection == buy)
  445. {
  446. if((balance > MA && useMovingAVG) || !(useMovingAVG))
  447. {
  448. double buy_Tp = SymbolInfoDouble(Symbol(),SYMBOL_ASK) + glTp * 10 * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
  449. double buy_Sl = SymbolInfoDouble(Symbol(),SYMBOL_ASK) - glSl * 10 * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
  450. if(!trade.Buy(lot, Symbol(),SymbolInfoDouble(Symbol(),SYMBOL_ASK),buy_Sl,buy_Tp,"Buy Trade"))
  451. {
  452. Print(" Error in Placing Buy Trade : ",GetLastError());
  453. }
  454. else
  455. {
  456. tradeSyncAddToStruct(k,trade.ResultOrder());
  457. }
  458. }
  459. else
  460. {
  461. Print(" Trade is not Placed because Balance is less than MA Value ");
  462. }
  463. }
  464. else
  465. {
  466. if((balance < MA && useMovingAVG) || !(useMovingAVG))
  467. {
  468. double sell_SL = SymbolInfoDouble(Symbol(),SYMBOL_BID) + glSl * 10 * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
  469. double Sell_TP = SymbolInfoDouble(Symbol(),SYMBOL_BID) - glTp * 10 * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
  470. if(!trade.Sell(lot,Symbol(),SymbolInfoDouble(Symbol(),SYMBOL_BID),sell_SL,Sell_TP,"Sell Trade"))
  471. {
  472. Print(" Error in Placing Sell Trade : ",GetLastError());
  473. }
  474. else
  475. {
  476. tradeSyncAddToStruct(k,trade.ResultOrder());
  477. }
  478. }
  479. else
  480. {
  481. Print(" Trade is not Placed because Balance is less than MA Value ");
  482. }
  483. }
  484. }
  485. }
  486. prevOrderCount = count;
  487. }
  488. }
  489. }
  490. }
  491. }
  492. }
  493. //+------------------------------------------------------------------+
  494. //| |
  495. //+------------------------------------------------------------------+
  496. void placeSellTrade()
  497. {
  498. double sellSl = 0, sellTp = 0;
  499. double Bid = SymbolInfoDouble(Symbol(),SYMBOL_BID);
  500. if(slPips != 0)
  501. {
  502. sellSl = Bid + (slPips * 10 * Point());
  503. }
  504. if(tpPips != 0)
  505. {
  506. sellTp = Bid - (tpPips * 10 * Point());
  507. }
  508. if(eaType == Tally_Sim)
  509. {
  510. AddToStructure(ticketAssigner,1,magicNo,Bid,0,TimeCurrent(),0,sellSl,sellTp,lot,0);
  511. ticketAssigner++;
  512. }
  513. else
  514. {
  515. int count = orderCount();
  516. if(prevOrderCount != count && count != -1)
  517. {
  518. for(int k = prevOrderCount + 1;k <= count;k++)
  519. {
  520. getTicketByNumber(k,sellSl,sellTp);
  521. if(getTicketByNumber(k,sellSl,sellTp) != -1)
  522. {
  523. if(enableTradingDaily == true)
  524. {
  525. if(eaType == Tally_Trade && CopyTallyTrade)
  526. {
  527. if(CopyBuffer(handler, 0, 0, 4, bufferData) < 0)
  528. {
  529. Print("Error in copying Buffer data ", GetLastError());
  530. }
  531. double balance = bufferData[1];
  532. if(CopyBuffer(handler, 1, 0, 4, bufferData) < 0)
  533. {
  534. Print("Error in copying Buffer data ", GetLastError());
  535. }
  536. double MA = bufferData[1];
  537. if(balance != EMPTY_VALUE)
  538. {
  539. ObjectSetString(0, "lbl_balance", OBJPROP_TEXT,
  540. "Balance = " + DoubleToString(balance, 2));
  541. }
  542. else
  543. {
  544. ObjectSetString(0, "lbl_balance", OBJPROP_TEXT,
  545. "Balance = " + DoubleToString(0, 2));
  546. }
  547. if(MA != EMPTY_VALUE)
  548. {
  549. ObjectSetString(0, "lbl_ma", OBJPROP_TEXT,
  550. "Moving Average = " + DoubleToString(MA, _Digits));
  551. }
  552. else
  553. {
  554. ObjectSetString(0, "lbl_ma", OBJPROP_TEXT,
  555. "Moving Average = " + DoubleToString(0, _Digits));
  556. }
  557. Print(" Balance = ",balance," MA = ",MA);
  558. if(tradesDirection == reverse)
  559. {
  560. if(balance < MA)
  561. {
  562. if(!trade.Sell(lot,Symbol(),Bid,sellSl,sellTp,"Sell Trade"))
  563. {
  564. Print(" Error in Placing Sell Trade : ",GetLastError());
  565. }
  566. }
  567. else
  568. {
  569. Print(" Trade is not Placed because Balance is less than MA Value ");
  570. }
  571. }
  572. else
  573. {
  574. if(balance > MA)
  575. {
  576. if(!trade.Buy(lot,Symbol(),SymbolInfoDouble(Symbol(),SYMBOL_ASK),sellTp,sellSl,"Buy Trade"))
  577. {
  578. Print(" Error in Placing Buy Trade : ",GetLastError());
  579. }
  580. }
  581. else
  582. {
  583. Print(" Trade is not Placed because Balance is less than MA Value ");
  584. }
  585. }
  586. }
  587. }
  588. prevOrderCount = count;
  589. }
  590. }
  591. }
  592. }
  593. }
  594. //+------------------------------------------------------------------+
  595. //| |
  596. //+------------------------------------------------------------------+
  597. void AddToStructure(int ticket, int type, int magic, double open_price,
  598. double close_price, datetime open_time, datetime close_time,
  599. double sl, double tp, double lotSize, double profit)
  600. {
  601. if(GlobalVariableGet(global) == 0)
  602. {
  603. for(int i = 0; i < MaxOrders; i++)
  604. {
  605. if(od[i].trade_ticket == -1)
  606. {
  607. od[i].trade_ticket = ticket;
  608. od[i].trade_type = type;
  609. od[i].trade_magic_no = magic;
  610. od[i].trade_open_price = open_price;
  611. od[i].trade_close_price = close_price;
  612. od[i].trade_open_time = open_time;
  613. od[i].trade_close_time = close_time;
  614. od[i].trade_sl = sl;
  615. od[i].trade_tp = tp;
  616. od[i].trade_lot = lotSize;
  617. od[i].trade_profit = profit;
  618. Print(" ========== Trade Placed of Ticket ========== ",ticket);
  619. Print("[AddToStructure] Added at index: ", i,
  620. " | Ticket = ", ticket,
  621. " | Type = ", type,
  622. " | Magic = ", magic,
  623. " | OpenPrice = ", open_price,
  624. " | ClosePrice = ", close_price,
  625. " | SL = ", sl,
  626. " | TP = ", tp,
  627. " | Lots = ", lotSize,
  628. " | Profit = ", profit);
  629. string line = MakeTradeString(
  630. od[i].trade_ticket,
  631. od[i].trade_type,
  632. od[i].trade_magic_no,
  633. od[i].trade_open_price,
  634. od[i].trade_close_price,
  635. od[i].trade_open_time,
  636. od[i].trade_close_time,
  637. od[i].trade_sl,
  638. od[i].trade_tp,
  639. od[i].trade_lot,
  640. od[i].trade_profit
  641. );
  642. writeDatainFile(line);
  643. break;
  644. }
  645. }
  646. }
  647. }
  648. //+------------------------------------------------------------------+
  649. //| |
  650. //+------------------------------------------------------------------+
  651. void writeAllDataToFile()
  652. {
  653. for(int i = 0; i < MaxOrders; i++)
  654. {
  655. if(od[i].trade_ticket != -1)
  656. {
  657. string line = MakeTradeString(
  658. od[i].trade_ticket,
  659. od[i].trade_type,
  660. od[i].trade_magic_no,
  661. od[i].trade_open_price,
  662. od[i].trade_close_price,
  663. od[i].trade_open_time,
  664. od[i].trade_close_time,
  665. od[i].trade_sl,
  666. od[i].trade_tp,
  667. od[i].trade_lot,
  668. od[i].trade_profit
  669. );
  670. if(GlobalVariableGet(global) == 0)
  671. {
  672. int filehandle = FileOpen(filename,FILE_WRITE|FILE_CSV|FILE_COMMON,",");
  673. if(filehandle != INVALID_HANDLE)
  674. {
  675. GlobalVariableSet(global,1);
  676. FileWrite(filehandle,line);
  677. Print(line);
  678. FileClose(filehandle);
  679. GlobalVariableSet(global,0);
  680. }
  681. }
  682. }
  683. }
  684. }
  685. //+------------------------------------------------------------------+
  686. //| |
  687. //+------------------------------------------------------------------+
  688. void tradeSyncAddToStruct(ulong sim_ticket,ulong live_ticket)
  689. {
  690. for(int i = 0; i < MaxOrders; i++)
  691. {
  692. if(od_sync[i].sim_trade_ticket == -1)
  693. {
  694. od_sync[i].sim_trade_ticket = sim_ticket;
  695. od_sync[i].live_trade_ticket = live_ticket;
  696. Print(" == Sim Ticket = ",sim_ticket," Live Ticket = ",live_ticket," Is Added to Structure === ");
  697. break;
  698. }
  699. }
  700. }
  701. //+------------------------------------------------------------------+
  702. //| |
  703. //+------------------------------------------------------------------+
  704. void checkTPSLHit()
  705. {
  706. if(GlobalVariableGet(global) == 0)
  707. {
  708. double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
  709. double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
  710. for(int i = 0; i < MaxOrders; i++)
  711. {
  712. if(od[i].trade_ticket != -1 && od[i].trade_close_price == 0)
  713. {
  714. int ticket = od[i].trade_ticket;
  715. int type = od[i].trade_type;
  716. double sl = od[i].trade_sl;
  717. double tp = od[i].trade_tp;
  718. double closePrice = 0;
  719. // ----------------------------------------------
  720. // BUY ORDER CHECK
  721. // ----------------------------------------------
  722. if(type == 0)
  723. {
  724. // TP hit → Bid >= TP
  725. if(bid >= tp && tp > 0)
  726. {
  727. closePrice = bid;
  728. Print(" ======== Buy Trade TP Hit ======= ",ticket);
  729. }
  730. // SL hit → Bid <= SL
  731. if(bid <= sl && sl > 0)
  732. {
  733. closePrice = bid;
  734. Print(" ======== Buy Trade SL Hit ======= ",ticket);
  735. }
  736. }
  737. // ----------------------------------------------
  738. // SELL ORDER CHECK
  739. // ----------------------------------------------
  740. if(type == 1)
  741. {
  742. // TP hit → Ask <= TP (price goes DOWN)
  743. if(ask <= tp && tp > 0)
  744. {
  745. closePrice = ask;
  746. Print(" ======== Sell Trade TP Hit ======= ",ticket);
  747. }
  748. // SL hit → Ask >= SL
  749. if(ask >= sl && sl > 0)
  750. {
  751. closePrice = ask;
  752. Print(" ======== Sell Trade SL Hit ======= ",ticket);
  753. }
  754. }
  755. // ----------------------------------------------
  756. // IF ANYTHING TRIGGERED → CLOSE TRADE
  757. // ----------------------------------------------
  758. if(closePrice > 0)
  759. {
  760. od[i].trade_close_price = closePrice;
  761. od[i].trade_close_time = TimeCurrent();
  762. double tpdifference = type == 1 ? (od[i].trade_open_price - od[i].trade_close_price) / Point() : (od[i].trade_close_price - od[i].trade_open_price) / Point();
  763. od[i].trade_profit += tpinDollar(od[i].trade_lot, tpdifference);
  764. Print("======= TRADE CLOSED of ticket =======",ticket);
  765. Print("Index: ", i,
  766. " | Ticket: ", ticket,
  767. " | Type: ", type,
  768. " | ClosePrice: ", closePrice,
  769. " | Time: ", od[i].trade_close_time,
  770. " | Profit: ", od[i].trade_profit);
  771. DrawVirtualBuyClose(closePrice);
  772. datetime t1 = od[i].trade_open_time;
  773. double price1 = od[i].trade_open_price;
  774. datetime t2 = od[i].trade_close_time;
  775. double price2 = od[i].trade_close_price;
  776. // DrawDottedTrendline("Ticket "+string(ticket), t1, price1, t2, price2, clrGreen);
  777. tpSlHit = false; // make these zero so new trade place's
  778. datetime openTime = od[i].trade_open_time;
  779. double openPrice = od[i].trade_open_price;
  780. datetime closeTime = od[i].trade_close_time;
  781. double closePrice = od[i].trade_close_price;
  782. long dealType = od[i].trade_type;
  783. string lineName = "TradeLine_" + (string)od[i].trade_ticket;
  784. createTrendLine(lineName, openTime, openPrice, closeTime, closePrice, dealType, od[i].trade_profit);
  785. PrintFormat("Trend line created for closed trade #%I64u | Profit: %.2f", od[i].trade_ticket, od[i].trade_profit);
  786. // string line = MakeTradeString(
  787. // od[i].trade_ticket,
  788. // od[i].trade_type,
  789. // od[i].trade_magic_no,
  790. // od[i].trade_open_price,
  791. // od[i].trade_close_price,
  792. // od[i].trade_open_time,
  793. // od[i].trade_close_time,
  794. // od[i].trade_sl,
  795. // od[i].trade_tp,
  796. // od[i].trade_lot,
  797. // od[i].trade_profit
  798. // );
  799. //
  800. // writeDatainFile(line);
  801. writeAllDataToFile();
  802. }
  803. }
  804. }
  805. }
  806. }
  807. //+------------------------------------------------------------------+
  808. //| |
  809. //+------------------------------------------------------------------+
  810. void closeAllVirtualTrades()
  811. {
  812. if(GlobalVariableGet(global) == 0)
  813. {
  814. double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
  815. double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
  816. for(int i = 0; i < MaxOrders; i++)
  817. {
  818. if(od[i].trade_ticket != -1 && od[i].trade_close_price == 0)
  819. {
  820. int ticket = od[i].trade_ticket;
  821. int type = od[i].trade_type;
  822. double sl = od[i].trade_sl;
  823. double tp = od[i].trade_tp;
  824. double closePrice = 0;
  825. // ----------------------------------------------
  826. // BUY ORDER CHECK
  827. // ----------------------------------------------
  828. if(type == 0)
  829. {
  830. closePrice = bid;
  831. Print(" ======== Buy Trade Closed By close all virtual Trades ======= ",ticket);
  832. }
  833. // ----------------------------------------------
  834. // SELL ORDER CHECK
  835. // ----------------------------------------------
  836. if(type == 1)
  837. {
  838. closePrice = ask;
  839. Print(" ======== Sell Trade Closed By close all virtual Trades ======= ",ticket);
  840. }
  841. // ----------------------------------------------
  842. // IF ANYTHING TRIGGERED → CLOSE TRADE
  843. // ----------------------------------------------
  844. if(closePrice > 0)
  845. {
  846. od[i].trade_close_price = closePrice;
  847. od[i].trade_close_time = TimeCurrent();
  848. double tpdifference = type == 1 ? (od[i].trade_open_price - od[i].trade_close_price) / Point() : (od[i].trade_close_price - od[i].trade_open_price) / Point();
  849. od[i].trade_profit += tpinDollar(od[i].trade_lot, tpdifference);
  850. Print("======= TRADE CLOSED of ticket =======",ticket);
  851. Print("Index: ", i,
  852. " | Ticket: ", ticket,
  853. " | Type: ", type,
  854. " | ClosePrice: ", closePrice,
  855. " | Time: ", od[i].trade_close_time,
  856. " | Profit: ", od[i].trade_profit);
  857. DrawVirtualBuyClose(closePrice);
  858. datetime t1 = od[i].trade_open_time;
  859. double price1 = od[i].trade_open_price;
  860. datetime t2 = od[i].trade_close_time;
  861. double price2 = od[i].trade_close_price;
  862. DrawDottedTrendline("Ticket "+string(ticket), t1, price1, t2, price2, clrGreen);
  863. tpSlHit = false; // make these zero so new trade place's
  864. writeAllDataToFile();
  865. }
  866. }
  867. }
  868. }
  869. }
  870. //+------------------------------------------------------------------+
  871. //| |
  872. //+------------------------------------------------------------------+
  873. double tpinDollar(double lotSize, double distance)
  874. {
  875. double pipvalue = NormalizeDouble(((SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)/(SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE)/Point()))*10),2);
  876. pipvalue = pipvalue / 10;
  877. double dollar = lotSize * distance * pipvalue;
  878. return NormalizeDouble(dollar,2);
  879. }
  880. //+------------------------------------------------------------------+
  881. //| |
  882. //+------------------------------------------------------------------+
  883. bool writeDatainFile(string str)
  884. {
  885. if(GlobalVariableGet(global) == 0)
  886. {
  887. int filehandle = FileOpen(filename,FILE_WRITE|FILE_CSV|FILE_COMMON|FILE_END,",");
  888. if(filehandle != INVALID_HANDLE)
  889. {
  890. GlobalVariableSet(global,1);
  891. FileSeek(filehandle, 0, SEEK_END);
  892. FileWrite(filehandle,str);
  893. Print(str);
  894. FileClose(filehandle);
  895. GlobalVariableSet(global,0);
  896. return true;
  897. }
  898. }
  899. return false;
  900. }
  901. //+------------------------------------------------------------------+
  902. //| |
  903. //+------------------------------------------------------------------+
  904. string MakeTradeString(int ticket, int type, int magic,
  905. double open_price, double close_price,
  906. datetime open_time, datetime close_time,
  907. double sl, double tp, double lotSize, double profit)
  908. {
  909. string str = StringFormat("%d,%d,%d,%.5f,%.5f,%s,%s,%.5f,%.5f,%.2f,%.2f",
  910. ticket,
  911. type,
  912. magic,
  913. open_price,
  914. close_price,
  915. TimeToString(open_time, TIME_DATE|TIME_SECONDS),
  916. TimeToString(close_time, TIME_DATE|TIME_SECONDS),
  917. sl,
  918. tp,
  919. lotSize,
  920. profit);
  921. return str;
  922. }
  923. //+------------------------------------------------------------------+
  924. //| |
  925. //+------------------------------------------------------------------+
  926. void setStart_EndTime(bool onInit,string start,string end,datetime & sessionStart,datetime & sessionEnd)
  927. {
  928. int newYorkStartHour = 0, newYorkStartMin = 0, newYorkEndHour = 0, newYorkEndMin = 0;
  929. datetime newYorkStartTrading,newYorkEndTrading;
  930. string time[];
  931. StringSplit(start,':',time);
  932. newYorkStartHour = (int)StringToInteger(time[0]);
  933. newYorkStartMin = (int)StringToInteger(time[1]);
  934. EventSetMillisecondTimer(500);
  935. time[0] = "";
  936. time[1] = "";
  937. StringSplit(end,':',time);
  938. newYorkEndHour = (int)StringToInteger(time[0]);
  939. newYorkEndMin = (int)StringToInteger(time[1]);
  940. // Print(" Start Time Hour: ",newYorkStartHour," Start Time Min: ",newYorkStartMin);
  941. // Print(" End Time Hour: ",newYorkEndHour," End Time Min: ",newYorkEndMin);
  942. datetime startDateTime;
  943. MqlDateTime st;
  944. TimeCurrent(st); // get current date
  945. st.hour = newYorkStartHour;
  946. st.min = newYorkStartMin;
  947. st.sec = 0;
  948. startDateTime = StructToTime(st);
  949. datetime endDateTime;
  950. MqlDateTime et;
  951. TimeCurrent(et); // get current date
  952. et.hour = newYorkEndHour;
  953. et.min = newYorkEndMin;
  954. et.sec = 0;
  955. endDateTime = StructToTime(et);
  956. MqlDateTime sdate,edate;
  957. datetime start_Time = 0, end_Time = 0;
  958. if(startDateTime > endDateTime)
  959. {
  960. if(onInit)
  961. {
  962. start_Time = iTime(Symbol(),PERIOD_D1,1);
  963. end_Time = iTime(Symbol(),PERIOD_D1,0);
  964. }
  965. else
  966. {
  967. start_Time = sessionStart;
  968. end_Time = sessionEnd;
  969. if(TimeCurrent() >= sessionEnd && sessionEnd != 0)
  970. {
  971. start_Time = iTime(Symbol(),PERIOD_D1,0);
  972. end_Time = start_Time + 86400;
  973. }
  974. }
  975. }
  976. else
  977. {
  978. start_Time = iTime(Symbol(),PERIOD_D1,0);
  979. end_Time = iTime(Symbol(),PERIOD_D1,0);
  980. }
  981. if(TimeToStruct(end_Time,edate))
  982. {
  983. edate.hour = newYorkEndHour;
  984. edate.min = newYorkEndMin;
  985. edate.sec = 0;
  986. }
  987. else
  988. Print("Error in Converting Time: ",GetLastError());
  989. newYorkEndTrading = StructToTime(edate);
  990. if(TimeToStruct(start_Time,sdate))
  991. {
  992. sdate.hour = newYorkStartHour;
  993. sdate.min = newYorkStartMin;
  994. sdate.sec = 0;
  995. }
  996. else
  997. Print("Error in Converting Time: ",GetLastError());
  998. newYorkStartTrading = StructToTime(sdate);
  999. sessionStart = newYorkStartTrading;
  1000. sessionEnd = newYorkEndTrading;
  1001. }
  1002. //+------------------------------------------------------------------+
  1003. //| |
  1004. //+------------------------------------------------------------------+
  1005. void setStart_EndTime_modify(bool onInit,string start,string end,datetime & sessionStart,datetime & sessionEnd)
  1006. {
  1007. int newYorkStartHour = 0, newYorkStartMin = 0, newYorkEndHour = 0, newYorkEndMin = 0;
  1008. datetime newYorkStartTrading,newYorkEndTrading;
  1009. string time[];
  1010. StringSplit(start,':',time);
  1011. newYorkStartHour = (int)StringToInteger(time[0]);
  1012. newYorkStartMin = (int)StringToInteger(time[1]);
  1013. time[0] = "";
  1014. time[1] = "";
  1015. StringSplit(end,':',time);
  1016. newYorkEndHour = (int)StringToInteger(time[0]);
  1017. newYorkEndMin = (int)StringToInteger(time[1]);
  1018. // Print(" Start Time Hour: ",newYorkStartHour," Start Time Min: ",newYorkStartMin);
  1019. // Print(" End Time Hour: ",newYorkEndHour," End Time Min: ",newYorkEndMin);
  1020. datetime startDateTime;
  1021. MqlDateTime st;
  1022. TimeCurrent(st); // get current date
  1023. st.hour = newYorkStartHour;
  1024. st.min = newYorkStartMin;
  1025. st.sec = 0;
  1026. startDateTime = StructToTime(st);
  1027. datetime endDateTime;
  1028. MqlDateTime et;
  1029. TimeCurrent(et); // get current date
  1030. et.hour = newYorkEndHour;
  1031. et.min = newYorkEndMin;
  1032. et.sec = 0;
  1033. endDateTime = StructToTime(et);
  1034. MqlDateTime sdate,edate;
  1035. datetime start_Time = 0, end_Time = 0;
  1036. if(startDateTime > endDateTime)
  1037. {
  1038. start_Time = iTime(Symbol(),PERIOD_D1,1);
  1039. end_Time = iTime(Symbol(),PERIOD_D1,0);
  1040. }
  1041. else
  1042. {
  1043. start_Time = iTime(Symbol(),PERIOD_D1,0);
  1044. end_Time = iTime(Symbol(),PERIOD_D1,0);
  1045. }
  1046. if(TimeToStruct(end_Time,edate))
  1047. {
  1048. edate.hour = newYorkEndHour;
  1049. edate.min = newYorkEndMin;
  1050. edate.sec = 0;
  1051. }
  1052. else
  1053. Print("Error in Converting Time: ",GetLastError());
  1054. newYorkEndTrading = StructToTime(edate);
  1055. if(TimeToStruct(start_Time,sdate))
  1056. {
  1057. sdate.hour = newYorkStartHour;
  1058. sdate.min = newYorkStartMin;
  1059. sdate.sec = 0;
  1060. }
  1061. else
  1062. Print("Error in Converting Time: ",GetLastError());
  1063. newYorkStartTrading = StructToTime(sdate);
  1064. sessionStart = newYorkStartTrading;
  1065. sessionEnd = newYorkEndTrading;
  1066. }
  1067. //+------------------------------------------------------------------+
  1068. //| Check Virtual TP/SL for all positions |
  1069. //+------------------------------------------------------------------+
  1070. //void CheckVirtualGlobalTpSl()
  1071. // {
  1072. //
  1073. // double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
  1074. // double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
  1075. //
  1076. // for(int i=PositionsTotal()-1; i >=0 ; i--)
  1077. // {
  1078. // ulong ticket = PositionGetTicket(i);
  1079. // if(PositionSelectByTicket(ticket))
  1080. // {
  1081. // if(PositionGetInteger(POSITION_MAGIC) == magicNo &&
  1082. // PositionGetString(POSITION_SYMBOL) == _Symbol)
  1083. // {
  1084. // if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
  1085. // {
  1086. // double tp_price = PositionGetDouble(POSITION_PRICE_OPEN) + glTp * 10 * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
  1087. // double sl_price = PositionGetDouble(POSITION_PRICE_OPEN) - glSl * 10 * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
  1088. //
  1089. // if(bid >= tp_price || bid <= sl_price)
  1090. // {
  1091. // closeAllActiveOrders();
  1092. // return;
  1093. // }
  1094. // }
  1095. // if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
  1096. // {
  1097. // double tp_price = PositionGetDouble(POSITION_PRICE_OPEN) - glTp * 10 * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
  1098. // double sl_price = PositionGetDouble(POSITION_PRICE_OPEN) + glSl * 10 * SymbolInfoDouble(_Symbol, SYMBOL_POINT);
  1099. //
  1100. // if(ask <= tp_price || ask >= sl_price)
  1101. // {
  1102. // closeAllActiveOrders();
  1103. // return;
  1104. // }
  1105. // }
  1106. // }
  1107. // }
  1108. // }
  1109. // }
  1110. //+------------------------------------------------------------------+
  1111. //| |
  1112. //+------------------------------------------------------------------+
  1113. void CheckDailyDrawdown()
  1114. {
  1115. if(!UseDailyDrawdownLimit)
  1116. return;
  1117. double equity = AccountInfoDouble(ACCOUNT_EQUITY);
  1118. double drawdown = g_dailyStartBalance - equity;
  1119. if(drawdown >= DailyDrawdownAmount)
  1120. {
  1121. enableTradingDaily = false;
  1122. Print("Daily Drawdown Limit Hit: ", drawdown, " >= ", DailyDrawdownAmount);
  1123. closeAllActiveOrders();
  1124. closeAllVirtualTrades();
  1125. }
  1126. }
  1127. //+------------------------------------------------------------------+
  1128. //| |
  1129. //+------------------------------------------------------------------+
  1130. void markClosedOrder(datetime eaTime)
  1131. {
  1132. HistorySelect(eaTime, TimeCurrent());
  1133. for(int i = HistoryDealsTotal() - 1; i >= 0; i--)
  1134. {
  1135. ulong dealTicket = HistoryDealGetTicket(i);
  1136. long dealMagic = HistoryDealGetInteger(dealTicket, DEAL_MAGIC);
  1137. if(dealMagic != magicNo && dealMagic != 0)
  1138. continue;
  1139. if(HistoryDealGetString(dealTicket, DEAL_SYMBOL) == Symbol())
  1140. {
  1141. //Print("Condition 2 ",HistoryDealGetInteger(dealTicket, DEAL_ENTRY)," HistoryDealsTotal(): ",HistoryDealsTotal());
  1142. if(HistoryDealGetInteger(dealTicket, DEAL_ENTRY) == DEAL_ENTRY_OUT)
  1143. {
  1144. //Print("deal out close: ",dealTicket);
  1145. long dealType = HistoryDealGetInteger(dealTicket, DEAL_TYPE);
  1146. if(dealType != DEAL_TYPE_BUY && dealType != DEAL_TYPE_SELL)
  1147. continue;
  1148. double profit = HistoryDealGetDouble(dealTicket, DEAL_PROFIT);
  1149. profit = NormalizeDouble(profit, 2);
  1150. string lineName = "TradeLine_" + (string)dealTicket;
  1151. if(ObjectFind(0, lineName) >= 0)
  1152. continue;
  1153. ulong entryDeal = findEntryDeal(dealTicket);
  1154. if(entryDeal == 0)
  1155. continue;
  1156. datetime openTime = (datetime)HistoryDealGetInteger(entryDeal, DEAL_TIME);
  1157. double openPrice = HistoryDealGetDouble(entryDeal, DEAL_PRICE);
  1158. datetime closeTime = (datetime)HistoryDealGetInteger(dealTicket, DEAL_TIME);
  1159. double closePrice = HistoryDealGetDouble(dealTicket, DEAL_PRICE);
  1160. createTrendLine(lineName, openTime, openPrice, closeTime, closePrice, dealType, profit);
  1161. PrintFormat("Trend line created for closed trade #%I64u | Profit: %.2f", dealTicket, profit);
  1162. }
  1163. }
  1164. }
  1165. }
  1166. //+------------------------------------------------------------------+
  1167. //| |
  1168. //+------------------------------------------------------------------+
  1169. void createTrendLine(string name,
  1170. datetime openTime, double openPrice,
  1171. datetime closeTime, double closePrice,
  1172. long dealType, double profit)
  1173. {
  1174. if(ObjectFind(0, name) >= 0)
  1175. return;
  1176. if(!ObjectCreate(0, name, OBJ_TREND, 0, openTime, openPrice, closeTime, closePrice))
  1177. {
  1178. Print("Error creating trend line: ", GetLastError());
  1179. return;
  1180. }
  1181. ObjectSetInteger(0, name, OBJPROP_WIDTH, tradeLineThickness);
  1182. ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
  1183. ObjectSetInteger(0, name, OBJPROP_RAY, false);
  1184. color lineColor = (dealType == DEAL_TYPE_BUY) ? clrRed : clrBlue;
  1185. ObjectSetInteger(0, name, OBJPROP_COLOR, lineColor);
  1186. createProfitLabel(name + "_label", openTime, openPrice, closeTime, closePrice, dealType, profit);
  1187. }
  1188. //+------------------------------------------------------------------+
  1189. //| |
  1190. //+------------------------------------------------------------------+
  1191. void createProfitLabel(string name,
  1192. datetime openTime, double openPrice,
  1193. datetime closeTime, double closePrice,
  1194. long dealType, double profit)
  1195. {
  1196. if(ObjectFind(0, name) >= 0)
  1197. return;
  1198. datetime middleTime = openTime + (closeTime - openTime) / 2;
  1199. double midPrice = (openPrice + closePrice) / 2;
  1200. if(!ObjectCreate(0, name, OBJ_TEXT, 0, middleTime, midPrice))
  1201. {
  1202. Print("Error creating profit label: ", GetLastError());
  1203. return;
  1204. }
  1205. string profitText = "$" + DoubleToString(profit, 2);
  1206. ObjectSetString(0, name, OBJPROP_TEXT, profitText);
  1207. ObjectSetInteger(0, name, OBJPROP_FONTSIZE, dollarFontSize);
  1208. ObjectSetInteger(0, name, OBJPROP_COLOR, dollarFontColor);
  1209. ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_TOP);
  1210. ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
  1211. }
  1212. //+------------------------------------------------------------------+
  1213. //| |
  1214. //+------------------------------------------------------------------+
  1215. ulong findEntryDeal(ulong closeDeal)
  1216. {
  1217. string symbol = HistoryDealGetString(closeDeal, DEAL_SYMBOL);
  1218. long positionID = HistoryDealGetInteger(closeDeal, DEAL_POSITION_ID);
  1219. int dealOutCount = 0;
  1220. for(int i = HistoryDealsTotal() - 1; i >= 0; i--)
  1221. {
  1222. ulong deal = HistoryDealGetTicket(i);
  1223. if(HistoryDealGetInteger(deal, DEAL_POSITION_ID) == positionID)
  1224. {
  1225. if(HistoryDealGetInteger(deal, DEAL_ENTRY) == DEAL_ENTRY_OUT)
  1226. {
  1227. dealOutCount++;
  1228. }
  1229. }
  1230. }
  1231. if(dealOutCount < 2)
  1232. {
  1233. for(int i = HistoryDealsTotal() - 1; i >= 0; i--)
  1234. {
  1235. ulong deal = HistoryDealGetTicket(i);
  1236. if(HistoryDealGetInteger(deal, DEAL_POSITION_ID) == positionID &&
  1237. HistoryDealGetInteger(deal, DEAL_ENTRY) == DEAL_ENTRY_IN &&
  1238. HistoryDealGetString(deal, DEAL_SYMBOL) == symbol)
  1239. return deal;
  1240. //Print("Deal: ", deal);
  1241. }
  1242. }
  1243. else
  1244. {
  1245. for(int i = 0; i < HistoryDealsTotal(); i++)
  1246. {
  1247. ulong deal = HistoryDealGetTicket(i);
  1248. if(HistoryDealGetInteger(deal, DEAL_POSITION_ID) == positionID &&
  1249. HistoryDealGetInteger(deal, DEAL_ENTRY) == DEAL_ENTRY_OUT)
  1250. {
  1251. return deal;
  1252. }
  1253. //Print("Deal: ", deal);
  1254. }
  1255. }
  1256. return 0;
  1257. }
  1258. //+------------------------------------------------------------------+
  1259. //| |
  1260. //+------------------------------------------------------------------+
  1261. void DrawArrow(string name, datetime time, double price, color clr, int arrow)
  1262. {
  1263. if(ObjectFind(0, name) == -1)
  1264. {
  1265. ObjectCreate(0, name, OBJ_ARROW, 0, time, price);
  1266. ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
  1267. ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);
  1268. ObjectSetInteger(0, name, OBJPROP_ARROWCODE, arrow);
  1269. }
  1270. }
  1271. //+------------------------------------------------------------------+
  1272. //| |
  1273. //+------------------------------------------------------------------+
  1274. void DrawVirtualBuyOpen(double openPrice)
  1275. {
  1276. datetime t = TimeCurrent();
  1277. string name = "VBUY_OPEN_" + IntegerToString(t);
  1278. // DrawArrow(name, t, openPrice, clrLime, 233);
  1279. ObjectCreate(0,name,OBJ_ARROW_BUY,0,TimeCurrent(),openPrice);
  1280. }
  1281. //+------------------------------------------------------------------+
  1282. //| |
  1283. //+------------------------------------------------------------------+
  1284. void DrawVirtualBuyClose(double closePrice)
  1285. {
  1286. datetime t = TimeCurrent();
  1287. string name = "VBUY_CLOSE_" + IntegerToString(t);
  1288. // DrawArrow(name, t, closePrice, clrRed, 234);
  1289. ObjectCreate(0,name,OBJ_ARROW_SELL,0,TimeCurrent(),closePrice);
  1290. }
  1291. //+------------------------------------------------------------------+
  1292. //| |
  1293. //+------------------------------------------------------------------+
  1294. void DrawDottedTrendline(string name, datetime time1, double price1, datetime time2, double price2, color clr)
  1295. {
  1296. // Delete if already exists
  1297. if(ObjectFind(0, name) != -1)
  1298. ObjectDelete(0, name);
  1299. // Create the trendline
  1300. if(!ObjectCreate(0, name, OBJ_TREND, 0, time1, price1, time2, price2))
  1301. Print("Error creating trendline: ", GetLastError());
  1302. // Set properties
  1303. ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
  1304. ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DOT); // Dotted line
  1305. ObjectSetInteger(0, name, OBJPROP_WIDTH, 1); // Line width
  1306. }
  1307. //+------------------------------------------------------------------+
  1308. //| |
  1309. //+------------------------------------------------------------------+
  1310. int orderCount()
  1311. {
  1312. int index = 0;
  1313. if(GlobalVariableGet(global) == 0)
  1314. {
  1315. GlobalVariableSet(global,1);
  1316. int handle = FileOpen(filename, FILE_READ | FILE_COMMON);
  1317. if(handle == INVALID_HANDLE)
  1318. {
  1319. Print("EA=> Handler invalid: orderCount() ", filename," ",GetLastError()," eaType: ",eaType);
  1320. return -1;
  1321. }
  1322. while(!FileIsEnding(handle))
  1323. {
  1324. string line = FileReadString(handle);
  1325. string parts[];
  1326. int count = StringSplit(line, ',', parts);
  1327. int ticket = (int)StringToInteger(parts[0]);
  1328. int type = (int)StringToInteger(parts[1]);
  1329. int magic = (int)StringToInteger(parts[2]);
  1330. double open_price = StringToDouble(parts[3]);
  1331. double close_price = StringToDouble(parts[4]);
  1332. datetime open_time = StringToTime(parts[5]);
  1333. datetime close_time = StringToTime(parts[6]);
  1334. double sl = StringToDouble(parts[7]);
  1335. double tp = StringToDouble(parts[8]);
  1336. double lotS = StringToDouble(parts[9]);
  1337. double profit = StringToDouble(parts[10]);
  1338. index++;
  1339. }
  1340. FileClose(handle);
  1341. GlobalVariableSet(global,0);
  1342. }
  1343. return index;
  1344. }
  1345. //+------------------------------------------------------------------+
  1346. //| |
  1347. //+------------------------------------------------------------------+
  1348. int getTicketByNumber(int id,double & buySl,double & buyTp)
  1349. {
  1350. int index = -1;
  1351. if(GlobalVariableGet(global) == 0)
  1352. {
  1353. GlobalVariableSet(global,1);
  1354. int handle = FileOpen(filename, FILE_READ | FILE_COMMON);
  1355. if(handle == INVALID_HANDLE)
  1356. {
  1357. Print("EA=> Handler invalid: getTicketByNumber() ", filename," error: ",GetLastError()," eaType: ",eaType);
  1358. return 0;
  1359. }
  1360. while(!FileIsEnding(handle))
  1361. {
  1362. string line = FileReadString(handle);
  1363. // Skip empty line
  1364. if(StringLen(line) < 2)
  1365. continue;
  1366. string parts[];
  1367. int count = StringSplit(line, ',', parts);
  1368. int ticket = (int)StringToInteger(parts[0]);
  1369. int type = (int)StringToInteger(parts[1]);
  1370. int magic = (int)StringToInteger(parts[2]);
  1371. double open_price = StringToDouble(parts[3]);
  1372. double close_price = StringToDouble(parts[4]);
  1373. datetime open_time = StringToTime(parts[5]);
  1374. datetime close_time = StringToTime(parts[6]);
  1375. double sl = StringToDouble(parts[7]);
  1376. double tp = StringToDouble(parts[8]);
  1377. double lotS = StringToDouble(parts[9]);
  1378. double profit = StringToDouble(parts[10]);
  1379. if(id == ticket)
  1380. {
  1381. buySl = sl;
  1382. buyTp = tp;
  1383. index = id;
  1384. }
  1385. }
  1386. FileClose(handle);
  1387. GlobalVariableSet(global,0);
  1388. }
  1389. return index;
  1390. }
  1391. //+------------------------------------------------------------------+
  1392. //| |
  1393. //+------------------------------------------------------------------+
  1394. void checkVirtualTicketClosed() // check if virtual trade closed so close Active Trade as well
  1395. {
  1396. if(GlobalVariableGet(global) == 0)
  1397. {
  1398. GlobalVariableSet(global,1);
  1399. int handle = FileOpen(filename, FILE_READ | FILE_COMMON);
  1400. if(handle == INVALID_HANDLE)
  1401. {
  1402. Print("EA=> Handler invalid: checkVirtualTicketClosed() ", filename," error: ",GetLastError()," eaType: ",eaType);
  1403. return;
  1404. }
  1405. while(!FileIsEnding(handle))
  1406. {
  1407. string line = FileReadString(handle);
  1408. string parts[];
  1409. int count = StringSplit(line, ',', parts);
  1410. int ticket = (int)StringToInteger(parts[0]);
  1411. int type = (int)StringToInteger(parts[1]);
  1412. int magic = (int)StringToInteger(parts[2]);
  1413. double open_price = StringToDouble(parts[3]);
  1414. double close_price = StringToDouble(parts[4]);
  1415. datetime open_time = StringToTime(parts[5]);
  1416. datetime close_time = StringToTime(parts[6]);
  1417. double sl = StringToDouble(parts[7]);
  1418. double tp = StringToDouble(parts[8]);
  1419. double lotS = StringToDouble(parts[9]);
  1420. double profit = StringToDouble(parts[10]);
  1421. for(int i = 0; i < MaxOrders; i++)
  1422. {
  1423. if(od_sync[i].sim_trade_ticket != -1)
  1424. {
  1425. if(od_sync[i].sim_trade_ticket == ticket && close_time > 0)
  1426. {
  1427. if(PositionSelectByTicket(od_sync[i].live_trade_ticket))
  1428. {
  1429. Print(" Virtual Trade is Closed so Remove the Live Trade As well "," Virtual Ticket = ",od_sync[i].sim_trade_ticket," Live Ticket = ",od_sync[i].live_trade_ticket);
  1430. if(trade.PositionClose(od_sync[i].live_trade_ticket))
  1431. {
  1432. Print("Position closed ", od_sync[i].live_trade_ticket);
  1433. od_sync[i].sim_trade_ticket = -1;
  1434. od_sync[i].sim_trade_ticket = -1;
  1435. }
  1436. else
  1437. {
  1438. Print("Cannot close order: ",GetLastError());
  1439. }
  1440. }
  1441. }
  1442. }
  1443. }
  1444. }
  1445. FileClose(handle);
  1446. GlobalVariableSet(global,0);
  1447. }
  1448. }
  1449. //+------------------------------------------------------------------+
  1450. //| |
  1451. //+------------------------------------------------------------------+
  1452. void deleteObjects()
  1453. {
  1454. int total = ObjectsTotal(0);
  1455. for(int i = total - 1; i >= 0; i--)
  1456. {
  1457. string name = ObjectName(0, i);
  1458. if(StringFind(name, "VBUY_OPEN_") >= 0 || StringFind(name, "VBUY_CLOSE_") >= 0 || StringFind(name, "Ticket ") >= 0)
  1459. {
  1460. ObjectDelete(0, name);
  1461. }
  1462. }
  1463. }
  1464. //+------------------------------------------------------------------+
  1465. //| Create Bottom Right Labels |
  1466. //+------------------------------------------------------------------+
  1467. void CreateInfoLabels(double balance,
  1468. int magic,
  1469. int maPeriod,
  1470. bool useMA,
  1471. bool drawdownReached)
  1472. {
  1473. int corner = CORNER_RIGHT_LOWER;
  1474. int xOffset = 200;
  1475. int yStart = 120; // IMPORTANT
  1476. int yStep = 18;
  1477. ObjectsDeleteAll(0,-1,-1);
  1478. if(CopyTallyTrade)
  1479. {
  1480. string names[5] =
  1481. {
  1482. "lbl_balance",
  1483. "lbl_magic",
  1484. "lbl_ma",
  1485. "lbl_use_ma",
  1486. "lbl_drawdown"
  1487. };
  1488. string texts[5];
  1489. texts[0] = "Balance = " + DoubleToString(balance, 2);
  1490. texts[1] = "Magic # = " + IntegerToString(magicNo1);
  1491. texts[2] = "Moving Average = " + IntegerToString(maPeriod);
  1492. texts[3] = "Use Moving Average = " + (useMovingAVG ? "TRUE" : "FALSE");
  1493. texts[4] = "Drawdown Reached = " + (!enableTradingDaily ? "TRUE" : "FALSE");
  1494. for(int i = 0; i < 5; i++)
  1495. {
  1496. if(ObjectFind(0, names[i]) == -1)
  1497. {
  1498. ObjectCreate(0, names[i], OBJ_LABEL, 0, 0, 0);
  1499. ObjectSetInteger(0, names[i], OBJPROP_CORNER, corner);
  1500. ObjectSetInteger(0, names[i], OBJPROP_XDISTANCE, xOffset);
  1501. ObjectSetInteger(0, names[i], OBJPROP_YDISTANCE, yStart - i * yStep);
  1502. ObjectSetInteger(0, names[i], OBJPROP_FONTSIZE, 9);
  1503. ObjectSetInteger(0, names[i], OBJPROP_COLOR, clrWhite);
  1504. ObjectSetString(0, names[i], OBJPROP_FONT, "Arial");
  1505. }
  1506. ObjectSetString(0, names[i], OBJPROP_TEXT, texts[i]);
  1507. }
  1508. }
  1509. else
  1510. {
  1511. string names[4] =
  1512. {
  1513. "lbl_balance",
  1514. "lbl_ma",
  1515. "lbl_use_ma",
  1516. "lbl_drawdown"
  1517. };
  1518. string texts[4];
  1519. texts[0] = "Balance = " + DoubleToString(balance, 2);
  1520. texts[1] = "Moving Average = " + IntegerToString(maPeriod);
  1521. texts[2] = "Use Moving Average = " + (useMovingAVG ? "TRUE" : "FALSE");
  1522. texts[3] = "Drawdown Reached = " + (!enableTradingDaily ? "TRUE" : "FALSE");
  1523. for(int i = 0; i < 4; i++)
  1524. {
  1525. if(ObjectFind(0, names[i]) == -1)
  1526. {
  1527. ObjectCreate(0, names[i], OBJ_LABEL, 0, 0, 0);
  1528. ObjectSetInteger(0, names[i], OBJPROP_CORNER, corner);
  1529. ObjectSetInteger(0, names[i], OBJPROP_XDISTANCE, xOffset);
  1530. ObjectSetInteger(0, names[i], OBJPROP_YDISTANCE, yStart - i * yStep);
  1531. ObjectSetInteger(0, names[i], OBJPROP_FONTSIZE, 9);
  1532. ObjectSetInteger(0, names[i], OBJPROP_COLOR, clrWhite);
  1533. ObjectSetString(0, names[i], OBJPROP_FONT, "Arial");
  1534. }
  1535. ObjectSetString(0, names[i], OBJPROP_TEXT, texts[i]);
  1536. }
  1537. }
  1538. }
  1539. //+------------------------------------------------------------------+
  1540. //+------------------------------------------------------------------+