Ei kuvausta

vol_hedge_strategy_mt5.mq5 32KB

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