Author: Copyright � 2011, Murad Ismayilov
Price Data Components
Series array that contains close prices for each barSeries array that contains close prices for each bar
Orders Execution
Checks for the total of open ordersChecks for the total of closed ordersIt automatically opens orders when conditions are reachedIt Closes Orders by itself
Indicators Used
Indicator of the average true range
Miscellaneous
It plays sound alerts
0 Views
0 Downloads
0 Favorites
Wm9
#property copyright "Copyright © 2011, Murad Ismayilov"
#property link      "http://www.mql4.com/ru/users/wmlab/"

#include <stdlib.mqh>
#include <stderror.mqh>

#define MAXBARS 100

//
// Âíåøíèå ïåðåìåííûå
//

extern double Lots = 0.01; // Êàêèì ëîòîì èãðàåì
extern double KAtr = 2.0;
extern int MagicNumber = 9840;
extern color ColorBuy = RoyalBlue;
extern color ColorSell = Tomato;
extern color ColorLine = SeaGreen;

//
// Ãëîáàëüíûå ïåðåìåííûå
//

string ExpertObjectPrefix = "Wm9";

//+------------------------------------------------------------------+
//| Ñòàðò ðîáîòà                                                     |
//+------------------------------------------------------------------+

int init()
{
   if (!IsTesting())
   {
      if (IsExpertEnabled())
      {
         Comment("Ñîâåòíèê áóäåò çàïóùåí ñëåäóþùèì òèêîì");
      }
      else 
      {
         Comment("Îòæàòà êíîïêà \"Ðàçðåøèòü çàïóñê ñîâåòíèêîâ\"");
      }
   }
   
   ClearAllObjectsWithPrefix(ExpertObjectPrefix);
   
   return (0);
}
  
//+------------------------------------------------------------------+
//| Çàâåðøåíèå ðàáîòû ðîáîòà                                         |
//+------------------------------------------------------------------+

int deinit()
{
   Comment("");
   
   ClearAllObjectsWithPrefix(ExpertObjectPrefix);

   return (0);
}

//+------------------------------------------------------------------+
//| Óäàëåíèå âñåõ íàøèõ îáúåêòîâ                                     |
//+------------------------------------------------------------------+

void ClearAllObjectsWithPrefix(string prefix)
{
   for (int indexObject = (ObjectsTotal() - 1); indexObject >= 0; indexObject--)
   {
      string objectName = ObjectName(indexObject);
      if (StringFind(objectName, prefix) == 0)
      {
         ObjectDelete(objectName);
      }
   }
}

//+------------------------------------------------------------------+
//| Ïîëó÷åíèå ÷èñëà îðäåðîâ                                          |
//+------------------------------------------------------------------+

int GetNumberOfOrders()
{
   int orders = 0;
   for (int orderIndex = (OrdersTotal() - 1); orderIndex >= 0; orderIndex--)
   {
      if (OrderSelect(orderIndex, SELECT_BY_POS))
      {
         if ((OrderSymbol() == Symbol()) && (OrderMagicNumber() == MagicNumber))
         {
            if ((OrderType() == OP_BUY) || (OrderType() == OP_SELL))
            {
               orders++;
            }
         }
      }
   }
   
   return (orders);
}

//+------------------------------------------------------------------+
//| Óäàëåíèå ìóñîðà ñ ãðàôèêà                                        |
//+------------------------------------------------------------------+

void WmClearAndDrawOrders(int magic, color colorBuy, color colorSell)
{
   static int clearTime = 0;

   int currentTime = TimeCurrent();
   if ((currentTime - clearTime) < 60)
   {
      return;      
   }
   
   clearTime = currentTime;

   for (int indexObject = (ObjectsTotal() - 1); indexObject >= 0; indexObject--)
   {
      string nameObject = ObjectName(indexObject);
      int firstChar = StringGetChar(nameObject, 0);
      if (firstChar != '#')
      {
         continue;
      }
      
      int posSpace = StringFind(nameObject, " ");
      if (posSpace < 2)
      {
         continue;
      }
      
      string strTicket = StringSubstr(nameObject, 1, posSpace - 1);
      int ticket = StrToInteger(strTicket);
      if (!ExistOrderTicket(Symbol(), magic, ticket))
      {
         ObjectDelete(nameObject);
      }
   }
   
   for (int indexOrder = 0; indexOrder < OrdersHistoryTotal(); indexOrder++)
   {
      if (!OrderSelect(indexOrder, SELECT_BY_POS, MODE_HISTORY))
      {
         continue;
      }
      
      if (OrderSymbol() != Symbol())
      {
         continue;
      }
   
      if ((magic != 0) && (OrderMagicNumber() != magic))
      {
         continue;
      }
      
      int orderType = OrderType();
      if ((orderType != OP_BUY) && (orderType != OP_SELL))
      {
         continue;
      }
      
      color clr;
      if (orderType == OP_BUY)
      {
         clr = colorBuy;
      }
      else
      {
         clr = colorSell;
      }

      strTicket = DoubleToStr(OrderTicket(), 0);      
      string strOpen = WindowExpertName() + "s" + strTicket;
      if (ObjectFind(strOpen) == -1)
      {
         ObjectCreate(strOpen, OBJ_ARROW, 0, OrderOpenTime(), OrderOpenPrice());
         ObjectSet(strOpen, OBJPROP_ARROWCODE, 1);
         ObjectSet(strOpen, OBJPROP_COLOR, clr);
      }
      
      string strTrend = WindowExpertName() + "t" + strTicket;
      if (ObjectFind(strTrend) == -1)
      {
         ObjectCreate(strTrend, OBJ_TREND, 0, OrderOpenTime(), OrderOpenPrice(), OrderCloseTime(), OrderClosePrice());
         ObjectSet(strTrend, OBJPROP_STYLE, STYLE_DOT);
         ObjectSet(strTrend, OBJPROP_WIDTH, 1);
         ObjectSet(strTrend, OBJPROP_COLOR, clr);
         ObjectSet(strTrend, OBJPROP_RAY, false);
      }      
      
      string strClose = WindowExpertName() + "f" + strTicket;
      if (ObjectFind(strClose) == -1)
      {
         ObjectCreate(strClose, OBJ_ARROW, 0, OrderCloseTime(), OrderClosePrice());
         ObjectSet(strClose, OBJPROP_ARROWCODE, 3);
         ObjectSet(strClose, OBJPROP_COLOR, clr);
      }
   }
}

//+------------------------------------------------------------------+
//| Ñòðîêîâîå çíà÷åíèå òàéìôðåéìà                                    |
//+------------------------------------------------------------------+

string GetNameTF(int timeFrame)
{
   switch (timeFrame)
   {
      case PERIOD_M1:  return ("M1");
      case PERIOD_M5:  return ("M5");
      case PERIOD_M15: return ("M15");
      case PERIOD_M30: return ("M30");
      case PERIOD_H1:  return ("H1");
      case PERIOD_H4:  return ("H4");
      case PERIOD_D1:  return ("Daily");
      case PERIOD_W1:  return ("Weekly");
      case PERIOD_MN1: return ("Monthly");
      default:         return (DoubleToStr(timeFrame, 0));
   }
}

//+------------------------------------------------------------------+
//| Ñòðîêîâîå çíà÷åíèå îïåðàöèè                                      |
//+------------------------------------------------------------------+

string GetNameOP(int cmd)
{
   switch (cmd)
   {
      case OP_BUY      : return ("Buy");
      case OP_SELL     : return ("Sell");
      case OP_BUYLIMIT : return ("Buy Limit");
      case OP_SELLLIMIT: return ("Sell Limit");
      case OP_BUYSTOP  : return ("Buy Stop");
      case OP_SELLSTOP : return ("Sell Stop");
      default          : return (DoubleToStr(cmd, 0));
   }
}

//+------------------------------------------------------------------+
//| Íîðìàëèçàöèÿ ëîòà                                                |
//+------------------------------------------------------------------+

double NormalizeLots(double lot)
{
   double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
   double lots = NormalizeDouble(lot / lotStep, 0) * lotStep;   
   lots = MathMax(lots, MarketInfo(Symbol(), MODE_MINLOT));
   lots = MathMin(lots, MarketInfo(Symbol(), MODE_MAXLOT));   
   return (lots);
}

//+------------------------------------------------------------------+
//| Ïðîâåðêà ñóùåñòâîâàíèÿ îðäåðà                                    |
//+------------------------------------------------------------------+

bool ExistOrders(string symbol, int cmd, int magic, datetime opentime = 0)
{
   int orderType;
   for (int i = 0; i < OrdersTotal(); i++)
   {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
      {
         orderType = OrderType();
         if ((orderType > 1) && (orderType < 6))
         {
            if (OrderSymbol() == symbol)
            {
               if (OrderMagicNumber() == magic)
               {
                  if (opentime <= OrderOpenTime()) 
                  return (true);
               }
            }
         }
      }
   }
  
   return (false);
}

//+------------------------------------------------------------------+
//| Ïðîâåðêà ñóùåñòâîâàíèÿ îðäåðà                                    |
//+------------------------------------------------------------------+

bool ExistOrderTicket(string symbol, int magic, int ticket)
{
   for (int orderIndex = (OrdersTotal() - 1); orderIndex >= 0; orderIndex--)
   {
      if (!OrderSelect(orderIndex, SELECT_BY_POS))
      {
         continue;
      }

      if (OrderSymbol() != Symbol())
      {
         continue;
      }
      
      if ((magic != 0) && (OrderMagicNumber() != magic))
      {
         continue;
      }

      if (OrderTicket() != ticket)
      {
         continue;
      }
      
      return (true);
   }
  
   return (false);
}

//+------------------------------------------------------------------+
//| Óñòàíîâêà îðäåðà                                                 |
//+------------------------------------------------------------------+

void WmOrderSend(string symbol, int cmd, double volume, double price, double stoploss, double takeprofit, string comment, int magic, datetime expiration = 0, color clr = CLR_NONE)
{
   comment = WindowExpertName() + " " + GetNameTF(Period()) + " " + comment;
   int msl = MarketInfo(symbol, MODE_STOPLEVEL);
   if ((expiration > 0) && (expiration < TimeCurrent())) 
   {
      expiration = 0;
   }
  
   for (int try = 1; try <= 3; try++)
   {
      if (!IsTesting() && (!IsExpertEnabled() || IsStopped()))
      {
         break;
      }
   
      while (!IsTradeAllowed()) 
      {
         Sleep(5000);
      }
    
      if (cmd == OP_BUY)
      {
         price = MarketInfo(Symbol(), MODE_ASK);
      }
      else
      {
         if (cmd == OP_SELL)
         {
            price = MarketInfo(Symbol(), MODE_BID);
         }
      }
      
      datetime opentime = TimeCurrent();
      int ticket = OrderSend(symbol, cmd, volume, price, 20, stoploss, takeprofit, comment, magic, expiration, clr);
      if (ticket > 0)
      {
         PlaySound("ok.wav"); 
         break;
      } 
      
      int error = GetLastError();
      Print("Error(", error, ") set order: ", ErrorDescription(error), ", try ", try);
      Print("Ask=", Ask, "  Bid=", Bid, "  symbol=", symbol, "  volume=", volume, "  cmd=", GetNameOP(cmd), "  price=", price, "  stoploss=", stoploss, "  takeprofit=", stoploss);
      
      if (error == ERR_TRADE_TIMEOUT)
      {
         Sleep(10000);
         if (ExistOrders(symbol, cmd, magic, opentime))
         {
            PlaySound("ok.wav");                
            break;
         }
      }
        
      if (
         (error == ERR_COMMON_ERROR) || 
         (error == ERR_ACCOUNT_DISABLED) || 
         (error == ERR_INVALID_ACCOUNT) || 
         (error == ERR_TRADE_DISABLED)
         )
      {
         break;
      }
      
      if (
         (error == ERR_SERVER_BUSY) || 
         (error == ERR_INVALID_TRADE_VOLUME) || 
         (error == ERR_MARKET_CLOSED)
         )
      {
         Sleep(1000*300); 
         break;
      }
      
      if (
         (error == ERR_TOO_FREQUENT_REQUESTS) || 
         (error == ERR_TOO_MANY_REQUESTS)
         )
      {
         Sleep(1000*100);
      }
      
      if (
         (error == ERR_ORDER_LOCKED) || 
         (error == ERR_LONG_POSITIONS_ONLY_ALLOWED) || 
         (error == ERR_TRADE_TOO_MANY_ORDERS) || 
         (error == ERR_INVALID_PRICE)
         )
      {
         break;
      }
      
      if (error == ERR_TRADE_CONTEXT_BUSY) 
      {
         while (IsTradeContextBusy()) 
         {
            Sleep(1000*11);
         }
      }
      
      if (error == ERR_TRADE_EXPIRATION_DENIED )
      {
         expiration = 0; 
         continue;
      }
      
      if ((error != ERR_PRICE_CHANGED) && (error != ERR_REQUOTE)) 
      {
         Sleep(1000*7.7);
      }
   }      
}

//+------------------------------------------------------------------+
//| Çàêðûòèå âûáðàííîé ïîçèöèè                                       |
//+------------------------------------------------------------------+

void WmOrderClose(double volume = 0.0)
{
   if ((OrderType() == OP_BUY) || (OrderType() == OP_SELL))
   {
      for (int try = 1; try <= 3; try++)
      {
         if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) 
         {
            break;
         }
         
         while (!IsTradeAllowed()) 
         {
            Sleep(5000);
         }

         double price;      
         RefreshRates();
         if (OrderType() == OP_BUY)
         {
            price = Bid; 
         } 
         else
         {
            price = Ask; 
         }

         if (volume == 0.0)
         {
            volume = OrderLots();
         }
         
         if (OrderClose(OrderTicket(), volume, price, 20))
         {
            PlaySound("expert.wav");
            break;
         } 
         else
         {
            int error = GetLastError();
            Print("Error(", error, ") close order: ", ErrorDescription(error), ", try ", try);
            Print("Ask=", Ask, "  Bid=", Bid, "  symbol=", Symbol(), "  price=", price, "  volume=", volume);
      
            if (error == ERR_TRADE_TIMEOUT)
            {
               Sleep(10000);
            }
        
            if (
               (error == ERR_COMMON_ERROR) || 
               (error == ERR_ACCOUNT_DISABLED) || 
               (error == ERR_INVALID_ACCOUNT) || 
               (error == ERR_TRADE_DISABLED)
               )
            {
               break;
            }
      
            if (
               (error == ERR_SERVER_BUSY) || 
               (error == ERR_INVALID_TRADE_VOLUME) || 
               (error == ERR_MARKET_CLOSED)
               )
            {
               Sleep(1000*300); 
               break;
            }
      
            if (
               (error == ERR_TOO_FREQUENT_REQUESTS) || 
               (error == ERR_TOO_MANY_REQUESTS)
               )
            {
               Sleep(1000*100);
            }
      
            if (
               (error == ERR_ORDER_LOCKED) || 
               (error == ERR_LONG_POSITIONS_ONLY_ALLOWED) || 
               (error == ERR_TRADE_TOO_MANY_ORDERS) || 
               (error == ERR_INVALID_PRICE)
               )
            {
               break;
            }
      
            if (error == ERR_TRADE_CONTEXT_BUSY) 
            {
               while (IsTradeContextBusy()) 
               {
                  Sleep(1000*11);
               }
            }
           
            if ((error != ERR_PRICE_CHANGED) && (error != ERR_REQUOTE)) 
            {
               Sleep(1000*7.7);
            }
         }
      }
   } 
   else 
   {
      Print("Incorrect Close ", GetNameOP(OrderType()));
   }
}

//+------------------------------------------------------------------+
//| Çàêðûòèå âñåõ ïîçèöèé                                            |
//+------------------------------------------------------------------+

void CloseAllOrders(int magic, int cmd)
{
   for (int orderIndex = (OrdersTotal() - 1); orderIndex >= 0; orderIndex--)
   {
      if (OrderSelect(orderIndex, SELECT_BY_POS))
      {
         if ((OrderSymbol() == Symbol()) && (OrderMagicNumber() == magic))
         {
            if ((OrderType() != OP_BUY) && (OrderType() != OP_SELL))
            {
               OrderDelete(OrderTicket());
            }
            else
            {
               if (OrderType() == cmd)
               {
                  WmOrderClose();
               }
            }
         }
      }
   }
}

//+------------------------------------------------------------------+
//| Ïîÿâèëñÿ íîâûé áàð?                                              |
//+------------------------------------------------------------------+

bool IsNewBar()
{
   static datetime prevTime = 0;

   datetime currentTime = iTime(NULL, 0, 0);
   if (prevTime == currentTime)
   {
      return (false);
   }

   prevTime = currentTime;
   return (true);
}

//+------------------------------------------------------------------+
//| Îáðàáîòêà ñèãíàëà                                                |
//+------------------------------------------------------------------+
  
int start() 
{
   static int Wm9Bars = 0;
   static double Wm9Close[MAXBARS];
   static double Wm9MA[MAXBARS];

   if (!IsTradeAllowed())
   {
      Comment("Íåîáõîäèìî ðàçðåøèòü ñîâåòíèêó òîðãîâàòü");
      return (0);
   }
  
   if (!IsOptimization())
   {
      WmClearAndDrawOrders(MagicNumber, ColorBuy, ColorSell);
   }
   
   if (!IsNewBar())
   {
      return;
   }

   if (Wm9Bars == 0)
   {
      Wm9Close[0] = iClose(NULL, 0, 0);
      Wm9Bars = 1;
   }
   
   double currentClose = iClose(NULL, 0, 0);
   double diffInPips = MathAbs(currentClose - Wm9Close[0]) / Point;
   double barPipsFive = KAtr * iATR(NULL, 0, 60, 1) / Point;
   
   Comment("Wm9Bars = ", Wm9Bars, " diffInPips = ", diffInPips, " barPipsFive = ", barPipsFive);   
   
   if (diffInPips <= barPipsFive)
   {
      return;   
   }
   
   int indexBar;
   for (indexBar = (MAXBARS - 1); indexBar >= 1; indexBar--)
   {
      Wm9Close[indexBar] = Wm9Close[indexBar - 1];
   }
   
   Wm9Close[0] = currentClose;
   
   Wm9Bars++;
   if (Wm9Bars > MAXBARS)
   {
      Wm9Bars = MAXBARS;
   }
   
   if (Wm9Bars < 2)
   {
      return;
   }   
   
   if (!IsOptimization())
   {
      string rayName;
   
      for (indexBar = 1; indexBar < Wm9Bars; indexBar++)
      {
         rayName = ExpertObjectPrefix + DoubleToStr(indexBar, 0);
         if (ObjectFind(rayName) != -1)
         {
            ObjectSet(rayName, OBJPROP_TIME1, Time[indexBar]);
            ObjectSet(rayName, OBJPROP_PRICE1, Wm9Close[indexBar]);
            ObjectSet(rayName, OBJPROP_TIME2, Time[indexBar - 1]);
            ObjectSet(rayName, OBJPROP_PRICE2, Wm9Close[indexBar - 1]);
            ObjectSet(rayName, OBJPROP_COLOR, ColorLine);
         }
         else
         {
            ObjectCreate(rayName, OBJ_TREND, 0, Time[indexBar], Wm9Close[indexBar], Time[indexBar - 1], Wm9Close[indexBar - 1]);
            ObjectSet(rayName, OBJPROP_STYLE, STYLE_SOLID);
            ObjectSet(rayName, OBJPROP_WIDTH, 3);
            ObjectSet(rayName, OBJPROP_COLOR, ColorLine);
            ObjectSet(rayName, OBJPROP_RAY, false);         
         }        
      }

      for (indexBar = indexBar + 1; indexBar < MAXBARS; indexBar++)
      {
         rayName = ExpertObjectPrefix + DoubleToStr(indexBar, 0);
         if (ObjectFind(rayName) != -1)
         {
            ObjectDelete(rayName);
         }         
      }
   }
   
   if (Wm9Bars < 3)
   {
      return;
   }

   if (GetNumberOfOrders() == 0)
   {
      double lots = NormalizeLots(Lots);
      int slpips = barPipsFive;
      double sl, tp;
      
      if ((Wm9Close[0] > Wm9Close[1]) && (Wm9Close[1] > Wm9Close[2]))
      {
         CloseAllOrders(MagicNumber, OP_SELL);
         RefreshRates();
         sl = NormalizeDouble(Bid - (slpips * Point), Digits);
         tp = NormalizeDouble(Ask + (slpips * Point), Digits);
         WmOrderSend(Symbol(), OP_BUY, lots, Ask, sl, tp, "", MagicNumber);
         return;
      }
      
      if ((Wm9Close[0] < Wm9Close[1]) && (Wm9Close[1] < Wm9Close[2]))
      {
         CloseAllOrders(MagicNumber, OP_BUY);
         RefreshRates();
         sl = NormalizeDouble(Ask + (slpips * Point), Digits);
         tp = NormalizeDouble(Bid - (slpips * Point), Digits);
         WmOrderSend(Symbol(), OP_SELL, lots, Bid, sl, tp, "", MagicNumber);
         return;
      }
   }   
}

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---