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

unlocker112.mq4

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

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

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

О программе

Данный продукт представляет собой торговый советник для MetaTrader 4, предназначенный для управления позициями и защиты от просадок через механизм частичного лока. Советник реализован в виде двух основных классов — CLock и CUnlocker, которые наследуют функциональность из внешней библиотеки sovetnikovNET\Orders.mqh.

Советник осуществняет анализ текущих позиций и ордеров, управляет торговыми операциями через стандартные API MetaTrader (OrderSend, OrderClose, OrderModify). Основные возможности включают закрытие позиций по условию достижения уровня прибыли или убытка, выставление и модификацию отложенных ордеров, а также усреднение позиции (грид-сетка) с нарастающими лотами.

Система содержит механизм «копилки», который накапливает прибыль от закрытых сделок и использует её для управления рисками, а также механизм «самоуничтожения», автоматически закрывающий позиции при достижении заданного процента прибыли от баланса. Стабилизация и поддержка позиций реализованы через дополнительные ордера с отдельным магическим числом.

В коде присутствуют условные блоки для MQL5 (использование индикаторов EMA и Parabolic SAR, работа с историями сделок), однако файл относится к платформе MQL4. Советник не содержит явно объявленных пользовательских входных параметров в данном фрагменте кода.

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

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

#ifndef __SOVETNIKOV_UNLOCKER_2sdfhgsd
#define __SOVETNIKOV_UNLOCKER_2sdfhgsd

#include <sovetnikovNET\Orders.mqh>

class CLock: public COrders
  {
public:
   datetime          tmKopilka;

   virtual 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)
              {

               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))
           {
            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)
                 {
                  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))
           {
            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)
        {
         Print(__LINE__);
         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();
         long 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])
                 {
                  PrintFormat("Close self-destruct #%lld profit: %.2f",utickets[i], ND2(dprofits[i]));
                  OrderClose(utickets[i],NLot(dlock_lot/2));//закрываем все перекрытые
                 }
               else
                 {
                  PrintFormat("Close self-destruct #%lld profit: %.2f",utickets[i], dprofits[i]);
                  OrderClose(utickets[i]);//закрываем все перекрытые
                 }

              }

            return true;
           }
        }

      return false;
     }

   virtual void      SetAll(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 dLockNext,double dLockMultiplicator,double dLotMultiplicator,double dAverageStep,double dStepMultiplicator,double dKopilkaProcent,double dMinimalLot,bool bSelfDestruct)
     {
      string _sExpertName=WindowExpertName();

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

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

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

         this.OnTick();

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

            if(tlock>0)
              {
               OrderClose(tlock);
               Reset(0,OP_SELL);
               return;
              }
           }

         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;

            int icount=Count(OP_SELL,iLockMagic+1); //посчитаем кол-во открытых ордеров усреднения, которые открыл лок
            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();

                  double dpt=OrderStep();

                  double dnextStep=ND1(MathPow(dStepMultiplicator,icount>0?(icount-1):0)*dAverageStep);

                  if(dpt<=-dnextStep && dnextStep>0 && dAverageStep>0 && dStepMultiplicator>0)
                    {

                     if(tlock>0)
                       {

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

                       }

                     double dNextLot=NLot(dlot*dLotMultiplicator); //найдем лот для усреднения

                     ulong t=OrderSend(OP_SELL,dNextLot,-1,0,0,StringFormat("%s-%d",_sExpertName,icount+1),false,iLockMagic+1);
                     DEBUG_OrderSend2(t,this);

                     if(OrderSelect(t))
                       {
                        tmFirst=OrderOpenTime();
                        dLastPrice=OrderOpenPrice();
                        dPrice=dLastPrice;

                        tlast=t; //последний открытый
                        tmLast=tmFirst;
                       }
                    }

                 }
              }

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

            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 || ideal_magic==iLockMagic+1)
                    {

                     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;
                              break;
                             }    
                          }
                       }
                    }
                 }

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

                  long ideal_magic=::OrderMagicNumber();

                  if(ideal_magic==iLockMagic || ideal_magic==iLockMagic+1)
                    {

                     double dCloseTP=::OrderClosePrice();

                     double dOpenTP=::OrderOpenPrice();

                     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;
                              break;
                             }   
                          }
                       }
                    }
                 }
#endif

               if(nd(_Ask)>=nd(dLastPrice+dLockNext*p))
                 {
                  double dLockLot=NLot(dSummLot*dLockMultiplicator);//рассчитаем новый лот лока

                  tlock=OrderSend(OP_BUY,dLockLot,-1,0,dLockTP,StringFormat("%s-LOCK",_sExpertName),true,iLockMagic);
                  DEBUG_OrderSend2(tlock,this);
                 }

              }

            int idirect=0;
            double dAvg=get_Average(iLockMagic,OP_SELL,idirect,dprofit); //рассчитаем точку тр с компенсацией на заданный профит

            if(idirect>=0)
              {

               SetAll(iLockMagic,OP_SELL,0,0,false,false);
              }
            else
              {

               if(_Ask<=dAvg)
                 {

                  OrderCloseAll(OP_SELL);
                 }
               else
                 {

                  SetAll(iLockMagic,OP_SELL,0,dAvg,false,false);
                 }
              }
           }
         else
           {
            Reset(0,OP_SELL); //сбросим копилку сетки
           }

        }

      if(iTradeMode==OP_BUY)
        {

         string sType=TypeToString(iTradeMode);
         double dKopilka=pglobal.LoadParam(StringFormat("Kopilka%s_Profit",sType),0);

         this.OnTick();

         if(orders[OP_BUY]==0)
           {

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

            if(tlock>0)
              {
               OrderClose(tlock);
               Reset(0,OP_BUY);
               return;
              }
           }

         if(orders[OP_BUY]>0)
           {

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

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

            int icount=Count(OP_BUY,iLockMagic+1); //посчитаем кол-во открытых ордеров усреднения, которые открыл лок
            ulong tlock=getOrderTicket(OP_SELL,0,iLockMagic); //проверим наличие лока

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

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

                  if(dLockTP>0 && _Ask<=dopen-dLockTP*p)
                    {
                     OrderClose(tlock);
                     return;
                    }
                 }
              }

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

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

                 }
               return;
              }

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

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

               if(OrderSelect(tlast,true))
                 {

                  dLastPrice=OrderOpenPrice();

                  double dpt=OrderStep();

                  double dnextStep=ND1(MathPow(dStepMultiplicator,icount>0?(icount-1):0)*dAverageStep);

                  if(dpt<=-dnextStep && dnextStep>0 && dAverageStep>0 && dStepMultiplicator>0)
                    {

                     if(tlock>0)
                       {

                        OrderClose(tlock);
                        Kopilka(iLockMagic,dKopilkaProcent,dMinimalLot,tlast,dlot,dSummLot,OP_BUY,tmFirst);

                       }

                     double dNextLot=NLot(dlot*dLotMultiplicator); //найдем лот для усреднения

                     ulong t=OrderSend(OP_BUY,dNextLot,-1,0,0,StringFormat("%s-%d",_sExpertName,icount+1),false,iLockMagic+1);
                     DEBUG_OrderSend2(t,this);

                     if(OrderSelect(t))
                       {
                        tmFirst=OrderOpenTime();
                        dLastPrice=OrderOpenPrice();

                        tlast=t; //последний открытый
                        tmLast=tmFirst;
                       }
                    }

                 }
              }

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

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

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

#ifdef __MQL5__

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

                  if(ideal_magic==iLockMagic || ideal_magic==iLockMagic+1)
                    {

                     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 && _Bid>dLastPrice)
                       {

                        double dprices[];
                        int j=CopyHigh(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;
                              break;
                             }  
                          }
                       }
                    }
                 }

#else
               if(OrderSelect((int)thist,SELECT_BY_TICKET,MODE_HISTORY))
                 {
                  long ideal_magic=::OrderMagicNumber();

                  if(ideal_magic==iLockMagic || ideal_magic==iLockMagic+1)
                    {

                     double dCloseTP=::OrderClosePrice();
                     double dOpenTP=::OrderOpenPrice();

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

                     if(dPrice>0 && tmFirst>0 && dPrice>dLastPrice && _Bid>dLastPrice)
                       {

                        double dprices[];
                        int j=CopyHigh(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;
                              break;
                             }  
                          }
                       }
                    }
                 }
#endif

               if(nd(_Bid)<=nd(dLastPrice-dLockNext*p))
                 {

                  double dLockLot=NLot(dSummLot*dLockMultiplicator);//рассчитаем новый лот лока

                  tlock=OrderSend(OP_SELL,dLockLot,-1,0,dLockTP,StringFormat("%s-LOCK",_sExpertName),true,iLockMagic);
                  DEBUG_OrderSend2(tlock,this);
                 }

              }

            int idirect=0;
            double dAvg=get_Average(iLockMagic,OP_BUY,idirect,dprofit); //рассчитаем точку тр с компенсацией на заданный профит

            if(idirect<=0)
              {

               SetAll(iLockMagic,OP_BUY,0,0,false,false);
              }
            else
              {
               if(_Bid>=dAvg)
                 {

                  OrderCloseAll(OP_BUY);
                 }
               else
                 {

                  SetAll(iLockMagic,OP_BUY,0,dAvg,false,false);
                 }
              }
           }
         else
           {
            Reset(0,OP_BUY); //сбросим копилку сетки
           }

        }

     }

   virtual bool      Check(string symbol,long imagic)
     {

      if((m_name==NULL || symbol==m_name) && (m_imagic==-1 || m_imagic==imagic || imagic==-1))
         return true;

      return false;
     }

   virtual double    get_Average(long iLockMagic,int itype,int &idirect,double dProfit=0)
     {

      double SummPrice=0.0,SummLots=0.0,Formula=0.0,SummLoss=0.0;
      int k=0,flag=0;
      idirect=0;

      int total=PositionsTotal();
      double tickvalue=SymbolInfoDouble(m_name,SYMBOL_TRADE_TICK_VALUE);

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

         long etype=m_position.PositionType();

         if((m_position.Magic()==iLockMagic && etype==InverseSignal((ENUM_ORDER_TYPE)itype)) || (m_position.Magic()!=iLockMagic && etype==itype))
           {
            k++;
            if(etype==OP_BUY)
              {
               SummLots+=m_position.Volume();
               SummPrice+=m_position.PriceOpen()*m_position.Volume();
               SummLoss+=2*m_position.Commission()+m_position.Swap();
              }
            else
               if(etype==OP_SELL)
                 {
                  SummLots-=m_position.Volume();
                  SummPrice-=m_position.PriceOpen()*m_position.Volume();
                  SummLoss+=2*m_position.Commission()+m_position.Swap();
                 }

           }

        }//Next i

      if(k>0 && tickvalue*Abs(SummLots)>0)
        {
         if(SummLots>0)
            idirect=1;
         else
            if(SummLots<0)
               idirect=-1;

         if(idirect==0)
            return 0;

         double points=SymbolInfoDouble(m_name,SYMBOL_POINT);
         double doffset=idirect*((dProfit-SummLoss)/(tickvalue*Abs(SummLots))*points);

         Formula=nd(Abs(SummPrice/SummLots)+doffset,m_name);

        }

      return Formula;
     }

   void              Reset(datetime tmNew,int itype)
     {
      if(tmNew==0.0)
        {
         tmKopilka=0;
         pglobal.SaveParam(StringFormat("Kopilka%s_Profit",TypeToString(itype)),0); //сбросим копилку
         pglobal.SaveParam(StringFormat("Kopilka%s_Time",TypeToString(itype)),0); //сбросим копилку
        }

      tmKopilka=(datetime)pglobal.LoadParam(StringFormat("Kopilka%s_Time",TypeToString(itype)),0);

      if(tmNew>tmKopilka)
        {
         tmKopilka=tmNew;
         pglobal.SaveParam(StringFormat("Kopilka%s_Time",TypeToString(itype)),tmKopilka); //сохраним новое время для копилки
        }

     }

   virtual ulong      getLastOrderTicket(long iLockMagic,double &dSummLot,int itype,_ORDER_MODE imode=ORDER_UP,datetime dtmOpen=0)
     {
      double array_order_open[][2]; //0- price,1-ticket
      ArrayResize(array_order_open,0);

      dSummLot=0;

      int c=0;

      for(int i=PositionsTotal()-1; i>=0; i--)
        {

         if(!SelectByIndex(i,true))
            continue;

         ulong uOrderTicket=m_position.Ticket();
         int lOrderType=m_position.PositionType();
         double dOrderOpenPrice=m_position.PriceOpen();
         double dOrderLots=m_position.Volume();

         if(m_position.Time()>=dtmOpen)
           {

            if(lOrderType==POSITION_TYPE_BUY && itype==OP_BUY)
              {

               ArrayResize(array_order_open,c+1);
               array_order_open[c][0]=dOrderOpenPrice;
               array_order_open[c][1]=(double)uOrderTicket;
               dSummLot+=dOrderLots;
               c++;
              }

            if(lOrderType==POSITION_TYPE_SELL && itype==OP_SELL)
              {

               ArrayResize(array_order_open,c+1);
               array_order_open[c][0]=dOrderOpenPrice;
               array_order_open[c][1]=(double)uOrderTicket;
               dSummLot+=dOrderLots;
               c++;
              }
           }

        }

      if(itype==OP_BUY && c>0)
        {
         ArraySort(array_order_open); //сортируем в сторону увеличения, тогда 0й ордер будет самый нижний, последний сверху (первый).
         if(imode==ORDER_DN)
            return ((ulong)array_order_open[0][1]

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

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

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

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

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

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

Стоимость полного кода
3 747,50₽ ≈ $45.80