Ei kuvausta

vol_hedge_strategy_mt5.mq5 36KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939
  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.00"
  9. #define MaxOrders 100
  10. #include <Trade\Trade.mqh>
  11. CTrade trade;
  12. //+------------------------------------------------------------------+
  13. //| Expert initialization function |
  14. //+------------------------------------------------------------------+
  15. enum NewsCloseOrder
  16. {
  17. CloseAllRunningOrder=0,
  18. LetTheOrderRun=1,
  19. };
  20. enum selectLine
  21. {
  22. LineOnNewsBar =0,
  23. LineOnNewsStop=1
  24. };
  25. #import "volHedgeNewsFilter.ex5"
  26. //+------------------------------------------------------------------+
  27. //| |
  28. //+------------------------------------------------------------------+
  29. void initiateNews();
  30. int returnNewsStatus(bool High_Impact_News=true
  31. ,int High_Start_Time=60//Stop Trade before high News (min)
  32. ,int High_Stop_Time=15 //Stop Trade after high News (min)
  33. ,bool show_high_line=true//Show verticle Line when high news comes
  34. ,bool Medium_Impact_News=true
  35. ,int Medium_Start_Time=60//Stop Trade before medium News (min)
  36. ,int Medium_Stop_Time=15 //Stop Trade after medium News (min)
  37. ,bool show_medium_line=true//Show verticle Line when medium news comes
  38. ,bool Low_Impact_News=true
  39. ,int Low_Start_Time=60//Stop Trade before low News (min)
  40. ,int Low_Stop_Time=15 //Stop Trade after low News (min)
  41. ,bool show_low_line=true//Show verticle Line when low news comes
  42. ,string symbol=""
  43. ,string expert=""
  44. ,int GMT_Broker_Time=2
  45. ,selectLine sl=0
  46. ,string extraSymbol=""
  47. );
  48. void initiateNews();
  49. bool checkDate(string &lastNewsTitle, string &symbolNews, string &impactNews, string &news1, string &news2, string &news3, datetime &timeRemaining, datetime date,string expertname = "",string symbol = "",string extraSymbol="", int gmt=2,string description_1 = "",int candle = 0);
  50. void PrintStructure();
  51. #import
  52. struct new_trade_store
  53. {
  54. ulong buy_ticket; // Buy Ticket
  55. ulong sell_ticket; // Sell Ticket
  56. string symbol; // Symbol
  57. double price; // Price
  58. double stop_loss; // StopLoss
  59. double take_profit; // TakeProfit
  60. datetime start_time; // Start time
  61. datetime end_time; // End Time
  62. new_trade_store()
  63. {
  64. buy_ticket = -1;
  65. sell_ticket = -1;
  66. }
  67. };
  68. new_trade_store newTradeStore[MaxOrders];
  69. enum lotcalculator
  70. {
  71. fix, //Fixed Lot Size
  72. rsk, //Risk Percentage
  73. dollar, // Risk in Dollars
  74. };
  75. sinput string string_0 = "<><><><><><> General SETTINGS <><><><><><>"; //__
  76. input int magic_no = 333; // Magic no
  77. input bool bothHitsSl = false; // Open after Both Hits StopLoss
  78. input int maxTrades = 2; // Max Concurrent Trades
  79. input int maxSlippage = 5; // Max Slippage
  80. input bool enableSpreadFilter = false; // Enable Spread Filter
  81. input double maximumSpread = 10; // Maximum Spread
  82. input string string_1 = "<><><><><><> Lot Management<><><><><><>"; //__
  83. input lotcalculator lot_calculator = fix; // Lot Size Option
  84. input double lot_amount = 0.1; // Lot Size
  85. input double risk = 0.5; // Risk in Percentage %
  86. input double dollars = 10; // Risk in GBP
  87. input string string_2 = "<><><><><><> Time Filter Setting <><><><><><> ";//_
  88. input bool enableTimeSession = false; // Enable Time Session
  89. input string start_time_session = "01:00"; // Start Session
  90. input string end_time_session = "23:59"; // End Session
  91. input string string_0_2 = "<><><><><><> Trailing Setting<><><><><><>"; //__
  92. input bool indivial_trailing = false; // Indiviual Trailing
  93. input double ts_sl = 15; // Trailing Start in Pips
  94. input double ts = 5; // Trailing Stop in Pips
  95. input string news = "<><><><><><> News Settings <><><><><><>"; // News
  96. input NewsCloseOrder newsClose = CloseAllRunningOrder; // On News Action on Running Orders
  97. input bool High_Impact_News = true; //High Impact News
  98. input int High_Start_Time = 60; //Stop Trade before high News (min)
  99. input int High_Stop_Time = 15; //Stop Trade after high News (min)
  100. input bool show_high_line = true; //Show verticle Line when high news comes
  101. input selectLine Select_News_Line = 0; //News Line
  102. input bool mobileAlert = true; //Mobile Alert
  103. input bool Medium_Impact_News = false; // Medium Impact News
  104. input int Medium_Start_Time = 60; // Stop Trade before medium News (min)
  105. input int Medium_Stop_Time = 15; // Stop Trade after medium News (min)
  106. input bool show_medium_line = false; // Show vertical Line when medium news comes
  107. input bool Low_Impact_News = false; // Low Impact News
  108. input int Low_Start_Time = 60; // Stop Trade before low News (min)
  109. input int Low_Stop_Time = 15; // Stop Trade after low News (min)
  110. input bool show_low_line = false; // Show vertical Line when low news comes
  111. // Global Variables
  112. static double tickCurrentBid = 0;
  113. double tickPreviousBid = 0;
  114. static double tickCurrentAsk = 0;
  115. double tickPreviousAsk = 0;
  116. datetime startSessionTime, endSessionTime;
  117. int GMT_Broker_Time = +2; // GMT_Broker_Time Time of your Broker
  118. int gmt = 0; // GMT_Broker_Time Time of your Broker
  119. string Lname="newsLabel3";
  120. //+------------------------------------------------------------------+
  121. //| |
  122. //+------------------------------------------------------------------+
  123. int OnInit()
  124. {
  125. //---
  126. Print(" OnInIt. ");
  127. trade.SetExpertMagicNumber(magic_no);
  128. trade.SetDeviationInPoints(maxSlippage);
  129. trade.SetTypeFilling(ORDER_FILLING_IOC);
  130. trade.LogLevel(LOG_LEVEL_ALL);
  131. trade.SetAsyncMode(false);
  132. int filehandle = FileOpen("vol_hedge_data.csv", FILE_READ | FILE_CSV | FILE_COMMON | FILE_ANSI);
  133. if(filehandle != INVALID_HANDLE)
  134. {
  135. Print(" Valid Handler. ");
  136. while(!FileIsEnding(filehandle))
  137. {
  138. string orderToRead = FileReadString(filehandle);
  139. string orderData[];
  140. //Print("Data: ", OrderToRead);
  141. StringSplit(orderToRead, StringGetCharacter(",",0), orderData);
  142. Print("Array Size: ", ArraySize(orderData));
  143. Print(" Order is: ", orderToRead);
  144. for(int i = 0 ; i < ArraySize(orderData) ; i++)
  145. {
  146. Print(" Order Data: ", orderData[i], " i: ", i);
  147. }
  148. if(ArraySize(orderData) >= 6)
  149. {
  150. if(orderData[0] == Symbol())
  151. {
  152. // store into local variables first (trim if needed)
  153. ulong buy_ticket_local = (ulong)-1; // keep -1 as per your convention
  154. ulong sell_ticket_local = (ulong)-1;
  155. string symbol_local = orderData[0];
  156. double price_local = StringToDouble(orderData[1]);
  157. double sl_local = StringToDouble(orderData[2]);
  158. double tp_local = StringToDouble(orderData[3]);
  159. // if your CSV has extra fields (tp2,tp3, etc.) parse here as needed
  160. datetime start_local = StringToTime(orderData[4]);
  161. datetime end_local = StringToTime(orderData[5]);
  162. // OPTIONAL: only add when price == 0:
  163. // if(MathAbs(price_local) > 1e-9) { Print("Skipped: price != 0"); continue; }
  164. // call the single-responsibility function that writes into struct array
  165. addToNewTradeStore(buy_ticket_local, sell_ticket_local,
  166. symbol_local, price_local,
  167. sl_local, tp_local,
  168. start_local, end_local);
  169. }
  170. }
  171. }
  172. FileClose(filehandle);
  173. }
  174. else
  175. {
  176. Print(" InValid Handler. Error: ", GetLastError());
  177. }
  178. timeFilter(true,start_time_session, end_time_session, startSessionTime, endSessionTime);
  179. Print(" Session Start = ", startSessionTime, " Asian Session End = ", endSessionTime);
  180. int timeDifference = (int)TimeCurrent() - (int)TimeGMT();
  181. Print("Time Difference is: ", timeDifference);
  182. if(timeDifference > 0)
  183. {
  184. GMT_Broker_Time = (int)MathRound((double)timeDifference / 3600.0);
  185. }
  186. else
  187. if(timeDifference < 0)
  188. {
  189. GMT_Broker_Time = (int)MathRound((double)timeDifference / 3600.0);
  190. }
  191. else // timeDifference == 0
  192. {
  193. GMT_Broker_Time = 0;
  194. }
  195. Print("Gmt Time: ", TimeGMT(), " Broker Gmt Time: ", GMT_Broker_Time);
  196. gmt = GMT_Broker_Time;
  197. if(!MQLInfoInteger(MQL_TESTER))
  198. {
  199. initiateNews(); // change here
  200. }
  201. //---
  202. return(INIT_SUCCEEDED);
  203. }
  204. //+------------------------------------------------------------------+
  205. //| Expert deinitialization function |
  206. //+------------------------------------------------------------------+
  207. void OnDeinit(const int reason)
  208. {
  209. //---
  210. }
  211. //+------------------------------------------------------------------+
  212. //| Expert tick function |
  213. //+------------------------------------------------------------------+
  214. void OnTick()
  215. {
  216. static int status=-1,preStatus=-1;
  217. if(!MQLInfoInteger(MQL_TESTER))
  218. {
  219. status=returnNewsStatus(High_Impact_News
  220. ,High_Start_Time
  221. ,High_Stop_Time
  222. ,show_high_line
  223. ,Medium_Impact_News
  224. ,Medium_Start_Time
  225. ,Medium_Stop_Time
  226. ,show_medium_line
  227. ,Low_Impact_News
  228. ,Low_Start_Time
  229. ,Low_Stop_Time
  230. ,show_low_line
  231. ,Symbol()
  232. ,MQLInfoString(MQL_PROGRAM_NAME)
  233. ,GMT_Broker_Time
  234. ,Select_News_Line
  235. ,""
  236. );
  237. }
  238. else
  239. status=0;
  240. if(status==0)
  241. {
  242. mainActivity();
  243. }
  244. if(status==1 || status==2 || status==3)
  245. {
  246. if(newsClose==0)
  247. {
  248. if(orderCount_1(POSITION_TYPE_BUY,magic_no)>0)
  249. closeTrades(POSITION_TYPE_BUY,magic_no);
  250. if(orderCount_1(POSITION_TYPE_SELL,magic_no)>0)
  251. closeTrades(POSITION_TYPE_SELL,magic_no);
  252. }
  253. else
  254. if(newsClose==1)
  255. {
  256. if((orderCount_1(POSITION_TYPE_BUY,magic_no)>0) || (orderCount_1(POSITION_TYPE_SELL,magic_no)>0))
  257. {
  258. mainActivity();
  259. }
  260. }
  261. }
  262. if(status!=preStatus)
  263. {
  264. if(status==0 && preStatus!=-1)
  265. {
  266. // if(ObjectFind(0,Lname))
  267. {
  268. // ObjectSetInteger(0,Lname,OBJPROP_COLOR,clrRed);
  269. ObjectSetString(0,Lname,OBJPROP_TEXT,"");
  270. }
  271. Alert("Trading is start");
  272. if(mobileAlert)
  273. SendNotification("Trading is start");
  274. preStatus=status;
  275. }
  276. else
  277. if(status==1)
  278. {
  279. ObjectSetInteger(0,Lname,OBJPROP_COLOR,clrRed);
  280. ObjectSetString(0,Lname,OBJPROP_TEXT,"High Impact News");
  281. Alert("Trading Stop due to high impact news");
  282. if(mobileAlert)
  283. SendNotification("Trading Stop due to high impact news");
  284. preStatus=status;
  285. }
  286. else
  287. if(status==2)
  288. {
  289. ObjectSetInteger(0,Lname,OBJPROP_COLOR,clrBlue);
  290. ObjectSetString(0,Lname,OBJPROP_TEXT,"Medium Impact News");
  291. Alert("Trading Stop due to medium impact news");
  292. if(mobileAlert)
  293. SendNotification("Trading Stop due to medium impact news");
  294. preStatus=status;
  295. }
  296. else
  297. if(status==3)
  298. {
  299. ObjectSetInteger(0,Lname,OBJPROP_COLOR,clrGreen);
  300. ObjectSetString(0,Lname,OBJPROP_TEXT,"Low Impact News");
  301. Alert("Trading Stop due to low impact news");
  302. if(mobileAlert)
  303. SendNotification("Trading Stop due to low impact news");
  304. preStatus=status;
  305. }
  306. }
  307. else
  308. {
  309. mainActivity();
  310. }
  311. }
  312. //+------------------------------------------------------------------+
  313. //| |
  314. //+------------------------------------------------------------------+
  315. void mainActivity()
  316. {
  317. //---
  318. if(indivial_trailing)
  319. {
  320. Individual_Trailing();
  321. }
  322. double Bid = SymbolInfoDouble(Symbol(), SYMBOL_BID);
  323. double Ask = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
  324. if(tickPreviousBid == 0 && tickCurrentBid == 0)
  325. {
  326. tickPreviousBid = Bid;
  327. tickCurrentBid = Bid;
  328. }
  329. else
  330. {
  331. tickPreviousBid = tickCurrentBid;
  332. tickCurrentBid = Bid;
  333. }
  334. if(tickPreviousAsk == 0 && tickCurrentAsk == 0)
  335. {
  336. tickPreviousAsk = Ask;
  337. tickCurrentAsk = Ask;
  338. }
  339. else
  340. {
  341. tickPreviousAsk = tickCurrentAsk;
  342. tickCurrentAsk = Ask;
  343. }
  344. // Print(" Time is: ", TimeCurrent());
  345. timeFilter(false,start_time_session, end_time_session, startSessionTime, endSessionTime);
  346. // Comment(" Session Start = ", startSessionTime, " Asian Session End = ", endSessionTime);
  347. if((!enableTimeSession) || (enableTimeSession && TimeCurrent() >= startSessionTime && TimeCurrent() <= endSessionTime))
  348. {
  349. tradePlacingCheck();
  350. if(bothHitsSl)
  351. {
  352. removeBuySellOnSlHit();
  353. }
  354. }
  355. }
  356. //+------------------------------------------------------------------+
  357. //+------------------------------------------------------------------+
  358. //| |
  359. //+------------------------------------------------------------------+
  360. void closeTrades(int type,int magicno)
  361. {
  362. Print("Total order: ",OrdersTotal());
  363. for(int i= PositionsTotal()-1; i>=0; i--)
  364. {
  365. // Print(" Selection: ",OrderSelect(i,SELECT_BY_POS)," i: ",i," OrdersTotal(): ", OrdersTotal());
  366. ulong ticket = PositionGetTicket(i);
  367. if(PositionSelectByTicket(ticket))
  368. {
  369. if(PositionGetInteger(POSITION_TYPE) == type)
  370. {
  371. if(PositionGetInteger(POSITION_MAGIC) == magicno && PositionGetString(POSITION_SYMBOL) == Symbol())
  372. {
  373. //trade.PositionClose(PositionGetInteger(POSITION_TICKET))
  374. if(!trade.PositionClose(PositionGetInteger(POSITION_TICKET)))
  375. {Print("Problem in closing order order ",PositionGetInteger(POSITION_TICKET)); }
  376. else
  377. {
  378. Print("Order Closed by closeTrades() new filter",PositionGetInteger(POSITION_TICKET));
  379. }
  380. }
  381. }
  382. }
  383. }
  384. }
  385. //+------------------------------------------------------------------+
  386. //| |
  387. //+------------------------------------------------------------------+
  388. int orderCount_1(int type,int magic)
  389. {
  390. int count1=0;
  391. for(int i= PositionsTotal()-1; i>=0; i--)
  392. {
  393. // Print(" Selection: ",OrderSelect(i,SELECT_BY_POS)," i: ",i," OrdersTotal(): ", OrdersTotal());
  394. ulong ticket = PositionGetTicket(i);
  395. if(PositionSelectByTicket(ticket))
  396. {
  397. // if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY || PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
  398. if(PositionGetInteger(POSITION_MAGIC) == magic && PositionGetString(POSITION_SYMBOL) == Symbol())
  399. {
  400. //trade.PositionClose(PositionGetInteger(POSITION_TICKET))
  401. if(PositionGetInteger(POSITION_TYPE) == type)
  402. {
  403. count1++;
  404. }
  405. }
  406. }
  407. }
  408. return count1;
  409. }
  410. //+------------------------------------------------------------------+
  411. //| |
  412. //+------------------------------------------------------------------+
  413. int orderCount(int type)
  414. {
  415. int count = 0;
  416. for(int i= PositionsTotal()-1; i>=0; i--)
  417. {
  418. ulong ticket = PositionGetTicket(i);
  419. if(PositionSelectByTicket(ticket))
  420. {
  421. if(PositionGetInteger(POSITION_MAGIC) == magic_no && PositionGetString(POSITION_SYMBOL) == Symbol())
  422. {
  423. if(PositionGetInteger(POSITION_TYPE) == type)
  424. {
  425. count++;
  426. }
  427. }
  428. }
  429. }
  430. return count;
  431. }
  432. //+------------------------------------------------------------------+
  433. //| |
  434. //+------------------------------------------------------------------+
  435. void addToNewTradeStore(ulong r_buy_ticket, ulong r_sell_ticket,
  436. string r_symbol, double r_price,
  437. double r_stop_loss, double r_take_profit,
  438. datetime r_start_time, datetime r_end_time)
  439. {
  440. for(int i = 0; i < MaxOrders; i++)
  441. {
  442. // treat slot as empty when both tickets are -1 (same convention as constructor)
  443. if(newTradeStore[i].buy_ticket == -1 && newTradeStore[i].sell_ticket == -1)
  444. {
  445. newTradeStore[i].buy_ticket = r_buy_ticket;
  446. newTradeStore[i].sell_ticket = r_sell_ticket;
  447. newTradeStore[i].symbol = r_symbol;
  448. newTradeStore[i].price = r_price;
  449. newTradeStore[i].stop_loss = r_stop_loss;
  450. newTradeStore[i].take_profit = r_take_profit;
  451. newTradeStore[i].start_time = r_start_time;
  452. newTradeStore[i].end_time = r_end_time;
  453. Print("Stored -> idx: ", i,
  454. " | sym: ", newTradeStore[i].symbol,
  455. " | price: ", DoubleToString(newTradeStore[i].price, Digits()),
  456. " | sl: ", DoubleToString(newTradeStore[i].stop_loss, Digits()),
  457. " | tp: ", DoubleToString(newTradeStore[i].take_profit, Digits()),
  458. " | start: ", TimeToString(newTradeStore[i].start_time, TIME_DATE|TIME_SECONDS),
  459. " | end: ", TimeToString(newTradeStore[i].end_time, TIME_DATE|TIME_SECONDS));
  460. break;
  461. }
  462. }
  463. }
  464. //+------------------------------------------------------------------+
  465. //| |
  466. //+------------------------------------------------------------------+
  467. void tradePlacingCheck()
  468. {
  469. for(int i = 0; i < MaxOrders; i++)
  470. {
  471. if(newTradeStore[i].buy_ticket == -1 && newTradeStore[i].sell_ticket == -1)
  472. {
  473. if(newTradeStore[i].price > 0)
  474. {
  475. if(TimeCurrent() > newTradeStore[i].start_time && TimeCurrent() < newTradeStore[i].end_time)
  476. {
  477. double levelPriceIs = newTradeStore[i].price;
  478. if((tickPreviousBid > levelPriceIs && tickCurrentBid < levelPriceIs) ||
  479. (tickPreviousBid < levelPriceIs && tickCurrentBid > levelPriceIs))
  480. {
  481. if(countLiveTrades() < maxTrades)
  482. {
  483. if((enableSpreadFilter && spreadFilter()) || !enableSpreadFilter)
  484. {
  485. ulong buyTicket = placeBuyTrade(newTradeStore[i].stop_loss, newTradeStore[i].take_profit);
  486. ulong sellTicket = placeSellTrade(newTradeStore[i].stop_loss, newTradeStore[i].take_profit);
  487. newTradeStore[i].buy_ticket = buyTicket;
  488. newTradeStore[i].sell_ticket = sellTicket;
  489. }
  490. }
  491. }
  492. }
  493. }
  494. }
  495. }
  496. }
  497. //+------------------------------------------------------------------+
  498. //| |
  499. //+------------------------------------------------------------------+
  500. ulong placeBuyTrade(double stoploss, double takeprofit)
  501. {
  502. double buySL = 0, buyTp=0;
  503. //openPrice = SymbolInfoDouble(Symbol(),SYMBOL_ASK);
  504. double Ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK);
  505. double Bid = SymbolInfoDouble(Symbol(),SYMBOL_BID);
  506. if(stoploss != 0)
  507. {
  508. buySL = Ask - (stoploss * Point());
  509. }
  510. if(takeprofit != 0)
  511. {
  512. buyTp = Ask + (takeprofit * Point());
  513. }
  514. double distance = MathAbs((Ask - buySL) / Point());
  515. if(trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,getLot(distance),Ask,buySL,buyTp,"Buy Trade Placed"))
  516. {
  517. Print("Buy Trade Placed: ",trade.ResultOrder());
  518. return trade.ResultOrder();
  519. }
  520. else
  521. {
  522. Print("Error in placing Buy: "+Symbol()+" ",GetLastError());
  523. return -1;
  524. }
  525. return -1;
  526. }
  527. //+------------------------------------------------------------------+
  528. //| |
  529. //+------------------------------------------------------------------+
  530. ulong placeSellTrade(double stoploss, double takeprofit)
  531. {
  532. double sellSL = 0, sellTp = 0;
  533. double Ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK);
  534. double Bid = SymbolInfoDouble(Symbol(),SYMBOL_BID);
  535. if(stoploss != 0)
  536. {
  537. sellSL = Bid + (stoploss * Point());
  538. }
  539. if(takeprofit != 0)
  540. {
  541. sellTp = Bid - (takeprofit * Point());
  542. }
  543. double distance = MathAbs((Bid - sellSL) / Point());
  544. if(trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,getLot(distance),Bid,sellSL,sellTp,"Sell Trade Placed"))
  545. {
  546. Print("Sell Trade PLaced: ",trade.ResultOrder());
  547. return trade.ResultOrder();
  548. }
  549. else
  550. {
  551. Print("Error in placing Sell: "+Symbol()+" ",GetLastError());
  552. return -1;
  553. }
  554. return -1;
  555. }
  556. //+------------------------------------------------------------------+
  557. //| |
  558. //+------------------------------------------------------------------+
  559. double getLot(double stop_loss)
  560. {
  561. Print("Tick Value: ",SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE));
  562. Print("Tick Size: ",SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE));
  563. double modeTickV=SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)
  564. ,modeTickS=SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE);
  565. // Print("Pip value: ", NormalizeDouble(((SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)/(SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE)/Point))*10),2));
  566. double pipvalue = NormalizeDouble(((SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_VALUE)/(SymbolInfoDouble(Symbol(),SYMBOL_TRADE_TICK_SIZE)/Point()))*10),2);
  567. // pipvalue=NormalizeDouble((modeTickV/modeTickS/Point()),)
  568. // pipvalue=
  569. pipvalue = pipvalue / 10;
  570. double lotSize = lot_amount;
  571. if(lot_calculator == rsk || lot_calculator == dollar) //calculating risk
  572. {
  573. double riskamount = 0;
  574. if(lot_calculator == rsk)
  575. {
  576. riskamount = (risk/100)*AccountInfoDouble(ACCOUNT_BALANCE);
  577. }
  578. if(lot_calculator == dollar)
  579. {
  580. riskamount = dollars;
  581. }
  582. double pipvalue_required=riskamount/stop_loss;
  583. lotSize = pipvalue_required/pipvalue;
  584. //sl=riskamount/pipValuelot
  585. int roundDigit=0;
  586. double step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);
  587. while(step<1)
  588. {
  589. roundDigit++;
  590. step=step*10;
  591. }
  592. Print("Round Digits:",roundDigit);
  593. lotSize = NormalizeDouble(lotSize,roundDigit);
  594. //
  595. }
  596. Print("Lot Size: ",lotSize);
  597. if(lotSize > SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX))
  598. {
  599. lotSize=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
  600. }
  601. else
  602. if(lotSize<SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN))
  603. {
  604. lotSize=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
  605. }
  606. //---
  607. return lotSize;
  608. }
  609. //+------------------------------------------------------------------+
  610. //| |
  611. //+------------------------------------------------------------------+
  612. void timeFilter(bool onInit,string startTime,string endTime,datetime & sessionStart,datetime & sessionEnd)
  613. {
  614. int newYorkStartHour = 0, newYorkStartMin = 0, newYorkEndHour = 0, newYorkEndMin = 0;
  615. datetime newYorkStartTrading,newYorkEndTrading;
  616. string time[];
  617. StringSplit(startTime,':',time);
  618. newYorkStartHour = (int)StringToInteger(time[0]);
  619. newYorkStartMin = (int)StringToInteger(time[1]);
  620. EventSetMillisecondTimer(500);
  621. time[0] = "";
  622. time[1] = "";
  623. StringSplit(endTime,':',time);
  624. newYorkEndHour = (int)StringToInteger(time[0]);
  625. newYorkEndMin = (int)StringToInteger(time[1]);
  626. // Print(" Start Time Hour: ",newYorkStartHour," Start Time Min: ",newYorkStartMin);
  627. // Print(" End Time Hour: ",newYorkEndHour," End Time Min: ",newYorkEndMin);
  628. datetime startDateTime;
  629. MqlDateTime st;
  630. TimeCurrent(st); // get current date
  631. st.hour = newYorkStartHour;
  632. st.min = newYorkStartMin;
  633. st.sec = 0;
  634. startDateTime = StructToTime(st);
  635. datetime endDateTime;
  636. MqlDateTime et;
  637. TimeCurrent(et); // get current date
  638. et.hour = newYorkEndHour;
  639. et.min = newYorkEndMin;
  640. et.sec = 0;
  641. endDateTime = StructToTime(et);
  642. MqlDateTime sdate,edate;
  643. datetime start_Time = 0, end_Time = 0;
  644. if(startDateTime > endDateTime)
  645. {
  646. if(onInit)
  647. {
  648. start_Time = iTime(Symbol(),PERIOD_D1,1);
  649. end_Time = iTime(Symbol(),PERIOD_D1,0);
  650. }
  651. else
  652. {
  653. start_Time = sessionStart;
  654. end_Time = sessionEnd;
  655. if(TimeCurrent() >= sessionEnd && sessionEnd != 0)
  656. {
  657. start_Time = iTime(Symbol(),PERIOD_D1,0);
  658. end_Time = start_Time + 86400;
  659. }
  660. }
  661. }
  662. else
  663. {
  664. start_Time = iTime(Symbol(),PERIOD_D1,0);
  665. end_Time = iTime(Symbol(),PERIOD_D1,0);
  666. }
  667. if(TimeToStruct(end_Time,edate))
  668. {
  669. edate.hour = newYorkEndHour;
  670. edate.min = newYorkEndMin;
  671. edate.sec = 0;
  672. }
  673. else
  674. Print("Error in Converting Time: ",GetLastError());
  675. newYorkEndTrading = StructToTime(edate);
  676. if(TimeToStruct(start_Time,sdate))
  677. {
  678. sdate.hour = newYorkStartHour;
  679. sdate.min = newYorkStartMin;
  680. sdate.sec = 0;
  681. }
  682. else
  683. Print("Error in Converting Time: ",GetLastError());
  684. newYorkStartTrading = StructToTime(sdate);
  685. sessionStart = newYorkStartTrading;
  686. sessionEnd = newYorkEndTrading;
  687. }
  688. //+------------------------------------------------------------------+
  689. //| |
  690. //+------------------------------------------------------------------+
  691. void removeBuySellOnSlHit()
  692. {
  693. for(int i = 0 ; i < MaxOrders ; i++)
  694. {
  695. bool isBuyPresent=false, isSellPresent=false;
  696. if(newTradeStore[i].buy_ticket != -1 && newTradeStore[i].sell_ticket != -1)
  697. {
  698. for(int j = PositionsTotal()-1; j>=0; j--)
  699. {
  700. ulong ticket = PositionGetTicket(j);
  701. if(PositionSelectByTicket(ticket))
  702. {
  703. if(ticket == newTradeStore[i].buy_ticket)
  704. {
  705. isBuyPresent=true;
  706. }
  707. }
  708. }
  709. for(int j = PositionsTotal()-1; j>=0; j--)
  710. {
  711. ulong ticket = PositionGetTicket(j);
  712. if(PositionSelectByTicket(ticket))
  713. {
  714. if(ticket == newTradeStore[i].sell_ticket)
  715. {
  716. isSellPresent = true;
  717. }
  718. }
  719. }
  720. if(!isBuyPresent && !isSellPresent)
  721. {
  722. if(tradeHitSL(newTradeStore[i].buy_ticket) && tradeHitSL(newTradeStore[i].sell_ticket))
  723. {
  724. Print("Buy/Sell Ticket is closed on StopLoss so removed from struct. Buy Ticket: ", newTradeStore[i].buy_ticket, " Sell Ticket: ", newTradeStore[i].sell_ticket);
  725. newTradeStore[i].buy_ticket = (ulong)-1;
  726. newTradeStore[i].sell_ticket = (ulong)-1;
  727. //newTradeStore[i].symbol = "";
  728. //newTradeStore[i].price = 0.0;
  729. //newTradeStore[i].stop_loss = 0.0;
  730. //newTradeStore[i].take_profit = 0.0;
  731. //newTradeStore[i].start_time = 0;
  732. //newTradeStore[i].end_time = 0;
  733. }
  734. }
  735. }
  736. }
  737. }
  738. //+------------------------------------------------------------------+
  739. //| |
  740. //+------------------------------------------------------------------+
  741. bool tradeHitSL(ulong positionID)
  742. {
  743. if(HistorySelectByPosition(positionID))
  744. {
  745. for(int i = 0; i < HistoryDealsTotal(); i++)
  746. {
  747. ulong dealTicket = HistoryDealGetTicket(i);
  748. ulong dealPositionID = HistoryDealGetInteger(dealTicket, DEAL_POSITION_ID);
  749. if(HistoryDealGetInteger(dealTicket, DEAL_ENTRY) == DEAL_ENTRY_OUT && dealPositionID == positionID)
  750. {
  751. int dealType = (int)HistoryDealGetInteger(dealTicket, DEAL_TYPE);
  752. string comment = HistoryDealGetString(dealTicket, DEAL_COMMENT);
  753. if(StringFind(comment, "sl", 0) >= 0)
  754. {
  755. // if(dealType == DEAL_TYPE_BUY)
  756. // {
  757. //
  758. // }
  759. return true;
  760. }
  761. }
  762. }
  763. }
  764. return false;
  765. }
  766. //+------------------------------------------------------------------+
  767. //| |
  768. //+------------------------------------------------------------------+
  769. int countLiveTrades()
  770. {
  771. int count = 0;
  772. for(int i = 0; i < PositionsTotal(); i++)
  773. {
  774. ulong ticket = PositionGetTicket(i);
  775. if(PositionSelectByTicket(ticket))
  776. {
  777. if(PositionGetInteger(POSITION_MAGIC) == magic_no)
  778. {
  779. if(PositionGetString(POSITION_SYMBOL) == Symbol())
  780. {
  781. if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY || PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
  782. {
  783. count++;
  784. }
  785. }
  786. }
  787. }
  788. }
  789. return count;
  790. }
  791. //+------------------------------------------------------------------+
  792. //| |
  793. //+------------------------------------------------------------------+
  794. bool spreadFilter()
  795. {
  796. long spreadIs = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD);
  797. if(spreadIs > maximumSpread)
  798. {
  799. return false;
  800. }
  801. return true;
  802. }
  803. //+------------------------------------------------------------------+
  804. //| |
  805. //+------------------------------------------------------------------+
  806. void Individual_Trailing()
  807. {
  808. int openedpositions;
  809. double mySL,myResult;
  810. openedpositions=PositionsTotal();
  811. if((openedpositions>0))
  812. {
  813. int totalorders=PositionsTotal();
  814. for(int i=0; i<totalorders; i++) // scan all orders and positions. ..
  815. {
  816. ulong ticket = PositionGetTicket(i);
  817. if(PositionSelectByTicket(ticket))
  818. {
  819. if(PositionGetString(POSITION_SYMBOL)==Symbol() && PositionGetInteger(POSITION_MAGIC) ==magic_no) // only look if mygrid and symbol. ..
  820. {
  821. double SymbolAsk = SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_ASK);
  822. double SymbolBid = SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_BID);
  823. int SymbolDigits = (int)SymbolInfoInteger(PositionGetString(POSITION_SYMBOL), SYMBOL_DIGITS);
  824. double SymbolTickSize = SymbolInfoDouble(PositionGetString(POSITION_SYMBOL), SYMBOL_TRADE_TICK_SIZE);
  825. int type= (int)PositionGetInteger(POSITION_TYPE);
  826. if(type==POSITION_TYPE_BUY) // its a long position
  827. {
  828. mySL=NormalizeDouble(SymbolAsk-(ts*SymbolTickSize*10),Digits()); // new SL
  829. double startSl=PositionGetDouble(POSITION_PRICE_OPEN)+(ts_sl*SymbolTickSize*10);
  830. if(PositionGetDouble(POSITION_SL) != mySL)
  831. if(mySL>PositionGetDouble(POSITION_SL) && SymbolAsk>=startSl)
  832. {
  833. myResult=trade.PositionModify(ticket,mySL,PositionGetDouble(POSITION_TP)); //OrderModify(OrderTicket(),OrderOpenPrice(),mySL,OrderTakeProfit(),0,clrGreen);
  834. if(!myResult)
  835. {
  836. Print(" Buy Trade Trailing Error: ",GetLastError());
  837. }
  838. }
  839. }
  840. if(type==POSITION_TYPE_SELL)
  841. {
  842. mySL=NormalizeDouble(SymbolBid+(ts*SymbolTickSize*10),Digits()); // new SL
  843. double startSlSell=PositionGetDouble(POSITION_PRICE_OPEN)-(ts_sl*SymbolTickSize*10);
  844. if(PositionGetDouble(POSITION_SL) != mySL)
  845. if(((mySL<PositionGetDouble(POSITION_SL)) || (PositionGetDouble(POSITION_SL)<SymbolTickSize)) && SymbolBid<=startSlSell)
  846. {
  847. myResult=trade.PositionModify(ticket,mySL,PositionGetDouble(POSITION_TP)); //OrderModify(OrderTicket(),OrderOpenPrice(),mySL,OrderTakeProfit(),0,clrRed);
  848. if(!myResult)
  849. {
  850. Print(" Sell Trade Trailing Error: ",GetLastError());
  851. }
  852. }
  853. }
  854. }
  855. }
  856. }
  857. }
  858. }
  859. //+------------------------------------------------------------------+
  860. //| |
  861. //+------------------------------------------------------------------+
  862. //+------------------------------------------------------------------+