← К каталогу
Исходный код · ID 3526

unlocker.mq4

Вы автор или правообладатель?

Сообщите нам, если считаете, что материал размещён без разрешения.

Краткий обзор

О программе

unlocker.mqh — библиотека исходного кода для MetaTrader 4, предоставляющая класс CLock для управления торговыми позициями с механизмом частичного локирования. Библиотека наследуется от класса COrders и использует торговые API для работы с позициями и ордерами. Класс реализует выборочное закрытие позиций по типу, магическому номеру и направлению, а также поддерживает накопление прибыли в копилку для последующего частичного закрытия.

Состав библиотеки

Классов: 1 · методов: 12 · конструкторов: 0 · деструкторов: 0 · отдельных функций: 0

Классы
Класс class CLock

Класс для управления торговыми позициями с механизмом частичного локирования и накопления прибыли

Методы и конструкторы
Метод · CLock bool OrderCloseAll(int itype)

Закрывает все позиции и удаляет все ордера указанного типа

Метод · CLock bool OrderCloseAll(long iLockMagic,int itype)

Закрывает позиции и удаляет ордера указанного типа с учётом магического номера

Метод · CLock bool OrderCloseProfitAllNoLock(long iLockMagic,int itype)

Закрывает только прибыльные позиции указанного типа, исключая позиции с заданным магическим номером

Метод · CLock bool CloseByProfitInProcent(double dTPinProcent)

Закрывает все позиции, если накопленная прибыль достигает заданного процента от баланса

Метод · CLock bool SelfDestruct(int itype,long iLockMagic,double dTPinProcent)

Принудительно закрывает часть позиций при достижении заданного процента прибыли

Метод · CLock void SetAllforLock(long iLockMagic,int itype,double dstop,double dtake,bool bCheck,bool bForTral,double dTrailingStep)

Устанавливает или модифицирует уровни стоп-лосс и тейк-профита на позициях с поддержкой трейлинга

Метод · CLock void Run(int iTradeMode,long iLockMagic,double dTPinProcent,double dLockTP,double dLockBU,double dLockTral, double dLockNext,double dLockMultiplicator,double dKopilkaProcent,double dMinimalLot,bool bSelfDestruct)

Запускает основной цикл управления позицией с возможностью построения сетки, трейлинга и саморазрушения

Метод · CLock bool Check(string symbol,long imagic)

Проверяет, соответствует ли символ и магический номер заданным параметрам

Метод · CLock double get_Average(long iLockMagic,int itype,int &idirect,double dProfit)

Рассчитывает среднюю цену входа и определяет уровень тейк-профита для достижения заданной прибыли

Метод · CLock void Reset(datetime tmNew)

Сбрасывает или обновляет параметры накопления прибыли

Метод · CLock ulong getLastOrderTicket(long iLockMagic,double &dSummLot,int itype,_ORDER_MODE imode,datetime dtmOpen)

Возвращает тикет последнего ордера указанного типа и направления с учётом времени открытия

Метод · CLock bool Kopilka(long iLockMagic,double dKopilkaProcent,double dMinimalLot,ulong &_tlast,double &_dlot,double &_dSummLot,int _itype,datetime &_tmFirst)

Выполняет частичное закрытие позиций с накоплением прибыли в копилку для последующего использования

Получить полный код

Поиск по коду файла

#ifndef __SOVETNIKOV_UNLOCKER_2sdfhgsd
#define __SOVETNIKOV_UNLOCKER_2sdfhgsd

#include <sovetnikovNET\Orders.mqh>

class CLock: public COrders
  {
public:
   datetime          tmKopilka;

   virtual bool      OrderCloseAll(int itype=ALL)
     {
      __COPYRIGHT__

      int c=0,flag;

      bool bRet=false;

      for(int i=PositionsTotal()-1; i>=0; i--)
        {
         if(!SelectByIndex(i,true))
            continue;

         int etype=m_position.PositionType();

         flag=toMyTypes(etype)&itype;

         if(itype==ALL || etype==toDefType(flag,itype))
           {

            double dTakeProfit=m_position.TakeProfit();
            double dStopLoss=m_position.StopLoss();
            double dCurrentPrice=m_position.PriceCurrent();
            double dOpenPrice=m_position.PriceOpen();

            bool take_profit_level=false;

            if(m_position.TakeProfit()>0 && ((etype==OP_BUY && m_position.TakeProfit()-m_position.PriceCurrent()>=m_freeze) || (etype==OP_SELL && m_position.PriceCurrent()-m_position.TakeProfit()>=m_freeze)))
               take_profit_level=true;
            if(m_position.TakeProfit()==0.0)
               take_profit_level=true;

            bool stop_loss_level=false;

            if(m_position.StopLoss()>0 && ((etype==OP_BUY && MathAbs(m_position.PriceCurrent()-m_position.StopLoss())>=m_freeze) || (etype==OP_SELL && MathAbs(m_position.StopLoss()-m_position.PriceCurrent())>=m_freeze)))
               stop_loss_level=true;

            if(m_position.StopLoss()==0.0)
               stop_loss_level=true;

            if(take_profit_level && stop_loss_level)
              {

               m_trade.SetExpertMagicNumber(m_position.Magic());
               if(m_trade.PositionClose(m_position.Ticket())) //закрывает позицию
                 {
                  orders[(int)etype]--;
                  m_all--;
                  bRet=true;
                 }
              }
           }
        }

      for(int i=OrdersTotal()-1; i>=0; i--)
        {
         if(!SelectByIndex(i,false))
            continue;

         flag=toMyTypes(m_order.OrderType())&itype;

         if(itype==ALL || m_order.OrderType()==toDefType(flag,itype))
           {
            m_trade.SetExpertMagicNumber(m_position.Magic());
            if(m_trade.OrderDelete(m_order.Ticket())) //закрывает позицию
              {
               orders[(int)m_order.OrderType()]--;
               m_all--;
               bRet=true;
              }
           }
        }

      return bRet;
     }

   bool              OrderCloseAll(long iLockMagic,int itype)
     {
      __COPYRIGHT__

      int c=0,flag;

      bool bRet=false;

      for(int i=PositionsTotal()-1; i>=0; i--)
        {
         if(!SelectByIndex(i,true))
            continue;

         int etype=m_position.PositionType();
         long imagic=m_position.Magic();

         if((itype==OP_BUY && ((etype==OP_BUY && imagic!=iLockMagic) || (etype==OP_SELL && imagic==iLockMagic)))
            ||
            (itype==OP_SELL && ((etype==OP_SELL && imagic!=iLockMagic) || (etype==OP_BUY && imagic==iLockMagic))))
           {

            double dTakeProfit=m_position.TakeProfit();
            double dStopLoss=m_position.StopLoss();
            double dCurrentPrice=m_position.PriceCurrent();
            double dOpenPrice=m_position.PriceOpen();

            bool take_profit_level=false;

            if(m_position.TakeProfit()>0 && ((etype==OP_BUY && m_position.TakeProfit()-m_position.PriceCurrent()>=m_freeze) || (etype==OP_SELL && m_position.PriceCurrent()-m_position.TakeProfit()>=m_freeze)))
               take_profit_level=true;
            if(m_position.TakeProfit()==0.0)
               take_profit_level=true;

            bool stop_loss_level=false;

            if(m_position.StopLoss()>0 && ((etype==OP_BUY && MathAbs(m_position.PriceCurrent()-m_position.StopLoss())>=m_freeze) || (etype==OP_SELL && MathAbs(m_position.StopLoss()-m_position.PriceCurrent())>=m_freeze)))
               stop_loss_level=true;

            if(m_position.StopLoss()==0.0)
               stop_loss_level=true;

            if(take_profit_level && stop_loss_level)
              {

               m_trade.SetExpertMagicNumber(m_position.Magic());
               if(m_trade.PositionClose(m_position.Ticket())) //закрывает позицию
                 {
                  orders[(int)etype]--;
                  m_all--;
                  bRet=true;
                 }
              }
           }
        }

      for(int i=OrdersTotal()-1; i>=0; i--)
        {
         if(!SelectByIndex(i,false))
            continue;

         flag=toMyTypes(m_order.OrderType())&itype;

         if(itype==ALL || m_order.OrderType()==toDefType(flag,itype))
           {
            m_trade.SetExpertMagicNumber(m_position.Magic());
            if(m_trade.OrderDelete(m_order.Ticket())) //закрывает позицию
              {
               orders[(int)m_order.OrderType()]--;
               m_all--;
               bRet=true;
              }
           }
        }

      return bRet;
     }

   virtual bool      OrderCloseProfitAllNoLock(long iLockMagic,int itype)
     {
      __COPYRIGHT__

      int c=0,flag;

      bool bRet=false;

      for(int i=PositionsTotal()-1; i>=0; i--)
        {
         if(!SelectByIndex(i,true))
            continue;

         int etype=m_position.PositionType();

         flag=toMyTypes(etype)&itype;
         long imagic=m_position.Magic();

         if((itype==OP_BUY && ((etype==OP_BUY && imagic!=iLockMagic) || (etype==OP_SELL && imagic==iLockMagic)))
            ||
            (itype==OP_SELL && ((etype==OP_SELL && imagic!=iLockMagic) || (etype==OP_BUY && imagic==iLockMagic))))

           {
            double dProfit=m_position.Profit()+m_position.Swap()+m_position.Commission();
            if(dProfit>=0)
              {

               double dTakeProfit=m_position.TakeProfit();
               double dStopLoss=m_position.StopLoss();
               double dCurrentPrice=m_position.PriceCurrent();

               bool take_profit_level=false;

               if(m_position.TakeProfit()>0 && ((etype==OP_BUY && m_position.TakeProfit()-m_position.PriceCurrent()>=m_freeze) || (etype==OP_SELL && m_position.PriceCurrent()-m_position.TakeProfit()>=m_freeze)))
                  take_profit_level=true;
               if(m_position.TakeProfit()==0.0)
                  take_profit_level=true;

               bool stop_loss_level=false;

               if(m_position.StopLoss()>0 && ((etype==OP_BUY && MathAbs(m_position.PriceCurrent()-m_position.StopLoss())>=m_freeze) || (etype==OP_SELL && MathAbs(m_position.StopLoss()-m_position.PriceCurrent())>=m_freeze)))
                  stop_loss_level=true;

               if(m_position.StopLoss()==0.0)
                  stop_loss_level=true;

               if(take_profit_level && stop_loss_level)
                 {
                  m_trade.SetExpertMagicNumber(m_position.Magic());
                  if(m_trade.PositionClose(m_position.Ticket())) //закрывает позицию
                    {
                     orders[(int)etype]--;
                     m_all--;
                     bRet=true;
                    }
                 }
              }
           }
        }

      for(int i=OrdersTotal()-1; i>=0; i--)
        {
         if(!SelectByIndex(i,false))
            continue;

         flag=toMyTypes(m_order.OrderType())&itype;

         if(itype==ALL || m_order.OrderType()==toDefType(flag,itype))
           {
            m_trade.SetExpertMagicNumber(m_position.Magic());
            if(m_trade.OrderDelete(m_order.Ticket())) //закрывает позицию
              {
               orders[(int)m_order.OrderType()]--;
               m_all--;
               bRet=true;
              }
           }
        }

      return bRet;
     }

   bool              CloseByProfitInProcent(double dTPinProcent)
     {
      double dprofit=ND2(AccountBalance()*dTPinProcent/100);

      double dSummProfit=getProfit(ALL);

      if(dSummProfit>0 && dSummProfit>=dprofit)
        {

         OrderCloseAll(ALL);
         return true;
        }

      return false;

     }

   bool              SelfDestruct(int itype,long iLockMagic,double dTPinProcent)
     {

      int c=0;

      bool bRet=false;

      double dLockMinus=0;
      double dSetkaPlus=0;
      double dlock_lot=0;

      double dprofits[];
      ulong utickets[];
      ulong ulock=0;

      ArrayResize(utickets,0);
      ArrayResize(dprofits,0);

      double dTickProfit=SymbolInfoDouble(m_name,SYMBOL_TRADE_TICK_VALUE);

      bool bLock=false;

      for(int i=PositionsTotal()-1; i>=0; i--)
        {
         if(!SelectByIndex(i,true))
            continue;

         int etype=m_position.PositionType();
         ulong imagic=m_position.Magic();

         if((itype==OP_BUY && (etype==OP_BUY && imagic!=iLockMagic))
            ||
            (itype==OP_SELL && (etype==OP_SELL && imagic!=iLockMagic)))
           {
            double dprofit=Profit();

            if(dprofit>0)
              {
               int isize=ArraySize(utickets);

               if(ArrayResize(utickets,isize+1)!=-1 && ArrayResize(dprofits,isize+1)!=-1)
                 {

                  utickets[isize]=m_position.Ticket();
                  dprofits[isize]=dprofit;

                  dSetkaPlus+=dprofit;

                 }
              }

           }

         if((itype==OP_BUY && (etype==OP_SELL && imagic==iLockMagic))
            ||
            (itype==OP_SELL && (etype==OP_BUY && imagic==iLockMagic)))
           {
            double dprofit=Profit();

            if(dprofit<=0)
              {
               int isize=ArraySize(utickets);

               if(ArrayResize(utickets,isize+1)!=-1 && ArrayResize(dprofits,isize+1)!=-1)
                 {
                  ulock=m_position.Ticket();
                  dlock_lot=m_position.Volume();
                  utickets[isize]=m_position.Ticket();
                  dprofits[isize]=ND2(OrderProfitPoint()*(dlock_lot/2)*dTickProfit);

                  dLockMinus+=dprofit;
                  bLock=true;
                 }
              }

           }
        }

      int isize=ArraySize(utickets);
      if(bLock && dSetkaPlus>0 && isize>1 && NLot(dlock_lot)>=MinLot()*2)
        {
         double dprofit=ND2(AccountBalance()*dTPinProcent/100);

         if(ND2(dSetkaPlus+dLockMinus)>=ND2(dprofit))
           {

            for(int i=0; i<isize; i++)
              {

               if(ulock==utickets[i])
                 {
                  m_trade.SetExpertMagicNumber(m_position.Magic());
                  PrintFormat("Close self-destruct #%lld profit: %.2f",utickets[i], ND2(dprofits[i]));
                  OrderClose(utickets[i],NLot(dlock_lot/2));//закрываем все перекрытые
                 }
               else
                 {
                  m_trade.SetExpertMagicNumber(m_position.Magic());
                  PrintFormat("Close self-destruct #%lld profit: %.2f",utickets[i], dprofits[i]);
                  OrderClose(utickets[i]);//закрываем все перекрытые
                 }

              }

            return true;
           }
        }

      return false;
     }

   virtual void      SetAllforLock(long iLockMagic,int itype,double dstop,double dtake,bool bCheck=true,bool bForTral=false,double dTrailingStep=0)
     {
      int flag=0;
      int itotal=PositionsTotal();
      ulong iticket=0;

      for(int i=itotal-1; i>=0; i--)
        {
         if(!SelectByIndex(i,true))
            continue;

         if(m_position.Magic()==iLockMagic || m_position.Magic()==iLockMagic+1)
            continue;

         iticket=m_position.Ticket();
         long etype=m_position.PositionType();

         flag=toMyTypes(etype)&itype;

         if(etype==toDefType(flag,itype))
           {
            bool bModify=true;
            double dOrderStopLoss=m_position.StopLoss();
            double dOrderTakeProfit=m_position.TakeProfit();

            if(dstop==0 && dtake==0 && dOrderTakeProfit==0 && dOrderStopLoss==0)
               continue;

            if(bForTral && dstop>0 && dOrderStopLoss>0)
              {

               if(etype==OP_BUY && nd(dstop-dOrderStopLoss,m_position.Symbol())<dTrailingStep*p)
                  bModify=false;

               if(etype==OP_SELL && nd(dOrderStopLoss-dstop,m_position.Symbol())<dTrailingStep*p)
                  bModify=false;
              }

            if(dstop<0)
               dstop=dOrderStopLoss;

            if(dtake<0)
               dtake=dOrderTakeProfit;

            if(bModify)
              {

               if(CheckPositionModify(bCheck,m_position.Symbol(),etype,dOrderStopLoss,dOrderTakeProfit,dstop,dtake))
                 {
                  if(m_trade.PositionModify(iticket,dstop,dtake))
                    {
                     virtual_set(iticket,dstop,dtake);
                    }
                 }
               else
                 {

                 }

              }
           }

        }
     }

   void              Run(int iTradeMode,long iLockMagic,double dTPinProcent,double dLockTP,double dLockBU,double dLockTral, double dLockNext,double dLockMultiplicator,double dKopilkaProcent,double dMinimalLot,bool bSelfDestruct)
     {
      string _sExpertName=WindowExpertName();

      if(dLockBU>0)
         bu_simple_magic(iLockMagic,dLockBU,0);

      if(dLockTral>0)
         trailing_simple_magic(iLockMagic,dLockTral,dLockTral);

      double dprofit=ND2(AccountBalance()*dTPinProcent/100);

      if(iTradeMode==OP_SELL)
        {
         string sType=TypeToString(iTradeMode);
         double dKopilka=pglobal.LoadParam("Kopilka",0);

         this.OnTick();

         if(orders[OP_SELL]>=0)
           {

            if(bSelfDestruct)
              {
               if(SelfDestruct(OP_SELL,iLockMagic,dTPinProcent))
                  return; //для пересчета лока
              }

            double dSummLot=0;
            double dLastPrice=0,dPrice=0; //цена от которой идет рассчет для установки следующего лока
            datetime tmFirst=0,tmLast=0;

            ulong tlock=getOrderTicket(OP_BUY,0,iLockMagic); //проверим наличие лока

            if(OrderSelect(tlock))
              {
               double dtake=OrderTakeProfit();

               if(dtake==0)
                 {
                  double dopen=OrderOpenPrice();

                  if(dLockTP>0 && _Bid>=dopen+dLockTP*p)
                    {

                     OrderClose(tlock);
                     return;
                    }
                 }
              }

            ulong tlast=getLastOrderTicket(iLockMagic,dSummLot,OP_SELL,ORDER_UP); //найдем самый верхний селл

            /* if(dSummLot==0.0)
               {
                if(m_all>0)
                  {
                   Print("Close all orders.");
                   OrderCloseAll(iLockMagic,OP_SELL); //закроем оставшиеся ордера, так как основное направление (исправить закрытие)

                  }
                return;
               }*/

            if(OrderSelect(tlast,true))
              {
               tmFirst=OrderOpenTime();
               dPrice=OrderOpenPrice();
               double dlot=OrderLots();
               tmLast=tmFirst;

               Kopilka(iLockMagic,dKopilkaProcent,dMinimalLot,tlast,dlot,dSummLot,OP_SELL,tmFirst);

               if(OrderSelect(tlast,true))
                 {

                  dLastPrice=OrderOpenPrice();

                 }
              }

            /*
            проверяем не находимся ли мы ниже последнего ордера
            */

            if(tlock==0 && dLastPrice>0)
              {

               ulong thist=getHistoryOrderTicket(OP_BUY,tmLast,true);

#ifdef __MQL5__

               if(HistoryDealSelect(thist))
                 {
                  long ideal_magic=HistoryDealGetInteger(thist,DEAL_MAGIC);

                  if(ideal_magic==iLockMagic)
                    {

                     ulong id=HistoryDealGetInteger(thist,DEAL_POSITION_ID);
                     double dCloseTP=OrderClosePrice(id);
                     double dOpenTP=OrderOpenPrice(id);

                     if(dCloseTP>0 && dCloseTP>dLastPrice)
                        dLastPrice=dCloseTP; //обновим цену от которой считать следующий вход локом

                     if(dPrice>0 && tmFirst>0 && dPrice<dLastPrice && _Ask<dLastPrice)
                       {

                        double dprices[];
                        int j=CopyLow(m_name,PERIOD_M1,tmFirst,TimeCurrent(),dprices);
                        ArraySetAsSeries(dprices,true);

                        for(int i=0; i<j; i++)
                          {
                           if(dprices[i]<=dPrice)
                             {
                              dLastPrice=dPrice;
                              break;
                             }

                           if(dprices[i]<=dOpenTP-dLockNext*p)
                             {
                              dLastPrice=dOpenTP;

                             }
                          }
                       }
                    }
                 }

#else
               if(OrderSelect((int)thist,SELECT_BY_TICKET,MODE_HISTORY))
                 {

                  long ideal_magic=::OrderMagicNumber();

                  if(ideal_magic==iLockMagic)
                    {

                     double dCloseTP=::OrderClosePrice();

                     double dOpenTP=::OrderOpenPrice();

                     if(dCloseTP>0 && dCloseTP>dLastPrice)
                        dLastPrice=dCloseTP;

Показано первые 50% кода (символов: 21893)

Открыть по тарифу

Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.

Разовая покупка файла

На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.

Чтобы оформить заказ, введите email и перейдите к оплате.

Стоимость полного кода
2 189,30₽ ≈ $26.76