Stealth 2 Move

Author: Copyright © 2020, Vladimir Karputov
Price Data Components
Miscellaneous
It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
Stealth 2 Move
ÿþ//+------------------------------------------------------------------+

//|                                               Stealth 2 Move.mq5 |

//|                              Copyright © 2020, Vladimir Karputov |

//|                     https://www.mql5.com/ru/market/product/43516 |

//+------------------------------------------------------------------+

#property copyright "Copyright © 2020, Vladimir Karputov"

#property link      "https://www.mql5.com/ru/market/product/43516"

#property version   "2.500"

#property description "Invisible (for a broker) Stop Loss and Take Profit levels. You can now move the Levels manually"

/*

   barabashkakvn Trading engine 3.141

*/

#include <Trade\PositionInfo.mqh>

#include <Trade\Trade.mqh>

#include <Trade\SymbolInfo.mqh>

#include <Trade\AccountInfo.mqh>

#include <Trade\DealInfo.mqh>

#include <Trade\OrderInfo.mqh>

#include <Expert\Money\MoneyFixedMargin.mqh>

//---

CPositionInfo  m_position;                   // object of CPositionInfo class

CTrade         m_trade;                      // object of CTrade class

CSymbolInfo    m_symbol;                     // object of CSymbolInfo class

CAccountInfo   m_account;                    // object of CAccountInfo class

CDealInfo      m_deal;                       // object of CDealInfo class

COrderInfo     m_order;                      // object of COrderInfo class

CMoneyFixedMargin *m_money;                  // object of CMoneyFixedMargin class

//+------------------------------------------------------------------+

//| Enum Pips Or Points                                              |

//+------------------------------------------------------------------+

enum ENUM_PIPS_OR_POINTS

  {

   pips=0,     // Pips (1.00045-1.00055=1 pips)

   points=1,   // Points (1.00045-1.00055=10 points)

  };

//--- input parameters

input group             "Trading settings"

input ENUM_PIPS_OR_POINTS  InpPipsOrPoints=points; // Pips Or Points:

input uint     InpStopLoss          = 150;         // Stop Loss

input uint     InpTakeProfit        = 600;         // Take Profit

input ushort   InpTrailingFrequency = 10;          // Trailing, in seconds (< "10" -> only on a new bar)

input uint     InpBreakevenStop     = 250;         // Breakeven Stop

input uint     InpBreakevenStep     = 50;          // Breakeven Step

input group             "Additional features"

input bool     InpPrintLog          = false;       // Print log

input uchar    InpFreezeCoefficient = 1;           // Coefficient (if Freeze==0 Or StopsLevels==0)

input ulong    InpDeviation         = 10;          // Deviation

input long     InpMagic             = -1;          // Magic number ('-1' -> all, '0' -> manually)

//---

double   m_stop_loss                = 0.0;      // Stop Loss                  -> double

double   m_take_profit              = 0.0;      // Take Profit                -> double

double   m_breakeven_stop           = 0.0;      // Breakeven Stop             -> double

double   m_breakeven_step           = 0.0;      // Breakeven Step             -> double



double   m_adjusted_point;                      // point value adjusted for 3 or 5 points

datetime m_last_trailing            = 0;        // "0" -> D'1970.01.01 00:00';

datetime m_prev_bars                = 0;        // "0" -> D'1970.01.01 00:00';



string   m_prefix                   = "stealth ";

//+------------------------------------------------------------------+

//| Expert initialization function                                   |

//+------------------------------------------------------------------+

int OnInit()

  {

//---

   if(InpBreakevenStop!=0 && InpBreakevenStep==0)

     {

      string err_text=(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")?

                      ""@59;8=3 =52>7<>65=: ?0@0<5B@ \"Breakeven Step\" @025= =C;N!":

                      "Trailing is not possible: parameter \"Breakeven Step\" is zero!";

      //--- when testing, we will only output to the log about incorrect input parameters

      if(MQLInfoInteger(MQL_TESTER))

        {

         Print(__FILE__," ",__FUNCTION__,", ERROR: ",err_text);

         return(INIT_FAILED);

        }

      else // if the Expert Advisor is run on the chart, tell the user about the error

        {

         Alert(__FILE__," ",__FUNCTION__,", ERROR: ",err_text);

         return(INIT_PARAMETERS_INCORRECT);

        }

     }

//---

   ResetLastError();

   if(!m_symbol.Name(Symbol())) // sets symbol name

     {

      Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");

      return(INIT_FAILED);

     }

   RefreshRates();

//---

   m_trade.SetMarginMode();

   m_trade.SetTypeFillingBySymbol(m_symbol.Name());

   m_trade.SetDeviationInPoints(InpDeviation);

//--- tuning for 3 or 5 digits

   int digits_adjust=1;

   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)

      digits_adjust=10;

   m_adjusted_point=m_symbol.Point()*digits_adjust;

   if(InpPipsOrPoints==pips) // Pips (1.00045-1.00055=1 pips)

     {

      m_stop_loss                = InpStopLoss                 * m_adjusted_point;

      m_take_profit              = InpTakeProfit               * m_adjusted_point;

      m_breakeven_stop           = InpBreakevenStop            * m_adjusted_point;

      m_breakeven_step           = InpBreakevenStep            * m_adjusted_point;

     }

   else // Points (1.00045-1.00055=10 points)

     {

      m_stop_loss                = InpStopLoss                 * m_symbol.Point();

      m_take_profit              = InpTakeProfit               * m_symbol.Point();

      m_breakeven_stop           = InpBreakevenStop            * m_symbol.Point();

      m_breakeven_step           = InpBreakevenStep            * m_symbol.Point();

     }

//---

   /*if(MQLInfoInteger(MQL_TESTER))

     {

      m_trade.SetExpertMagicNumber(200);

      bool res=false;

      while(!res)

        {

         res=m_trade.Sell(m_symbol.LotsMin());

         Sleep(1000);

        }

     }*/

//---

   return(INIT_SUCCEEDED);

  }

//+------------------------------------------------------------------+

//| Expert deinitialization function                                 |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

  {

//---

   ObjectsDeleteAll(0,m_prefix,0,OBJ_ARROW_RIGHT_PRICE);

  }

//+------------------------------------------------------------------+

//| Expert tick function                                             |

//+------------------------------------------------------------------+

void OnTick()

  {

   if(InpTrailingFrequency>=10) // trailing no more than once every 10 seconds

     {

      datetime time_current=TimeCurrent();

      if(time_current-m_last_trailing>InpTrailingFrequency)

        {

         Trailing();

         m_last_trailing=time_current;

        }

     }

   if(InpTrailingFrequency<10) // trailing only at the time of the birth of new bar

     {

      //--- we work only at the time of the birth of new bar

      datetime time_0=iTime(m_symbol.Name(),Period(),0);

      if(time_0==m_prev_bars)

         return;

      m_prev_bars=time_0;

      Trailing();

     }

  }

//+------------------------------------------------------------------+

//| Refreshes the symbol quotes data                                 |

//+------------------------------------------------------------------+

bool RefreshRates()

  {

//--- refresh rates

   if(!m_symbol.RefreshRates())

     {

      Print(__FILE__," ",__FUNCTION__,", ERROR: ","RefreshRates error");

      return(false);

     }

//--- protection against the return value of "zero"

   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)

     {

      Print(__FILE__," ",__FUNCTION__,", ERROR: ","Ask == 0.0 OR Bid == 0.0");

      return(false);

     }

//---

   return(true);

  }

//+------------------------------------------------------------------+

//| Trailing                                                         |

//+------------------------------------------------------------------+

void Trailing()

  {

   for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of current positions

      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties

         if(m_position.Symbol()==m_symbol.Name() && (InpMagic==-1 || (InpMagic==0 && m_position.Magic()==0)))

           {

            //The sequence of steps:

            //   Step 1. Checking Stop Loss

            //   Step 2. Checking Take Profit

            //   Step 3. Checking breakeven

            double price_sl_arrow= 0.0;

            double price_tp_arrow= 0.0;

            double price_br_arrow= 0.0;

            string name_sl_arrow = m_prefix+IntegerToString(m_position.Ticket())+" SL";

            string name_tp_arrow = m_prefix+IntegerToString(m_position.Ticket())+" TP";

            string name_br_arrow = m_prefix+IntegerToString(m_position.Ticket())+" BR";

            if(InpStopLoss!=0) // Step 1. Checking Stop Loss

              {

               bool find_sl_arrow=(ObjectFind(0,name_sl_arrow)==0);

               if(find_sl_arrow)

                  if(!ObjectGetDouble(0,name_sl_arrow,OBJPROP_PRICE,0,price_sl_arrow))

                     continue;

               if(m_position.PositionType()==POSITION_TYPE_BUY)

                 {

                  if(!find_sl_arrow) // object not found

                     price_sl_arrow=m_position.PriceOpen()-m_stop_loss;

                  else

                     if(price_sl_arrow==0.0)

                        continue;

                  //---

                  if(m_position.PriceCurrent()<=price_sl_arrow)

                    {

                     if(!m_trade.PositionClose(m_position.Ticket()))

                       {

                        Print(__FILE__," ",__FUNCTION__,", ERROR: ","BUY PositionClose ",m_position.Ticket(),", ",m_trade.ResultRetcodeDescription());

                        continue;

                       }

                     ArrowRightPriceDelete(0,name_sl_arrow);

                     ArrowRightPriceDelete(0,name_tp_arrow);

                     ArrowRightPriceDelete(0,name_br_arrow);

                     continue;

                    }

                  else

                    {

                     if(!find_sl_arrow)

                        ArrowRightPriceCreate(0,name_sl_arrow,0,iTime(m_symbol.Name(),Period(),0),price_sl_arrow);

                     else

                        ArrowRightPriceMove(0,name_sl_arrow,iTime(m_symbol.Name(),Period(),0),price_sl_arrow);

                    }

                 }

               if(m_position.PositionType()==POSITION_TYPE_SELL)

                 {

                  if(!find_sl_arrow) // object not found

                     price_sl_arrow=m_position.PriceOpen()+m_stop_loss;

                  else

                     if(price_sl_arrow==0.0)

                        continue;

                  //---

                  if(m_position.PriceCurrent()>=price_sl_arrow)

                    {

                     if(!m_trade.PositionClose(m_position.Ticket()))

                       {

                        Print(__FILE__," ",__FUNCTION__,", ERROR: ","BUY PositionClose ",m_position.Ticket(),", ",m_trade.ResultRetcodeDescription());

                        continue;

                       }

                     ArrowRightPriceDelete(0,name_sl_arrow);

                     ArrowRightPriceDelete(0,name_tp_arrow);

                     ArrowRightPriceDelete(0,name_br_arrow);

                     continue;

                    }

                  else

                    {

                     if(!find_sl_arrow)

                        ArrowRightPriceCreate(0,name_sl_arrow,0,iTime(m_symbol.Name(),Period(),0),price_sl_arrow);

                     else

                        ArrowRightPriceMove(0,name_sl_arrow,iTime(m_symbol.Name(),Period(),0),price_sl_arrow);

                    }

                 }

              }

            if(InpTakeProfit!=0) // Step 2. Checking Take Profit

              {

               bool find_tp_arrow=(ObjectFind(0,name_tp_arrow)==0);

               if(find_tp_arrow)

                  if(!ObjectGetDouble(0,name_tp_arrow,OBJPROP_PRICE,0,price_tp_arrow))

                     continue;

               if(m_position.PositionType()==POSITION_TYPE_BUY)

                 {

                  if(!find_tp_arrow) // object not found

                     price_tp_arrow=m_position.PriceOpen()+m_take_profit;

                  else

                     if(price_tp_arrow==0.0)

                        continue;

                  //---

                  if(m_position.PriceCurrent()>=price_tp_arrow)

                    {

                     if(!m_trade.PositionClose(m_position.Ticket()))

                       {

                        Print(__FILE__," ",__FUNCTION__,", ERROR: ","BUY PositionClose ",m_position.Ticket(),", ",m_trade.ResultRetcodeDescription());

                        continue;

                       }

                     ArrowRightPriceDelete(0,name_sl_arrow);

                     ArrowRightPriceDelete(0,name_tp_arrow);

                     ArrowRightPriceDelete(0,name_br_arrow);

                     continue;

                    }

                  else

                    {

                     if(!find_tp_arrow)

                        ArrowRightPriceCreate(0,name_tp_arrow,0,iTime(m_symbol.Name(),Period(),0),price_tp_arrow);

                     else

                        ArrowRightPriceMove(0,name_tp_arrow,iTime(m_symbol.Name(),Period(),0),price_tp_arrow);

                    }

                 }

               if(m_position.PositionType()==POSITION_TYPE_SELL)

                 {

                  if(!find_tp_arrow) // object not found

                     price_tp_arrow=m_position.PriceOpen()-m_take_profit;

                  else

                     if(price_tp_arrow==0.0)

                        continue;

                  //---

                  if(m_position.PriceCurrent()<=price_tp_arrow)

                    {

                     if(!m_trade.PositionClose(m_position.Ticket()))

                       {

                        Print(__FILE__," ",__FUNCTION__,", ERROR: ","BUY PositionClose ",m_position.Ticket(),", ",m_trade.ResultRetcodeDescription());

                        continue;

                       }

                     ArrowRightPriceDelete(0,name_sl_arrow);

                     ArrowRightPriceDelete(0,name_tp_arrow);

                     ArrowRightPriceDelete(0,name_br_arrow);

                     continue;

                    }

                  else

                    {

                     if(!find_tp_arrow)

                        ArrowRightPriceCreate(0,name_tp_arrow,0,iTime(m_symbol.Name(),Period(),0),price_tp_arrow);

                     else

                        ArrowRightPriceMove(0,name_tp_arrow,iTime(m_symbol.Name(),Period(),0),price_tp_arrow);

                    }

                 }

              }

            if(InpBreakevenStop!=0) // Step 3. Checking breakeven

              {

               bool find_br_arrow=(ObjectFind(0,name_br_arrow)==0);

               if(find_br_arrow)

                  if(!ObjectGetDouble(0,name_br_arrow,OBJPROP_PRICE,0,price_br_arrow))

                     continue;

               if(m_position.PositionType()==POSITION_TYPE_BUY)

                 {

                  if(!find_br_arrow) // object not found

                    {

                     if(m_position.PriceCurrent()<m_position.PriceOpen()+m_breakeven_stop+m_breakeven_step)

                        continue;

                     price_br_arrow=m_position.PriceOpen()+m_breakeven_step;

                     if(m_position.PriceCurrent()>=m_position.PriceOpen()+m_breakeven_stop+m_breakeven_step)

                        ArrowRightPriceCreate(0,name_br_arrow,0,iTime(m_symbol.Name(),Period(),0),price_br_arrow);

                    }

                  else

                    {

                     if(price_br_arrow==0.0)

                        continue;

                     if(m_position.PriceCurrent()<=price_br_arrow)

                       {

                        if(!m_trade.PositionClose(m_position.Ticket()))

                          {

                           Print(__FILE__," ",__FUNCTION__,", ERROR: ","BUY PositionClose ",m_position.Ticket(),", ",m_trade.ResultRetcodeDescription());

                           continue;

                          }

                        ArrowRightPriceDelete(0,name_sl_arrow);

                        ArrowRightPriceDelete(0,name_tp_arrow);

                        ArrowRightPriceDelete(0,name_br_arrow);

                        continue;

                       }

                     ArrowRightPriceMove(0,name_br_arrow,iTime(m_symbol.Name(),Period(),0),price_br_arrow);

                    }

                 }

               if(m_position.PositionType()==POSITION_TYPE_SELL)

                 {

                  if(!find_br_arrow) // object not found

                    {

                     if(m_position.PriceCurrent()>m_position.PriceOpen()-m_breakeven_stop-m_breakeven_step)

                        continue;

                     price_br_arrow=m_position.PriceOpen()-m_breakeven_step;

                     if(m_position.PriceCurrent()<=m_position.PriceOpen()-m_breakeven_stop-m_breakeven_step)

                        ArrowRightPriceCreate(0,name_br_arrow,0,iTime(m_symbol.Name(),Period(),0),price_br_arrow);

                    }

                  else

                    {

                     if(price_br_arrow==0.0)

                        continue;

                     if(m_position.PriceCurrent()>=price_br_arrow)

                       {

                        if(!m_trade.PositionClose(m_position.Ticket()))

                          {

                           Print(__FILE__," ",__FUNCTION__,", ERROR: ","BUY PositionClose ",m_position.Ticket(),", ",m_trade.ResultRetcodeDescription());

                           continue;

                          }

                        ArrowRightPriceDelete(0,name_sl_arrow);

                        ArrowRightPriceDelete(0,name_tp_arrow);

                        ArrowRightPriceDelete(0,name_br_arrow);

                        continue;

                       }

                     ArrowRightPriceMove(0,name_br_arrow,iTime(m_symbol.Name(),Period(),0),price_br_arrow);

                    }

                 }

              }

           }

  }

//+------------------------------------------------------------------+

//| Create the right price label                                     |

//+------------------------------------------------------------------+

bool ArrowRightPriceCreate(const long            chart_ID=0,        // chart's ID

                           const string          name="RightPrice", // price label name

                           const int             sub_window=0,      // subwindow index

                           datetime              time=0,            // anchor point time

                           double                price=0,           // anchor point price

                           const color           clr=clrMagenta,    // price label color

                           const ENUM_LINE_STYLE style=STYLE_SOLID, // border line style

                           const int             width=1,           // price label size

                           const bool            back=false,        // in the background

                           const bool            selection=true,    // highlight to move

                           const bool            hidden=true,       // hidden in the object list

                           const long            z_order=0)         // priority for mouse click

  {

//--- set anchor point coordinates if they are not set

   ChangeArrowEmptyPoint(time,price);

//--- reset the error value

   ResetLastError();

//--- create a price label

   if(!ObjectCreate(chart_ID,name,OBJ_ARROW_RIGHT_PRICE,sub_window,time,price))

     {

      Print(__FUNCTION__,

            ": failed to create the right price label! Error code = ",GetLastError());

      return(false);

     }

//--- set the label color

   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);

//--- set the border line style

   ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);

//--- set the label size

   ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);

//--- display in the foreground (false) or background (true)

   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);

//--- enable (true) or disable (false) the mode of moving the label by mouse

//--- when creating a graphical object using ObjectCreate function, the object cannot be

//--- highlighted and moved by default. Inside this method, selection parameter

//--- is true by default making it possible to highlight and move the object

   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);

   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);

//--- hide (true) or display (false) graphical object name in the object list

   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);

//--- set the priority for receiving the event of a mouse click in the chart

   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);

//---

   ChartRedraw(0);

//--- successful execution

   return(true);

  }

//+------------------------------------------------------------------+

//| Move the anchor point                                            |

//+------------------------------------------------------------------+

bool ArrowRightPriceMove(const long   chart_ID=0,        // chart's ID

                         const string name="RightPrice", // label name

                         datetime     time=0,            // anchor point time coordinate

                         double       price=0)           // anchor point price coordinate

  {

//--- if point position is not set, move it to the current bar having Bid price

   if(!time)

      time=TimeCurrent();

   if(!price)

      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);

//--- reset the error value

   ResetLastError();

//--- move the anchor point

   if(!ObjectMove(chart_ID,name,0,time,price))

     {

      Print(__FUNCTION__,

            ": failed to move the anchor point! Error code = ",GetLastError());

      return(false);

     }

   ChartRedraw(0);

//--- successful execution

   return(true);

  }

//+------------------------------------------------------------------+

//| Delete the right price label from the chart                      |

//+------------------------------------------------------------------+

bool ArrowRightPriceDelete(const long   chart_ID=0,        // chart's ID

                           const string name="RightPrice") // label name

  {

//--- reset the error value

   ResetLastError();

//--- delete the label

   if(!ObjectDelete(chart_ID,name))

     {

      Print(__FUNCTION__,

            ": failed to delete the right price label! Error code = ",GetLastError());

      return(false);

     }

   ChartRedraw(0);

//--- successful execution

   return(true);

  }

//+------------------------------------------------------------------+

//| Check anchor point values and set default values                 |

//| for empty ones                                                   |

//+------------------------------------------------------------------+

void ChangeArrowEmptyPoint(datetime &time,double &price)

  {

//--- if the point's time is not set, it will be on the current bar

   if(!time)

      time=TimeCurrent();

//--- if the point's price is not set, it will have Bid value

   if(!price)

      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);

  }

//+------------------------------------------------------------------+



//+------------------------------------------------------------------+

Comments