mt4mm





//+------------------------------------------------------------------+
//|                                                        mt4mm.mq4 |
//|                                         Copyright © 2007, 4xTrim |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, 4xTrim"
#property link      ""

#include <WinUser32.mqh>

#import "mt4mm.dll"
   int mmOpen(int hWnd, string szSymbol, int inI[], double inF[], double cur[], double out[]);
#import

#define SLIPPAGE  100
int    TryCount   = 5;
string mt4comment = "";

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
   int inI[3];
   int i, ticket, ssl, stp;
   double inF[10];
   double cur[4];
   double out[12];
   // out[0]   -  0 - íå îòêðûâàåì îðäåð, 1 - îòêðûâàåì îðäåð
   // out[1]   -  òèï îðäåðà:
   //             0 - BUY
   //             1 - SELL
   //             2 - BUY LIMIT
   //             3 - SELL LIMIT
   //             4 - BUY STOP
   //             5 - SELL STOP
   // out[2]   -  êîëè÷åñòâî îòêðûâàåìûõ îðäåðîâ
   // out[3]   -  ðàçìåð ëîòà
   // out[4]   -  öåíà îòêðûòèÿ
   // out[5]   -  ñòîï-ëîññ â ïóíêòàõ
   // out[6]   -  0 - íå óñòàíàâëèâàåì stop-loss, > 0 - óñòàíàâëèâàåì stop-loss
   // out[7]   -  òåéê-ïðîôèò â ïóíêòàõ
   // out[8]   -  0 - íå óñòàíàâëèâàåì take-profit, > 0 - óñòàíàâëèâàåì take-profit
   // out[9]   -  0 - íå äîáàâëÿåì çíà÷åíèå ñòîïà ê êîìåíòó, > 0 - äîáàâëÿåì çíà÷åíèå ñòîïà
   // out[10]   -  0 - íå äîáàâëÿåì çíà÷åíèå òåéêà ê êîìåíòó, > 0 - äîáàâëÿåì çíà÷åíèå òåéêà
   // out[11]   -  MAGIC
//----
   cur[0]  = MarketInfo("EURUSD", MODE_BID);
   cur[1]  = MarketInfo("GBPUSD", MODE_BID);
   cur[2]  = MarketInfo("USDCHF", MODE_BID);
   cur[3]  = MarketInfo("USDJPY", MODE_BID);
//----
   inI[0]  = Digits;
   inI[1]  = MarketInfo(Symbol(), MODE_PROFITCALCMODE);
   inI[2]  = MarketInfo(Symbol(), MODE_MARGINCALCMODE);
//----
   inF[0]  = MarketInfo(Symbol(), MODE_TICKSIZE);
   inF[1]  = MarketInfo(Symbol(), MODE_TICKVALUE);
   inF[2]  = MarketInfo(Symbol(), MODE_MINLOT);
   inF[3]  = MarketInfo(Symbol(), MODE_LOTSTEP);
   inF[4]  = MarketInfo(Symbol(), MODE_STOPLEVEL);
   inF[5]  = MarketInfo(Symbol(), MODE_MARGINREQUIRED);
   inF[6]  = Bid;
   inF[7]  = MarketInfo(Symbol(), MODE_SPREAD);
   inF[8]  = AccountBalance();
   inF[9]  = AccountEquity();
//----
   mmOpen(WindowHandle(Symbol(),Period()), Symbol(), inI, inF, cur, out);
   if (out[0] == 1)
   {
      for (i = 0; i < out[2]; i++)
      {
         ssl = 0; stp = 0;
         if (out[6] > 0 && out[9] > 0.0) ssl = out[5];
         if (out[8] > 0 && out[10]> 0.0) stp = out[7];
         ticket = SetOrder(out[1], out[4], out[3], ssl, stp , out[11]);
         if (ticket > 0 && (out[6] > 0 || out[8] > 0))
         {
            if (out[6] == 0.0) out[5] = 0.0;
            if (out[8] == 0.0) out[7] = 0.0;
            ModOrder(ticket, out[1], out[5], out[7]);
         }
      }
   }
//----
   return(0);
  }

double GetLimit(int type, double openprice, double limitp, bool GetStop)
{
   double limit = 0.0;
//----
   if (limitp > 0.0)
   {
      if (MathMod(type, 2) == 0.0)
      {
         if (GetStop)
            limit = openprice - limitp * MarketInfo(Symbol(), MODE_TICKSIZE);
         else
            limit = openprice + limitp * MarketInfo(Symbol(), MODE_TICKSIZE);
      }
      else
      {
         if (GetStop)
            limit = openprice + limitp * MarketInfo(Symbol(), MODE_TICKSIZE);
         else
            limit = openprice - limitp * MarketInfo(Symbol(), MODE_TICKSIZE);
      }
   }
   return(limit);
}

//+---------------------------------------------------------------------------+
//| Îòêðûòèå îðäåðà                                                           |
//| ---------------                                                           |
//|   type        - òèï îòêðûâàåìîãî îðäåðà                                   |
//|   openprice   - öåíà, ïî êîòîðîé íåîáõîäèìî îòêðûòü îðäåð                 |
//|   lot         - ðàçìåð ëîòà                                               |
//|   slp         - åñëè > 0, òî çàïèñûâàåì ñòîï-ëîññ â êîììåíòàðèé           |
//|   tpp         - åñëè > 0, òî çàïèñûâàåì òåéê-ïðîôèò â êîììåíòàðèé         |
//|   mn          - MAGIC                                                     |
//| Âîçâðàùàåìîå çíà÷åíèå:                                                    |
//|    ñëó÷àå óñïåøíîãî îòêðûòèÿ îðäåðà ôóíêöèÿ âîçâðàùàåò åãî òèêåò.        |
//|    ïðîòèâíîì ñëó÷àå ôóíêöèÿ âîçâðàùàåò -1                                |
//+---------------------------------------------------------------------------+
int SetOrder(int type, double openprice, double lot, double slp, double tpp, double mn)
{
   int ticket = 0;
   int i = 0;
   string com;
//----
   if (lot < MarketInfo(Symbol(), MODE_MINLOT))
     lot = MarketInfo(Symbol(), MODE_MINLOT);
   if (lot > MarketInfo(Symbol(), MODE_MAXLOT))
     lot = MarketInfo(Symbol(), MODE_MAXLOT);
   GetLastError();   // Îáíóëÿåì ïåðåìåííóþ last_error
   while(i < TryCount)
   {
      com = mt4comment;
      if (slp > 0.0 || tpp > 0.0)
      {
         if (StringLen(mt4comment) > 0)
            com = com + " ";
         com = com + "(";
         if (slp > 0.0)
         {
            com = com + "SL: " + DoubleToStr(GetLimit(type, openprice, slp, true), Digits);
            if (tpp > 0.0)
               com = com + " / ";
         }
         if (tpp > 0.0)
            com = com + "TP: " + DoubleToStr(GetLimit(type, openprice, tpp, false), Digits);
         com = com + ")";
      }
      ticket = OrderSend(Symbol(), type, lot, openprice, SLIPPAGE, 0, 0, com, mn);
      if(ticket > 0)
         return(ticket);
      else
      {
         i++;
         // Åñëè îøèáêà íå ñåðüåçíàÿ
         if(ProcessError(GetLastError()))
         {
            RefreshRates();
            switch (type)
            {
            case OP_BUY:
               openprice = Ask;
               break;
            case OP_SELL:
               openprice = Bid;
               break;
            }
         }
         // ïîëó÷èëè ñåðüåçíóþ îøèáêó
         else
            return(-1);
      }
   }
   Print(" òå÷åíèå ", TryCount, " ïîïûòîê îðäåð ïî ñèìâîëó \"", Symbol(), "\" îòêðûòü íå óäàëîñü");
   return(-1);
}

//+---------------------------------------------------------------------------+
//| Ìîäèôèêàöèÿ îðäåðà                                                        |
//| ------------------                                                        |
//|   ticket   - òèêåò ìîäèôèöèðóåìîãî îðäåðà                                 |
//|   type     - òèï ìîäèôèöèðóåìîãî îðäåðà                                   |
//|   slp      - ñòîï-ëîññ â ïóíêòàõ                                          |
//|   tpp      - òåéê-ïðîôèò â ïóíêòàõ                                        |
//| Âîçâðàùàåìîå çíà÷åíèå:                                                    |
//|    ñëó÷àå óñïåøíîé ìîäèôèêàöèè îðäåðà ôóíêöèÿ âîçâðàùàåò TRUE.           |
//|    ïðîòèâíîì ñëó÷àå - FALSE.                                             |
//+---------------------------------------------------------------------------+
bool ModOrder(int ticket, double type, double slp, double tpp)
{
   if (OrderSelect(ticket, SELECT_BY_TICKET) == true)
   {
      double sl = 0.0, tp = 0.0;
      int i = 0;
//----
      if (MathMod(type, 2) == 0.0)
      {
         if (slp > 0.0) sl = OrderOpenPrice() - slp * MarketInfo(Symbol(), MODE_TICKSIZE);
         if (tpp > 0.0) tp = OrderOpenPrice() + tpp * MarketInfo(Symbol(), MODE_TICKSIZE);
      }
      else
      {
         if (slp > 0.0) sl = OrderOpenPrice() + slp * MarketInfo(Symbol(), MODE_TICKSIZE);
         if (tpp > 0.0) tp = OrderOpenPrice() - tpp * MarketInfo(Symbol(), MODE_TICKSIZE);
      }
      GetLastError();
      while (i < TryCount)
      {
         if (OrderModify(OrderTicket(), OrderOpenPrice(), sl, tp, 0))
            return(true);
         else
         {
            if (!ProcessError(GetLastError()))
               return(false);
            i++;
         }
      }
      Print(" òå÷åíèå ", TryCount, " ïîïûòîê îðäåð ¹ ", OrderTicket(), " ìîäèôèöèðîâàòü íå óäàëîñü");
   }
   return(false);
}

//+---------------------------------------------------------------------------+
//| Îáðàáîòêà îøèáîê                                                          |
//| ----------------                                                          |
//|   err - íîìåð âîçíèêøåé îøèáêè                                            |
//| Âîçâðàùàåìîå çíà÷åíèå:                                                    |
//|    ñëó÷àå âîçíèêíîâåíèÿ íåêðèòè÷åñêîé îøèáêè, ïîçâîëÿþùåé ïðîäîëæèòü     |
//|   âûïîëíåíèå ñîâåòíèêà, ôóíêöèÿ âîçâðàùàåò TRUE.                          |
//|    ïðîòèâíîì ñëó÷àå - FALSE.                                             |
//+---------------------------------------------------------------------------+
bool ProcessError(int err)
{
   int iteration;
//----
   PrintError(err);
   switch(err)
   {
   // Íåêðèòè÷åñêèå îøèáêè
   case 0:     // ERR_NO_ERROR
   case 135:   // ERR_PRICE_CHANGED
   case 138:   // ERR_REQUOTE
      return(true);
   // Íåêðèòè÷åñêèå îøèáêè, òðåáóþùèå òàéìàóòà
   case 4:     // ERR_SERVER_BUSY
   case 128:   // ERR_TRADE_TIMEOUT
      Sleep(1000 * 60);
      return(true);   
   case 129:   // ERR_INVALID_PRICE
   case 130:   // ERR_INVALID_STOPS
   case 136:   // ERR_OFF_QUOTES
      Sleep(1000 * 5);
      return(true);   
   case 137:   // ERR_BROKER_BUSY
   case 145:   // ERR_TRADE_MODIFY_DENIED
      Sleep(1000 * 15);
      return(true);   
   // Íåò ñâÿçè ñ ñåðâåðîì. Ïûòàåìñÿ âîññòàíîâèòü ñâÿçü
   case 6:     // ERR_NO_CONNECTION
   {
      bool connect = false;
      iteration = 0;
      while((!connect) || (iteration < 60)) // â òå÷åíèå 5 ìèíóò ïûòàåìñÿ ïîäêîííåêòèòüñÿ ê ñåðâåðó
      {
         Sleep(1000 * 5);
         connect = IsConnected();
         if(connect)
         {
            Print("Ñâÿçü âîññòàíîâëåíà");
            return(true);
         }
         iteration++;
         Print("Ñâÿçü íå âîññòàíîâëåíà, ïðîøëî ", iteration * 5, " ñåêóíä.");
      }
      Print("Ñîåäèíåíèå â òå÷åíèå ", iteration * 5, " ñåêóíä âîññòàíîâèòü íå óäàëîñü.");
      return(false);
   }
   // Ïîäñèñòåìà òîðãîâëè çàíÿòà. Æäåì, ïîêà îñâîáîäèòñÿ
   case 146:   // ERR_TRADE_CONTEXT_BUSY
   {
      bool tradecontextbusy = true;
      iteration = 0;
      while((tradecontextbusy) || (iteration < 60)) // â òå÷åíèå 5 ìèíóò æäåì îñâîáîæäåíèÿ ïîäñèñòåìû òîðãîâëè
      {
         Sleep(1000 * 5);
         tradecontextbusy = IsTradeContextBusy();
         if(!tradecontextbusy)
         {
            Print("Ïîäñèñòåìà òîðãîâëè îñâîáîäèëàñü.");
            return(true);
         }
         iteration++;
         Print("Ïîäñèñòåìà òîðãîâëè âñå åùå çàíÿòà, ïðîøëî ", iteration * 5, " ñåêóíä.");
      }
      Print("Ïîäñèñòåìà òîðãîâëè â òå÷åíèå ", iteration * 5, " ñåêóíä íå îñâîáîäèëàñü.");
      return(false);
   }
   // Êðèòè÷åñêèå îøèáêè. Ïðåêðàùàåì ïîïûòêè îòêðûòèÿ îðäåðà
   case 1:     // ERR_NO_RESULT
   case 2:     // ERR_COMMON_ERROR
   case 3:     // ERR_INVALID_TRADE_PARAMETERS
   case 5:     // ERR_OLD_VERSION
   case 7:     // ERR_NOT_ENOUGH_RIGHTS
   case 8:     // ERR_TOO_FREQUENT_REQUESTS
   case 9:     // ERR_MALFUNCTIONAL_TRADE
   case 64:    // ERR_ACCOUNT_DISABLED
   case 65:    // ERR_INVALID_ACCOUNT
   case 131:   // ERR_INVALID_TRADE_VOLUME
   case 132:   // ERR_MARKET_CLOSED
   case 133:   // ERR_TRADE_DISABLED
   case 134:   // ERR_NOT_ENOUGH_MONEY
   case 139:   // ERR_ORDER_LOCKED
   case 140:   // ERR_LONG_POSITIONS_ONLY_ALLOWED
   case 141:   // ERR_TOO_MANY_REQUESTS
   case 142:
   case 143:
   case 144:
   case 147:   // ERR_TRADE_EXPIRATION_DENIED
   case 148:   // ERR_TRADE_TOO_MANY_ORDERS
   case 4109:  // ERR_TRADE_NOT_ALLOWED
   case 4110:  // ERR_LONGS_NOT_ALLOWED
   case 4111:  // ERR_SHORTS_NOT_ALLOWED
      return(false);
   }
   return(false);
}
//+---------------------------------------------------------------------------+
//| Ïå÷àòü íîìåðà è îïèñàíèÿ îøèáêè â ëîã                                     |
//| --------------------------------------                                    |
//|   err - íîìåð âîçíèêøåé îøèáêè                                            |
//+---------------------------------------------------------------------------+
int PrintError(int err)
{
   Print("ERROR ", err, ":  ", err2str(err));
   return(0);
}
//+---------------------------------------------------------------------------+
//| Ïîëó÷åíèå îïèñàíèÿ îøèáêè ïî åå íîìåðó                                    |
//| --------------------------------------                                    |
//|   err - íîìåð âîçíèêøåé îøèáêè                                            |
//| Âîçâðàùàåìîå çíà÷åíèå:                                                    |
//|   Ôóíêöèÿ âîçâðàùàåò òåêñòîâîå îïèñàíèå îøèáêè                            |
//+---------------------------------------------------------------------------+
string err2str(int err)
{
   switch(err)
   {
   case 0:
      return("Íåò îøèáêè");
   case 1:
      return("Ôóíêöèÿ ìîäèôèêàöèè îðäåðà ïûòàåòñÿ èçìåíèòü óæå óñòàíîâëåííûå çíà÷åíèÿ òàêèìè æå çíà÷åíèÿìè");
   case 2:
      return("Îáùàÿ îøèáêà");
   case 3:
      return("Â òîðãîâóþ ôóíêöèþ ïåðåäàíû íåïðàâèëüíûå ïàðàìåòðû");
   case 4:
      return("Òîðãîâûé ñåðâåð çàíÿò");
   case 5:
      return("Ñòàðàÿ âåðñèÿ êëèåíòñêîãî òåðìèíàëà");
   case 6:
      return("Íåò ñâÿçè ñ òîðãîâûì ñåðâåðîì");
   case 7:
      return("Íåäîñòàòî÷íî ïðàâ");
   case 8:
      return("Ñëèøêîì ÷àñòûå çàïðîñû");
   case 9:
      return("Íåäîïóñòèìàÿ îïåðàöèÿ íàðóøàþùàÿ ôóíêöèîíèðîâàíèå ñåðâåðà");
   case 64:
      return("Ñ÷åò çàáëîêèðîâàí");
   case 65:
      return("Íåïðàâèëüíûé íîìåð ñ÷åòà");
   case 128:
      return("Èñòåê ñðîê îæèäàíèÿ ñîâåðøåíèÿ ñäåëêè");
   case 129:
      return("Íåïðàâèëüíàÿ öåíà");
   case 130:
      return("Íåïðàâèëüíûå ñòîïû");
   case 131:
      return("Íåïðàâèëüíûé îáúåì ñäåëêè");
   case 132:
      return("Ðûíîê çàêðûò");
   case 133:
      return("Òîðãîâëÿ çàïðåùåíà. Âîçìîæíî, Âû ðàáîòàåòå íà ñ÷åòå ïîä ïàðîëåì èíâåñòîðà");
   case 134:
      return("Íåäîñòàòî÷íî äåíåã äëÿ ñîâåðøåíèÿ îïåðàöèè");
   case 135:
      return("Öåíà èçìåíèëàñü");
   case 136:
      return("Íåò öåí");
   case 137:
      return("Áðîêåð çàíÿò");
   case 138:
      return("Ðåêâîò! Íîâûå öåíû");
   case 139:
      return("Îðäåð çàáëîêèðîâàí è óæå îáðàáàòûâàåòñÿ");
   case 140:
      return("Ðàçðåøåíà òîëüêî ïîêóïêà");
   case 141:
      return("Ñëèøêîì ìíîãî çàïðîñîâ");
   case 142:
      return("Îðäåð ïîñòàâëåí â î÷åðåäü");
   case 143:
      return("Îðäåð ïðèíÿò äèëåðîì ê èñïîëíåíèþ");
   case 144:
      return("Îðäåð àííóëèðîâàí ñàìèì êëèåíòîì ïðè ðó÷íîì ïîäòâåðæäåíèè ñäåëêè");
   case 145:
      return("Ìîäèôèêàöèÿ çàïðåùåíà, òàê êàê îðäåð ñëèøêîì áëèçîê ê ðûíêó");
   case 146:
      return("Ïîäñèñòåìà òîðãîâëè çàíÿòà");
   case 147:
      return("Èñïîëüçîâàíèå äàòû èñòå÷åíèÿ îðäåðà çàïðåùåíî áðîêåðîì");
   case 148:
      return("Êîëè÷åñòâî îòêðûòûõ è îòëîæåííûõ îðäåðîâ äîñòèãëî ïðåäåëà, óñòàíîâëåííîãî áðîêåðîì");
   case 4109:
      return("Òîðãîâëÿ íå ðàçðåøåíà. Âîçìîæíî íå âêëþ÷åíà îïöèÿ \"Ðàçðåøèòü ñîâåòíèêó òîðãîâàòü\" â ñâîéñòâàõ ýêñïåðòà");
   case 4110:
      return("Äëèííûå ïîçèöèè íå ðàçðåøåíû");
   case 4111:
      return("Êîðîòêèå ïîçèöèè íå ðàçðåøåíû");
   }
   return("Îïèñàíèå îøèáêè íå èçâåñòíî");
}
//+---------------------------------------------------------------------------+





Sample





Analysis



Market Information Used:



Indicator Curves created:


Indicators Used:



Custom Indicators Used:
mt4mm

Order Management characteristics:
It automatically opens orders when conditions are reached
It can change open orders parameters, due to possible stepping strategy

Other Features: