Author: Copyright � 2012, TheXpert
Orders Execution
Checks for the total of open ordersIt can change open orders parameters, due to possible stepping strategyIt Closes Orders by itself
Miscellaneous
It opens Message Boxes to the user
0 Views
0 Downloads
0 Favorites
DragSLTP
//+------------------------------------------------------------------+
//|                                                     DragSLTP.mq4 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2012, TheXpert"
#property link      "mqlite@gmail.com"

// maximum acceptable slippage for the price
extern int        Slippage          =  3;

// maximum loop count for orders opening if failed due to requoting
extern int        TimesToRepeat     =  3;

extern color      SL_Color = Red;
extern int        SL_Style = 3;            // StopLoss line
extern color      TP_Color = Green;
extern int        TP_Style = 3;            // TakeProfit line

extern bool       ConfirmActions = false;

extern bool       AutoSetSL = true;
extern double     SLPoints = 300;

extern bool       AutoSetTP = false;
extern double     TPPoints = 30;


string Symbol_;

///=========================================================================
/// GUI
///=========================================================================

void SetText(string name, datetime time, double price, string text, int size = 10, color clr = White)
{
   ObjectCreate(name, OBJ_TEXT, 0, time, price);
   
   ObjectSet(name, OBJPROP_PRICE1, price);
   ObjectSet(name, OBJPROP_TIME1, time);

   ObjectSetText(name, text, size, "", clr);
}

void SetHLine(string name, double price, color clr = Green, int style = 2, int width = 0)
{
   ObjectCreate(name, OBJ_HLINE, 0, 0, price); 
   
   ObjectSet(name, OBJPROP_PRICE1, price);
   ObjectSet(name, OBJPROP_STYLE, style);
   ObjectSet(name, OBJPROP_COLOR, clr);
   ObjectSet(name, OBJPROP_WIDTH, width);
}

///=========================================================================
/// Trading
///=========================================================================

void WaitForContext()
{
   while (IsTradeContextBusy() && !IsStopped())
   {
      Sleep(20);
   }
}

bool NeedToRetry(int errorCode)
{
   switch (errorCode)
   {
      case 4   : return (true);
      case 129 : return (true);
      case 130 : return (true);
      case 135 : return (true);
      case 138 : return (true);
      case 146 : return (true);
      
      default: return (false);
   }
}

#define IDOK 1
#define IDCANCEL 2

bool Confirmed(string action)
{
   if (!ConfirmActions) return (true);
   
   int result = MessageBox("Do you really want to\n" + action + "?", "Please confirm", IDOK);
   return (result == IDOK);
}

void CheckForSLTP()
{
   if (!AutoSetSL && !AutoSetTP) return;
   
   double slevel = MarketInfo(Symbol_, MODE_STOPLEVEL);
   double sl = MathMax(SLPoints, slevel);
   double tp = MathMax(TPPoints, slevel);
   
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
      // already closed
      if(!OrderSelect(i, SELECT_BY_POS)) continue;
      // not current symbol
      if(OrderSymbol() != Symbol_) continue;
      
      double newSL = 0;
      double newTP = 0;

      RefreshRates();

      switch(OrderType())
      {
         case OP_BUY:
            newSL = NormalizeDouble(Bid - sl*Point, Digits);
            newTP = NormalizeDouble(Ask + tp*Point, Digits);
            break;
            
         case OP_SELL:
            newSL = NormalizeDouble(Ask + sl*Point, Digits);
            newTP = NormalizeDouble(Bid - tp*Point, Digits);
            break;
      }
      
      bool needModify = false;
      
      if (!AutoSetSL || OrderStopLoss() != 0)
      {
         newSL = OrderStopLoss();
      }
      else
      {
         needModify = true;
      }
      
      if (!AutoSetTP || OrderTakeProfit() != 0)
      {
         newTP = OrderTakeProfit();
      }
      else
      {
         needModify = true;
      }
      
      if (needModify)
      {
         OrderModify(OrderTicket(), OrderOpenPrice(), newSL, newTP, OrderExpiration());
      }
   }
}

///=========================================================================
/// Misc
///=========================================================================

string ID()
{
   static string result;
   if (StringLen(result) == 0) result = "DSLTP " + " ";
   
   return (result);
}

int IDLen()
{
   static int size = -1;
   if (size == -1) size = StringLen(ID());
   
   return (size);
}

datetime GetTime(int i)
{
   if (i >= 0) return (Time[i]);
   return (Time[0] - i*60*Period());
}

///=========================================================================
/// DND Implementation
///=========================================================================

bool CheckDrag(string name)
{
   double x = ObjectGet(name, OBJPROP_PRICE1);
   if (GetLastError() != 0) return (false);
   
   if (ObjectSet(name, OBJPROP_PRICE1, x*1.1))
   {
      ObjectSet(name, OBJPROP_PRICE1, x);
      return (false);
   }
   
   return (true);
}

bool CheckDrop(string name)
{
   double x = ObjectGet(name, OBJPROP_PRICE1);
   if (GetLastError() != 0) return (true);
   
   if (ObjectSet(name, OBJPROP_PRICE1, x*1.1))
   {
      ObjectSet(name, OBJPROP_PRICE1, x);
      return (true);
   }
   
   return (false);
}


bool IsDragging = false;
string DragName = "";

double DropPrice;

void OnDropped(string name)
{
   IsDragging = false;

   string s = ObjectDescription(ID() + " HelpText");
   if (s == "") return;
   
   ObjectDelete(ID() + " HelpText");
   
   int t = GetTicketFromName(name);
   if (!OrderSelect(t, SELECT_BY_TICKET)) return;

   int stopLevel = MarketInfo(Symbol_, MODE_STOPLEVEL);
   
   string type = StringSubstr(name, 0, 2);
   
   DropPrice = NormalizeDouble(DropPrice, Digits);
   
   if (!Confirmed(s)) return;
   
   RefreshRates();
   if (type == "SL")
   {
      switch(OrderType())
      {
         case OP_BUY:
            if (DropPrice > Ask)
            {
               int err = 0;
               for (int i = 0; i < TimesToRepeat; i++)
               {
                  WaitForContext();
                  RefreshRates();
                  if (OrderClose(t, OrderLots(), Bid, Slippage))
                  {
                     Print("Order #", t, " closed successfully");
                     err = 0;
                     break;
                  }
                  else
                  {
                     err = GetLastError();
                     if (!NeedToRetry(err)) break;
                     Sleep(100);
                  }
               }
               
               if (err > 0)
               {
                  Print("Close order #", t, " failed, error #", err);
               }
            }
            else
            {
               WaitForContext();
               RefreshRates();
               double sl = NormalizeDouble(MathMin(DropPrice, Bid - stopLevel*Point), Digits);
               if (OrderModify(t, OrderOpenPrice(), sl, OrderTakeProfit(), OrderExpiration()))
               {
                  Print("SL for #", t, " modified successfully");
               }
               else
               {
                  Print("SL modification for #", t, " failed, Error #", GetLastError());
               }
            }
            break;
            
         case OP_SELL:
            if (DropPrice < Bid)
            {
               err = 0;
               for (i = 0; i < TimesToRepeat; i++)
               {
                  WaitForContext();
                  RefreshRates();
                  if (OrderClose(t, OrderLots(), Ask, Slippage))
                  {
                     Print("Order #", t, " closed successfully");
                     err = 0;
                     break;
                  }
                  else
                  {
                     err = GetLastError();
                     if (!NeedToRetry(err)) break;
                     Sleep(100);
                  }
               }
               
               if (err > 0)
               {
                  Print("Close order #", t, " failed, error #", err);
               }
            }
            else
            {
               WaitForContext();
               RefreshRates();
               sl = NormalizeDouble(MathMax(DropPrice, Ask + stopLevel*Point), Digits);
               if (OrderModify(t, OrderOpenPrice(), sl, OrderTakeProfit(), OrderExpiration()))
               {
                  Print("SL for #", t, " modified successfully");
               }
               else
               {
                  Print("SL modification for #", t, " failed, Error #", GetLastError());
               }
            }
            break;
      }
   }
   else if (type == "TP")
   {
      switch(OrderType())
      {
         case OP_BUY:
            if (DropPrice < Bid)
            {
               err = 0;
               for (i = 0; i < TimesToRepeat; i++)
               {
                  WaitForContext();
                  RefreshRates();
                  if (OrderClose(t, OrderLots(), Bid, Slippage))
                  {
                     Print("Order #", t, " closed successfully");
                     err = 0;
                     break;
                  }
                  else
                  {
                     err = GetLastError();
                     if (!NeedToRetry(err)) break;
                     Sleep(100);
                  }
               }
               
               if (err > 0)
               {
                  Print("Close order #", t, " failed, error #", err);
               }
            }
            else
            {
               WaitForContext();
               RefreshRates();
               double tp = NormalizeDouble(MathMax(DropPrice, Ask + stopLevel*Point), Digits);
               if (OrderModify(t, OrderOpenPrice(), OrderStopLoss(), tp, OrderExpiration()))
               {
                  Print("TP for #", t, " modified successfully");
               }
               else
               {
                  Print("TP modification for #", t, " failed, Error #", GetLastError());
               }
            }
            break;
            
         case OP_SELL:
            if (DropPrice > Ask)
            {
               err = 0;
               for (i = 0; i < TimesToRepeat; i++)
               {
                  WaitForContext();
                  RefreshRates();
                  if (OrderClose(t, OrderLots(), Ask, Slippage))
                  {
                     Print("Order #", t, " closed successfully");
                     err = 0;
                     break;
                  }
                  else
                  {
                     err = GetLastError();
                     if (!NeedToRetry(err)) break;
                     Sleep(100);
                  }
               }
               
               if (err > 0)
               {
                  Print("Close order #", t, " failed, error #", err);
               }
            }
            else
            {
               WaitForContext();
               RefreshRates();
               tp = NormalizeDouble(MathMin(DropPrice, Bid - stopLevel*Point), Digits);
               if (OrderModify(t, OrderOpenPrice(), OrderStopLoss(), tp, OrderExpiration()))
               {
                  Print("TP for #", t, " modified successfully");
               }
               else
               {
                  Print("TP modification for #", t, " failed, Error #", GetLastError());
               }
            }
            break;
      }
   }
}

void WhileDragging(string name)
{
   double ask = MarketInfo(Symbol_, MODE_ASK);
   double bid = MarketInfo(Symbol_, MODE_BID);
   
   int t = GetTicketFromName(name);
   int stopLevel = MarketInfo(Symbol_, MODE_STOPLEVEL);
   
   string text = "";
   
   string type = StringSubstr(name, 0, 2);
   double nowPrice = NormalizeDouble(ObjectGet(name, OBJPROP_PRICE1), Digits);
   DropPrice = nowPrice;
   
   if (!OrderSelect(t, SELECT_BY_TICKET))
   {
      type = "";
      text = "Invalid order (#" + t + ")";
   }
   
   int orderType = OrderType();
   
   
   if (type == "SL")
   {
      text =      "set SL for #" + t + " (" + 
                  DoubleToStr(OrderLots(), 2) + " " +
                  Type(OrderType()) + " at " + 
                  DoubleToStr(OrderOpenPrice(), Digits) + ") to ";
                  
      switch(OrderType())
      {
         case OP_BUY:
            if (nowPrice > ask)
            {
               text =   "Close #" + t + " (" + 
                        DoubleToStr(OrderLots(), 2) + " " +
                        Type(OrderType()) + " at " + 
                        DoubleToStr(OrderOpenPrice(), Digits) + ")";
            }
            else
            {
               text = text + DoubleToStr(MathMin(nowPrice, bid - stopLevel*Point), Digits);
            }
            break;
         case OP_SELL:
            if (nowPrice < bid)
            {
               text =   "Close #" + t + " (" + 
                        DoubleToStr(OrderLots(), 2) + " " +
                        Type(OrderType()) + " at " + 
                        DoubleToStr(OrderOpenPrice(), Digits) + ")";
            }
            else
            {
               text = text + DoubleToStr(MathMax(nowPrice, ask + stopLevel*Point), Digits);
            }
            break;
      }
   }
   else if (type == "TP")
   {
      text =      "set TP for #" + t + " (" + 
                  DoubleToStr(OrderLots(), 2) + " " +
                  Type(OrderType()) + " at " + 
                  DoubleToStr(OrderOpenPrice(), Digits) + ") to ";
                  
      switch(OrderType())
      {
         case OP_BUY:
            if (nowPrice < bid)
            {
               text =   "Close #" + t + " (" + 
                        DoubleToStr(OrderLots(), 2) + " " +
                        Type(OrderType()) + " at " + 
                        DoubleToStr(OrderOpenPrice(), Digits) + ")";
            }
            else
            {
               text = text + DoubleToStr(MathMax(nowPrice, bid + stopLevel*Point), Digits);
            }
            break;
         case OP_SELL:
            if (nowPrice > ask)
            {
               text =   "Close #" + t + " (" + 
                        DoubleToStr(OrderLots(), 2) + " " +
                        Type(OrderType()) + " at " + 
                        DoubleToStr(OrderOpenPrice(), Digits) + ")";
            }
            else
            {
               text = text + DoubleToStr(MathMin(nowPrice, ask - stopLevel*Point), Digits);
            }
            break;
      }                  
   }
   
   datetime time = GetTime(WindowFirstVisibleBar() - WindowBarsPerChart()/2);
   SetText(ID() + " HelpText", time, nowPrice + Point, text);
}

///=========================================================================
/// Implementation
///=========================================================================

int GetTicketFromName(string name)
{
   string ticket = StringSubstr(name, IDLen() + 3);
   
   int space = StringFind(ticket, " ");
   if (space == -1) return (-1);
   
   return (StrToInteger(StringSubstr(ticket, 0, space)));
}

int init()
{
   IsDragging = false;
   DragName = "";
   
   Symbol_ = Symbol();
}

int start()
{
   if (IsTesting()) return (0);
   
   while (!IsStopped())
   {
      if (IsDragging)
      {
         if (CheckDrop(DragName))
         {
            OnDropped(DragName);
         }
         else
         {
            WhileDragging(DragName);
         }
      }
      else
      {
         CheckForSLTP();
         CheckLines();
      }
   
      WindowRedraw();
   
      Sleep(50);
   }
   
   return(0);
}

void deinit()
{
   int count = ObjectsTotal();
   for (int i = count - 1; i >= 0; i--)
   {
      string name = ObjectName(i);
      if (StringFind(name, ID()) != -1)
      {
         ObjectDelete(name);
      }
   }
}

void CheckLines() 
{
   double stopLevel = MarketInfo(Symbol_, MODE_STOPLEVEL);
   double tickSize = MarketInfo(Symbol_, MODE_TICKSIZE);
   int    r;                  // òèêåò èñêîìîé ïîçèöèè
   int    t[];                // ìàññèâ òèêåòîâ ñóùåñòâóþùèõ ïîçèöèé

   // çàïîëíåíèå ìàññèâà òèêåòîâ ñóùåñòâóþùèõ ïîçèöèé
   ArrayResize(t, 0);

   for (int i = OrdersTotal() - 1; i >= 0; i--) 
   {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
      if (OrderSymbol() != Symbol_) continue;
      if (OrderType() != OP_BUY && OrderType() != OP_SELL) continue;
      
      if (OrderStopLoss() > 0 || OrderTakeProfit() > 0)
      {
         r = ArraySize(t);
         ArrayResize(t, r + 1);
         t[r] = OrderTicket();
      }
   }

   // óäàëåíèå ëèøíèõ (íåíóæíûõ) ëèíèé
   for (i = ObjectsTotal() - 1; i >= 0; i--)
   {
      string name = ObjectName(i);
      if (StringFind(name, ID()) == -1 || ObjectType(name) != OBJ_HLINE) continue;

      r = GetTicketFromName(name);
      if (ArraySearchInt(t, r) < 0 || !OrderSelect(r, SELECT_BY_TICKET))
      {
         ObjectDelete(name);
         continue;
      }
   }
   
   for (i = ArraySize(t) - 1; i >= 0; i--)
   {
      if (!OrderSelect(t[i], SELECT_BY_TICKET)) continue;
      
      double sl = OrderStopLoss();
      double tp = OrderTakeProfit();
      
      if (sl != 0)
      {
         SetHLine("SL " + ID() + " " + t[i], sl, SL_Color);
         
         if (!IsDragging)
         {
            if (CheckDrag("SL " + ID() + " " + t[i]))
            {
               IsDragging = true;
               DragName = "SL " + ID() + " " + t[i];
            }
         }
      }
      
      if (tp != 0)
      {
         SetHLine("TP " + ID() + " " + t[i], tp, TP_Color);

         if (!IsDragging)
         {
            if (CheckDrag("TP " + ID() + " " + t[i]))
            {
               IsDragging = true;
               DragName = "TP " + ID() + " " + t[i];
            }
         }
      }
   }
}

int ArraySearchInt(int a[], int what) 
{
   for (int i = 0; i < ArraySize(a); i++) 
   {
      if (a[i] == what) return(i);
   }
   return(-1);
}

string Type(int type)
{
   switch (type)
   {
      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");
   }
   return ("Unknown");
}}
   return ("Unknown");
}

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 ---