0
Да. Еще одно замечание. Так как MinTP у нас в пипсах, то при определенных настройках,
из-за спреда и комиссии минимальный профит может оказаться и убыточным. Немного, но…

Можно перейти на профиты ордеров. Когда общий профит будет больше чем…

Так. Мысль после тестирования настигла. Это не критично, но все таки.
avatar

kvashnin007

  • 10 февраля 2025, 15:31
0
Да. И кстати, я постоянно пишу, что я не гуру, а только учусь.
avatar

kvashnin007

  • 10 февраля 2025, 15:12
0
Что вам в моем коде не понравилось, я понял. Просто ничего. Вопросы, как всегда в общении с вами, не находят ответов. А не умение программировать не является недостатком. Это просто то, что не умею. Я вон тоже многого не умею. Зато всегда найду того, кто поможет или сам сделает. Это то как раз нормально. Я здесь не занимаюсь ликбезом. Ищу соратников для совместного ликбеза.

Не нормально другое: общение через губу.

Еще хуже — хамскок, как у SSG.
Или вы не считаете его общение таковым?

В таком случае нам реально не стоит общаться.

Удачи вам.

avatar

kvashnin007

  • 10 февраля 2025, 15:10
0
Скоро как три года живу в России. Но от этого я не перестал считать себя одесситом.

И где я подтрунивал? Реакция на ваши подтрунивания и, заметьте, вашими же словами.
Кстати. Кто такие МЫ? осталось без ответа.

Где я не прав в общении с вами?

Поконкретнее, пожалуйста. И объективно. С учетом того откуда и почему.
Следили бы лучше за своим языком.
avatar

kvashnin007

  • 10 февраля 2025, 14:58
0
Как только Эквити оторвался от депозита на установленную нами сумму, все закрывается.
Заметьте ни намека в большую или меньшую сторону.
А на счет игнорирования второго условия вы абсолютно правы. На то оно и «или».

В советнике я пытался использовать вариант превышения отрыва в плюс. А вы, вместо того, чтобы подсказать, что можно также использовать эту функцию и в обратном направления, что-то там поете за бездарный труд, за бабки.

Судя по вашим опусам, вы далеки от программирования, как я от Одессы.
Кроме того, пожалуйста, покажите свой уДАРНЫЙ (т.е. не бездарный) труд. Который вы своими ручками сваяли.
Может я и поменяю свое мнение о вас. Буду сильно удивлен.

Пора создавать закрытую группу. А то только время отнимаете на перепалку.
И еще. Можете радоваться уже сейчас. Никому ничего не продаю. Стыдно. Гимнастика для ума + общение.
В моем возрасте необходимые вещи.

И вообще: не нравиться — не ешь. А то слюни во все стороны. Тут уже был один такой умник. Отвалился.

avatar

kvashnin007

  • 10 февраля 2025, 12:40
0
Дальше вижу два варианта доработки.:

1. Разделить переменные по тренду. Вниз — одни переменные, вверх — другие.
2. Для возможного кеширования, разделить еще и эти (или только) на продажи и отдельно на покупки.
Получается плюс четыре варианта. Но… Их можно настраивать поочереди. Покупки вниз, покупки вверх и…

Погонять, выкинуть лишнее и заняться темой топика.

Потом разработаем методику оптимизации.

Должен получиться не лучший, но рабочий советник для реальной торговли.
avatar

kvashnin007

  • 10 февраля 2025, 12:13
0
Уважаемый, OSS5.

Чем больше «совершенствуем» советник, тем большая печалька меня охватывает.
Вчера сел и проверил наши варианты на соответствие работы при одинаковых условиях.
Первый и второй варианты не трогаю. Ибо мы от них отклонились. Как минимум в части открытия ордеров.

А вот третий с четвертым не ОГО. Вроде четверка это доработанная тройка и с отключенными «улучшениями»
должна показывать одинаковые результаты. Ан нет. Пришлось переписать код по-новому.
Честно говоря, различий я не обнаружил, но, видимо, они есть.

Я перезалью советник. Если не сложно презалейте его в базе.
А лучше дайте мне почту, куда закидывать файл, а вы уже его в базу.

Спасибо.

В следующий вариант хочу всунуть трал SL. Посмотреть, что из этого получится.
Обычный трал поордерно не вписывается. Хотя…

Представим себе: открыли ордер SELL. Цена пошла вниз, не дошла до ТР, а уже подключился трал SL или БУ.
Цена пошла вверх. По стратегии через шаг нужно открывать удвоенный ордер SELL. А наш первый ордер закрылся по тралу. Ладно хоть в небольшой плюс (MinTP). Ордеров нет — открываем опять стартовый. Но ниже цены первого села, ибо его мы закрываем Тралом ниже первой цены. Хорошо мы ничего, кроме стартовой позиции не потеряли.

Цена опять идет вверх открываем удвоенный SELL. Откуда трал начинать? А если цена опять вверх пойдет?
А трал еще не сработал. А сработал он, например, на удвоенном ордере.
Хотя интересная картина получается.Нижний ордер не закроется. Закроется верхний в БУ+. И как только цена оторвется от нижнего на шаг, то тутже откроется удвоенный от нижнего ордер SELL. Т.е. мы вернулись к алгоритму,
при этом еще и зафиксировали минимальный, но профит.
Т.е. получается, что тралиться у нас будет только верхний ордер. И по мере падения цены все нижние ордера тоже будут подключаться к тралу SL и он получится общим, для всех ордеров SELL. И закроются они все по общему SL.
При этом, естественно, ордерам, который встали на трал, надо будет отменять индивидуальный ТР.
А выставлятьТР от нижнего ордера на продажу. Как все замучено. Но можно попробовать.
Один минусик: цена шла-шла вниз, небольшой откат закрыл по тралу все ордера на попродажу. А цена — опять вниз.

Не совсем без нас, ибо при отсутствии ордеров на продажу тутже появляется стартовый.
Лот минимальный, но всеже.
Довольно неплохо должно получиться. С него и начну.

Я тут заморачивался с тралом общего БУ+. Иногда получалась не совсем пригодная картина.
При сокращении ордеров и пересчете общего БУ+, он находится между… Херня. Тоже надо пробовать.
Но потом.

Эти два трала, скорее всего, не совместимы. А вот с первым можно будет пробовать совмещать.

Для наблюдателей: в конечном итоге что-то из советника уберется, что-то останется.
avatar

kvashnin007

  • 10 февраля 2025, 12:06
0
Идея сырая в программировании бесполезна. Изначально ее надо обсосать. Продумать: что делать, если…
avatar

kvashnin007

  • 10 февраля 2025, 09:56
0
Простая функция. По возможности тралим SL или ставим ордеруSL в БУ+MinTP и, если ордер закрылся по стопу, открываем противоположный ордер с увеличенным лотом. по типу «неваляшки».
avatar

kvashnin007

  • 10 февраля 2025, 09:53
0
Я как-то писал свою тянучку за импульсом. Там я «тянул» стоповый ордер за ценой. По идее: если цена ломанулась резко и далеко, то она должна вернуться взад. Хотя бы на 50%. Потом забросил. Как всегда, появились более интересные темы.
avatar

kvashnin007

  • 10 февраля 2025, 09:47
0
Уважаемый, Алекс.

Прежде чего-то написать, я вдумываюсь в смысл. Кроме того, написав, я читаю и правлю написанное.

Последняя формула, это общая функция. Ни вашим, ни нашим. Я ее дал для просмотра спецам.
Если бы вы следили топиком, то заметили бы, что вопрос посмотреть где пЛОХ, я задавал еще 7 февраля.
Тогда вас не было видно. Эта формула общая. Берете любой свой советник, добавляете функцию.Прописываете
первой строкой в OnTick() TrailingEquity1();. Добавляете эти две внешних переменных,
input double Equity_RollbackUp и input double Equity_RollbackDown, запускаете прогон и сообщаете
:-«А у меня работает. И очень даже… Выкиньте свой комп.»

Ладно. Если с кодом не помогли, то хоть ответьте на вопрос: с какого бадуна вы думаете, что
«скорее всего по итогу это условие будет противоричивым»?
if(CurrentnEQ-CurrentnPR >= Equity_RollbackUp || CurrentnEQ-CurrentnPR <= — Equity_RollbackDown)

То есть вы видите мгновения, когда эквити может быть одновременно и больше депозита и меньше его?
Вы чего написали, вы хотя чуть -чуть вдумываетесь в смысл написанного.Методом тыка хороший советник не получиться.

Насчет МЕТОДА.
Где вы в этом топике наблюдаете «ТЫКА»?
Все идет плавно и последовательно.
Этот советник мне лично интересен, как предмет для основной темы топика.
Я просил кого-нибудь дать советник свой. Для работы над ним. Ладно. Взял свой дредний.
С момента его написания прошла уйма времени. Многие вещи я удже вижу в другиг тонах. Отчего же не поизмываться?
Тем более, что результатом топика должен быть вполне себе рабочий советник для реальных торгов.

Вы, наверно, не просили написать вам советник по вашей «идее». Ибо заметили бы постпросьбы:
Андрей Все охрененно. А можно ли добавить, то. А может это? И все. Вашей идее капут. Возможно, зря.
Но вы этого уже не узнаете никогда.

Да и еще.

Знак или я знал еще в те времена, когда вы еще под стол пешем ходили. Ну или уже немного повзрослее были.
avatar

kvashnin007

  • 10 февраля 2025, 08:51
0
Ничесе повеселился

Часть №4


//************************************************************************************************/
bool TrailingEquity()
{  
     if(Equity_Rollback == 0)                           // Если трал эквити не разрешeн
        return(false);                                  // выходим
        
     double CurrentnEQ  = AccountEquity() ;             // Текущий эквити меняется с каждым тиком
     
     // --------- Этап 1 - ожидание начала цикла для получения стартового эквити ---------
       
     if(b+s == 0)                                       // Если нет ордеров (начало очередного этапа)
        {
        CloseEQ = AccountEquity();                      // Запоминаем эквити на начало цикла, пока не появится хоть один ордер.
        return (false);                                 // Трал эквити еще не закончил свою работу.
        }
     
     // ------------------------- Этап 2 - работа трала эквити -----------------------------
     
      if(b+s > 0)                                       // Если появился ордер (начало очередного этапа) 
        {
        if(TrailEQ == false)                            // Если трал эквити еще не начался, то следим за эквити. 
           {  //                                         
           if(CurrentnEQ >= CloseEQ + Equity_Rollback)  // Если текущий эквити оторвался в + от стартового на дистанцию трала и более
               {
               CloseEQ = CurrentnEQ - Equity_Rollback;  // Запоминаем эквити для закрытия всего, который будем подтягивать за растущим эквити.
               TrailEQ = true;                          // Флаг начала трэйлинга подняли. Заработал трал эквити. 
               Alert ("Сработал Трэйлинг эквити");
               return (false);                          // Трал начал работу, но не выполнил еще свою функцию.
               }                                        // Просто передаем слежение за эквити дальнейшему алгоритму на последующих тиках 
           }    
        if(TrailEQ == true)                             // Если трал запущен и уже тралит эквити.
           {                                             
           if(CurrentnEQ > CloseEQ + Equity_Rollback)   // Если текущий эквити отрывается дальше  в + от эквити для закрытия CloseEQ
              CloseEQ = CurrentnEQ - Equity_Rollback;   // Каждый раз величиваем уровень эквити для закрытия CloseEQ
              //---                                        Если текущий эквити падает, эквити на закрытие остается на месте.
           if(CurrentnEQ <= CloseEQ)                    // Если текущий эквити упал до уровня срабатывания трала
              {  
              TrailEQ = false;                           // Флаг начала трэйлинга снимаем.                      
              Alert ("Сигнал на защиту Эквити");
              return (true);                             // Функция сработала.
              }
           } 
        } 
     return (false);                                     // Иначе трал трудится    
}
//************************************************************************************************/
void CloseAll()
{
   int    nn = 0,OMN,OT,Ticket,j; 
   int    total = OrdersTotal();
   double profits  = 0;
   
   while(true)
      {
      for (j = total-1; j >= 0; j--)
         {
         if (OrderSelect(j, SELECT_BY_POS))  
            {
            OT     = OrderType();
            OMN    = OrderMagicNumber();
            Ticket = OrderTicket();
            
            if (OT==OP_BUY) 
               if (OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_BID),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),Slippage,Blue)) 
                  profits+=OrderProfit();
             //---
            if (OT==OP_SELL) 
               if (OrderClose(Ticket,OrderLots(),NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),(int)MarketInfo(OrderSymbol(),MODE_DIGITS)),Slippage,Red)) 
                  profits+=OrderProfit();
            }
         }
      int n=0;
      
      for (j = 0; j < OrdersTotal(); j++)
         if (OrderSelect(j, SELECT_BY_POS))
            {
            OT = OrderType();
            n++;
            }
      if (n==0) break;
      nn++;
      if (nn>10) 
         Alert(Symbol()," Не удалось закрыть все сделки, осталось еще ",n);
      Sleep(1000);
      RefreshRates();
      }
      Alert(Symbol()," Закрыли все сделки ");
}
//************************************************************************************************/


avatar

kvashnin007

  • 8 февраля 2025, 14:48
0
Часть №3


                      //--- Выставляем ТР крайним ордерам OP_SELL в безубыток + ----
                      if(s>=CountAverage)
                         {
                         if(CloseOrder==FullAwerage)  // Закрываем оба ордера
                           if(tk==SelPriceMaxTic || tk==SelPriceMinTic)
                              if(Ask>AverageSelPrice && tp!=AverageSelPrice)
                                 if(!OrderModify(tk,op,OrderStopLoss(),AverageSelPrice,0,clrRed))
                                    Print("OrderModify error №6 #",GetLastError());
                         //---
                         if(CloseOrder==NoClose)      // Закрываем только убыточный ордер
                           if(tk==SelPriceMaxTic)
                              if(Ask>AverageSelPrice && tp!=AverageSelPrice)
                                 if(!OrderModify(tk,op,OrderStopLoss(),AverageSelPrice,0,clrRed))
                                    Print("OrderModify error №7 #",GetLastError());
                         //---
                         if(CloseOrder==StartClose && Ask<=AverageSelPrice)
                            {                
                            if(tk==SelPriceMaxTic)    // Профитному оставляем стартовый лот
                               if(!OrderClose(tk,NormalizeDouble(SelPriceMaxLot-StartLots,2),Ask,Slippage,clrBlue))
                                  Print("OrderModify error №3 #",GetLastError());
                            if(tk==SelPriceMinTic)    // А убыточный закрываем весь
                               if(!OrderClose(tk,lt,Ask,Slippage,clrBlue))
                                  Print("OrderModify error №3 #",GetLastError());
                            }
                         //---
                         if(CloseOrder==StartStart && Ask<=AverageBuyPrice)
                            {                
                            if(tk==SelPriceMaxTic)    // От профитномого убавлем стартовый лот
                               if(!OrderClose(tk,StartLots,Ask,Slippage,clrBlue))
                                  Print("OrderModify error №3 #",GetLastError());
                            if(tk==SelPriceMinTic)    // Убыточный закрываем весь
                               if(!OrderClose(tk,lt,Ask,Slippage,clrBlue))
                                  Print("OrderModify error №3 #",GetLastError());
                            }
                          }
                      }
                      //-------- Восстановление ТР не крайним ордерам OP_SELL ---------
                      if(tk != SelPriceMinTic && tk != SelPriceMaxTic)     
                         if(tp!= NormalizeDouble (op - TakeProfit * Point(), Digits()))
                            if(!OrderModify(tk, op, OrderStopLoss(), NormalizeDouble (op - TakeProfit * Point(), Digits()), 0, clrRed))
                               Print("OrderModify error №8 #", GetLastError());
                    }   //  End OP_SELL
}
//************************************************************************************************/
//*                      ФУНКЦИИ                                                                 */
//************************************************************************************************/
double GetLotPersent() //Функция возвращает значение лотов,
{ 
         double lots,MD,MinLots,MaxLots, LotSize; 
         int    lotsdigit=0; //вычисляется путем:Свободные средства*Risk
         
         MinLots = NormalizeDouble(MarketInfo(Symbol(),MODE_MINLOT),2);
         MaxLots = NormalizeDouble(MarketInfo(Symbol(),MODE_MAXLOT),2);
         LotSize = MarketInfo(Symbol(), MODE_LOTSIZE);                     //поделить на стоимость одного лота
         MD      = NormalizeDouble(MarketInfo(Symbol(), MODE_LOTSTEP), 2);
         
          //А также вычисляем колличество знаков
         if(MD==0.01) 
            lotsdigit=2; //присваивает значения максимума лотов
         if(MD==0.1) 
            lotsdigit=1; //присваивает значения максимума лотов
            
         if(MM) 
            lots=NormalizeDouble((AccountFreeMargin()*Risk/LotSize),lotsdigit);
         else 
            lots=StartLots;
         
         if(lots < MinLots) 
            lots = MinLots;
         if(lots > MaxLots) 
            lots = MaxLots;
   return(NormalizeDouble(lots,lotsdigit));
}
//************************************************************************************************/
bool CheckVolumeValue(double volume)
{
         //--- минимально допустимый объем для торговых операций
         double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
         if(volume<min_volume)
            return(false);
   
         //--- максимально допустимый объем для торговых операций
         double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
         if(volume>max_volume)
            return(false);

         //--- получим минимальную градацию объема
         double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);
      
         int ratio=(int)MathRound(volume/volume_step);
         if(MathAbs(ratio*volume_step-volume)>0.0000001)
            return(false);

   return(true);
}
//************************************************************************************************/
avatar

kvashnin007

  • 8 февраля 2025, 14:42
0
Часть №2


//************************** Определение средней цены между крайними ордерами + Минимальный профит **************************
      double   AverageBuyPrice=0,AverageSelPrice=0;
      
      if(b>=CountAverage) 
         AverageBuyPrice = NormalizeDouble((BuyPriceMax*BuyPriceMaxLot+BuyPriceMin*BuyPriceMinLot)
                           /(BuyPriceMaxLot+BuyPriceMinLot)+MinimalProfit*Point(),Digits());
      if(s>=CountAverage) 
         AverageSelPrice = NormalizeDouble((SelPriceMax*SelPriceMaxLot+SelPriceMin*SelPriceMinLot)
                           /(SelPriceMaxLot+SelPriceMinLot)-MinimalProfit*Point(),Digits());
                        
//*********************************** Определение лотов на покупку и продажу ************************************************
      double BuyLot = 0, SelLot = 0;
      
      //----------------  Если ММ не разрешeн ----------------
      if(!MM)
         {
         if(b==0)
            BuyLot = StartLots;
         else
            BuyLot = NormalizeDouble(MathCeil((BuyPriceMinLot * CoeffLots)*100)/100,2);
         //---   
         if(s==0)
            SelLot = StartLots;
         else
            SelLot = NormalizeDouble(MathCeil((SelPriceMaxLot * CoeffLots)*100)/100,2);
         }
      //----------------  Если ММ разрешeн ----------------
      if(MM)
         {
         if(BuyPriceMinLot == 0 || b==0)
            BuyLot = GetLotPersent();
         else
            BuyLot = NormalizeDouble(MathCeil((BuyPriceMinLot * CoeffLots)*100)/100,2);
         //---   
         if(SelPriceMaxLot == 0 || s==0)
            SelLot = GetLotPersent();
         else
            SelLot = NormalizeDouble(MathCeil((SelPriceMaxLot * CoeffLots)*100)/100,2);
         }
        //--- Проверка лотов на превышение максимально нами разрешенного --- 
         if(BuyLot>MaximalLots)      
           BuyLot=NormalizeDouble(MaximalLots,2);
         if(SelLot>MaximalLots)      
           SelLot=NormalizeDouble(MaximalLots,2);
           
         //--- Проверка лотов на валидность---  
         if(!CheckVolumeValue(BuyLot) || !CheckVolumeValue(SelLot))
            return;   
//************************** Открытие ордеров ******************************

            SignalB = false; SignalS = false;

            if(OpenOrder == NoBars)
               {
               SignalB = true;
               SignalS = true;
               }
            if(OpenOrder == OutOpen)
               {
               if(Open[0]<Open[1] && Bid>Open[1])
                  SignalB = true;
               if(Open[0]>Open[1] && Bid<Open[1])
                  SignalS = true;
               }
            if(OpenOrder == cCloseOut)
               {
               if(Open[1]<Open[2] && Close[1]>High[2])
                  SignalB = true;
               if(Open[1]>Open[2] && Close[1]<Low[2])
                  SignalS = true;
               }

            if((b==0) || (b>0 && SignalB && (BuyPriceMin-Ask)>(PointOrderStep*Point())))
               if(OrderSend(Symbol(),OP_BUY,NormalizeDouble(BuyLot,2),NormalizeDouble(Ask,Digits()),Slippage,0,0,"",MagicNumber,0,clrBlue)<0)
                  Print("Order Buy Send error #",GetLastError());
      
            if((s==0) || (s>0 && SignalS && (Bid-SelPriceMax)>(PointOrderStep*Point())))
               if(OrderSend(Symbol(),OP_SELL,NormalizeDouble(SelLot,2),NormalizeDouble(Bid,Digits()),Slippage,0,0,"",MagicNumber,0,clrRed)<0)
                  Print("Order Sell Send error #",GetLastError());
                  
//********************** Сопровождение ордеров в цикле **********************
         for(int i=OrdersTotal()-1;i>=0;i--)
            if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
               if(OrderMagicNumber()==MagicNumber)
                  if(OrderSymbol()==Symbol())
                    {
                    op=NormalizeDouble(OrderOpenPrice(),Digits());
                    tp=NormalizeDouble(OrderTakeProfit(),Digits());
                    lt=NormalizeDouble(OrderLots(),2);
                    tk=OrderTicket();
                    sl=OrderStopLoss();
                     
                    if(OrderType()==OP_BUY && b==1 && tp==0)
                      {
                      //--- Выставляем SL и ТР стартовым ордерам OP_BUY ---------
                      if(b==1 && tp==0)
                        {
                         sl=0; tp=0;
                        
                         if(StopLoss>0)
                            sl=NormalizeDouble(Ask-StopLoss*Point(),Digits());
                         if(TakeProfit>0)
                            tp=NormalizeDouble(Ask+TakeProfit*Point(),Digits());
                    
                         if(!OrderModify(tk,op,sl,tp,0,clrBlue))
                            Print("OrderModify error №1 #",GetLastError());
                         }
                      //--- Выставляем ТР крайних ордеров OP_BUY в безубыток + --------
                      if(b>=CountAverage)
                         {
                         if(CloseOrder==FullAwerage)
                            if(tk==BuyPriceMaxTic || tk==BuyPriceMinTic)
                               if(Bid<=AverageBuyPrice && tp!=AverageBuyPrice)
                                  if(!OrderModify(tk,op,OrderStopLoss(),AverageBuyPrice,0,clrBlue))
                                     Print("OrderModify error №2 #",GetLastError());
                         //---
                         if(CloseOrder==NoClose)
                            if(tk==BuyPriceMinTic)
                               if(Bid<=AverageBuyPrice && tp!=AverageBuyPrice)
                                  if(!OrderModify(tk,op,OrderStopLoss(),AverageBuyPrice,0,clrBlue))
                                     Print("OrderModify error №3 #",GetLastError());
                         //---
                         if(CloseOrder==StartClose && Bid>=AverageBuyPrice)
                            {                
                            if(tk==BuyPriceMinTic)    // Профитному оставляем стартовый лот
                               if(!OrderClose(tk,NormalizeDouble(BuyPriceMinLot-StartLots,2),Bid,Slippage,clrBlue))
                                  Print("OrderModify error №3 #",GetLastError());
                            if(tk==BuyPriceMaxTic)    // Убыточный закрываем весь
                               if(!OrderClose(tk,lt,Bid,Slippage,clrBlue))
                                  Print("OrderModify error №3 #",GetLastError());
                            }
                         //---
                         if(CloseOrder==StartStart && Bid>=AverageBuyPrice)
                            {                
                            if(tk==BuyPriceMinTic)    // От профитномого сокращаем стартовый лот
                               if(!OrderClose(tk,StartLots,Bid,Slippage,clrBlue))
                                  Print("OrderModify error №3 #",GetLastError());
                            if(tk==BuyPriceMaxTic)    // Убыточный закрываем весь
                               if(!OrderClose(tk,lt,Bid,Slippage,clrBlue))
                                  Print("OrderModify error №3 #",GetLastError());
                            }
                         }
                                 
                      //--------- Восстановление ТР не крайним ордерам OP_BUY --------------
                      if(tk != BuyPriceMinTic && tk != BuyPriceMaxTic)     
                        if(tp!= NormalizeDouble (op + TakeProfit * Point(), Digits()))
                          if(!OrderModify(tk, op, OrderStopLoss(), NormalizeDouble (op + TakeProfit * Point(), Digits()), 0, clrBlue))
                            Print("OrderModify error №4 #", GetLastError());
                      } //  End OP_BUY
                   //---------------------------------------------------------------------
                   if(OrderType()==OP_SELL)
                      {
                      // Выставляем SL и ТР стартовым ордерам OP_SELL
                      if(s==1 && tp==0)
                        {
                        sl=0; tp=0;
                        
                        if(StopLoss>0)
                           sl=NormalizeDouble(Bid+StopLoss*Point(),Digits());
                        if(TakeProfit>0)
                           tp=NormalizeDouble(Bid-TakeProfit*Point(),Digits());
                           
                        if(!OrderModify(tk,op,sl,tp,0,clrRed))
                           Print("OrderModify error №5 #",GetLastError());
                        }
avatar

kvashnin007

  • 8 февраля 2025, 14:40
0
Добавил два обещанных варианта сокращения ордеров. Расставил их по увеличению просадки.
Я стараюсь оптимизировать не по балансу, а по просадке.
По балансу, конечно, прибыльность огого, но… Это путь к потере депозита.

В среднем просадка уменьшилась относительно FullAverage.

Завтра добавлю трал общего БУ направлений. Надеюсь.

А пока простыни на V 1.4.

Часть №1


//+------------------------------------------------------------------+
//|                                                     KAE Grid.mq4 |
//|                                                   Copyright 2025 |
//|                                            kvashnin007@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025"
#property version   "1.4"
#property strict
//************************************************************************************************/
//*                                                                                              */
//************************************************************************************************/
enum ENUM_OO         // Вариант открытия ордеров
   {
   NoBars     = 0,     // No Bars       - Открываем ордера при их отсутствии, не глядя на бар
   OutOpen    = 1,     // Out Open      - Открываем ордера при их отсутствии, если цена пробила цену открытия предыдущей свечи
   cCloseOut  = 2    // Out High Low  - Открываем ордера при их отсутствии, если свеча закрыласьза екстремум предыдущей свечи
   };
enum ENUM_ST         // Вариант сокращения ордеров
   {
   FullAwerage  = 0, // FullAwerage   - Сокращает весь ордер на весь ордер в плюс MinimalProfit
   StartClose   = 1, // Start Close   - Оставляет StartLots от плюсового ордера, закрывает минусовой
   StartStart   = 2, // Start Start   - Сокращает StartLots от плюсового ордера, закрывает минусовой
   NoClose      = 3  // No Close      - Закрывает только убыточный ордер
   };
//************************************************************************************************/
input bool         MM                  = false;        // Мани Менеджмент
input double       Risk                = 0.5;          // Риск на сделку % в процентах от свободной маржи.
input double       StartLots           = 0.03;         // Start lot
input double       CoeffLots           = 2.0;          // Увеличение лота
input double       MaximalLots         = 2.56;         // Maximal Lots 
//---
input double       Equity_Rollback     = 12.7;         // Текущая прибыль (в $) всех ордеров, с которой тралим EQUITY
input ENUM_OO      OpenOrder           = NoBars;       // Type Open orders
input ENUM_ST      CloseOrder          = FullAwerage;  // Type Close orders
input int          CountAverage        = 2;            // Минимальное количество ордеров для сокращения
input int          StopLoss            = 0;            // Stop Loss (in pips)
input int          TakeProfit          = 390;          // Take Profit (in pips)
input int          PointOrderStep      = 270;          // Point order step (in pips)
input int          MinimalProfit       = 70;           // Minimal profit for close grid (in pips)
//---
input int          MagicNumber         = 1961;         // Magic Number (in number)
input int          Slippage            = 30;           // Slippage (in pips)
//-------------------------------------------------------------------------------------------------
double Equiti=0;
double Balans=0;
double ProfitBuy = 0, ProfitSell = 0, ProfitFull = 0, NewEQ = 0; 
bool   TrailEQ   = false;    // Флаг начала работы трала эквити
//---
double BuyPriceMax=0,BuyPriceMin=0,BuyPriceMaxLot=0,BuyPriceMinLot=0,
       SelPriceMin=0,SelPriceMax=0,SelPriceMinLot=0,SelPriceMaxLot=0;
int    BuyPriceMaxTic=0,BuyPriceMinTic=0,SelPriceMaxTic=0,SelPriceMinTic=0;
double op=0,lt=0,tp=0,sl=0;
int    tk=0,b=0,s=0;
bool   SignalB, SignalS;     // Сигналы-разрешение на открытие ордеров.
double CloseEQ;              // Эквити, при откате до которого выключаем свет.
//************************************************************************************************/
int OnInit()
{
   return(INIT_SUCCEEDED);
}
//************************************************************************************************/
void OnDeinit(const int reason){}
//************************************************************************************************/
void OnTick()
{     // --- Обнуляем переменные ---        
       BuyPriceMax=0;BuyPriceMin=0;BuyPriceMaxLot=0;BuyPriceMinLot=0;
       SelPriceMin=0;SelPriceMax=0;SelPriceMinLot=0;SelPriceMaxLot=0;
       BuyPriceMaxTic=0;BuyPriceMinTic=0;SelPriceMaxTic=0;SelPriceMinTic=0;
       op=0;lt=0;tp=0;sl=0;
       ProfitBuy=0;ProfitSell=0;ProfitFull=0;
       tk=0;b=0;s=0;
//***********************************  Цикл сбора данный о крайних ордерах  *****************************************
       for(int i=OrdersTotal()-1;i>=0;i--)
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
            if(OrderMagicNumber()==MagicNumber)
               if (OrderSymbol()==Symbol())
                  {
                  op=NormalizeDouble(OrderOpenPrice(),Digits());
                  lt=NormalizeDouble(OrderLots(),2);
                  tk=OrderTicket();
                  if(OrderType()==OP_BUY)
                    {
                     b++;
                     if(op>BuyPriceMax || BuyPriceMax==0)
                       {
                        BuyPriceMax    = op;
                        BuyPriceMaxLot = lt;
                        BuyPriceMaxTic = tk;
                       }
                     if(op<BuyPriceMin || BuyPriceMin==0)
                       {
                        BuyPriceMin    = op;
                        BuyPriceMinLot = lt;
                        BuyPriceMinTic = tk;
                       }
                    }
                  // ===
                  if(OrderType()==OP_SELL)
                    {
                    s++;
                    if(op>SelPriceMax || SelPriceMax==0)
                      {
                      SelPriceMax    = op;
                      SelPriceMaxLot = lt;
                      SelPriceMaxTic = tk;
                      }
                    if(op<SelPriceMin || SelPriceMin==0)
                      {
                      SelPriceMin    = op;
                      SelPriceMinLot = lt;
                      SelPriceMinTic = tk;
                      }
                    }
                  }
       //----------  Трейлинг Equiti --------------         
       if(Equity_Rollback >0 && TrailingEquity() == true)
          CloseAll();
       
avatar

kvashnin007

  • 8 февраля 2025, 14:38
0
Андрей АМ2, глянь пожалуйста.
На этом коде можно построить Невероятно простой, но эффективный советник.
avatar

kvashnin007

  • 8 февраля 2025, 11:56
0
Еще полдня котику под хвост.Вроде все по феншую. А…
Не работает моя идейка. А какая изящная. Жаль.

Может кто из более продвинутых сможет посмотреть в чем дело. Или свой вариант оформить.

Идея простая. Как только Эквити оторвался от депозита на установленную нами сумму, все закрывается.
Мой вариант рисует идеальну прямую, правда вниз. Функция REVERS() куда-то затерялась.

<code>
//************************************************************************************************/
bool TrailingEquity1()
{  
     double CurrentnEQ  = AccountEquity() ;             // Текущий эквити меняется с каждым тиком.
     double CurrentnPR  = AccountBalance() ;            // Текущий депозит меняется с каждым закрытием ордеров
                                                        //         или их открытием за счет спреда и комиссии.

     if(CurrentnEQ-CurrentnPR >= Equity_RollbackUp || CurrentnEQ-CurrentnPR <= - Equity_RollbackDown)
        {
        CloseAll();
        Print ("Сигнал на защиту Эквити");
        return (true);                                  // Трал дает сигнал об окончании работы 
        }   
  return (false);                                       // Иначе трал еще трудится    
}
//************************************************************************************************/
</code>

avatar

kvashnin007

  • 8 февраля 2025, 11:18
0
Так было изначально. Не пашет. Этот вариант хоть пашет. А >= можно интерпретировать как: Если эквити начал падать относительно депозита, то…

Кажется понял: CurrentnPR здесь не причем. Нужен AccountBalance().

Устал. Завтра попробую.
avatar

kvashnin007

  • 7 февраля 2025, 19:28
0
Дорожная идейка простейшая до безобразия. Но изящная.
А не могу запустить. Суть идейки Текущий эквити оторвался от текущего депозита на выбранноя нами расстояние — тушим свет. Все закрываем. Бьюсь полдня — не хочет со мной сотрудничать.

Вот бы кто-то из разумных подсказал гле я пЛОХ.

<code>
//************************************************************************************************/
bool TrailingEquity2()
{  
     if(Equity_Rollback == 0)                           // Если трал эквити не разрешeн
        return(false);                                  // выходим
        
     double CurrentnEQ  = AccountEquity() ;             // Текущий эквити меняется с каждым тиком
     double CurrentnPR  = AccountProfit() ;             // Текущий профит меняется с каждым тиком
     
     if(CurrentnEQ-CurrentnPR <= Equity_Rollback)
        {
//        CloseAll();
        Print ("Сигнал на защиту Эквити");
        return (true);                                  // Трал дает сигнал об окончании работы 
        }   
  return (false);                                       // Иначе трал еще трудится    
}
//************************************************************************************************/
</code>
avatar

kvashnin007

  • 7 февраля 2025, 14:17
0
Бадался я, бадался…
Убил последнюю ошибку, но трал эквити запустил таки.
Прошу заметить: написан с нуля и не претендует на истину.
Но тем не менее, заработал.

И тут меня достигла таки печалька.
Помнится раскатывал губу на ровненькую линию с малой просадкой.
А стало еще хуже, чем без трала. Я и так, и сяк — дермецом попахивает.
Пришлось менять входа на открытие ордера. Картинка улучшилась, но все равно не совсем, как расчитывал.

Пока установил врЕменную новую переменную выбора вариантов открытия ордеров OpenOrder.
Надо погонять и решить: какой лучше. Его и оставить. Думаю, победит No Bars
Второй вариант: обращаем внимание, как закроется свеча. Выше предыдущей — Бай. Ниже — Сел.
Оба варианта открывают первые свечи где придется. Последующие — не ближе PointOrderStep.

Прошу не забывать: настройки и результаты сильно рознятся в зависимости от таймфрейма. И, особенно, от ВАЛЮТЫ.

<code>
input double       Equity_Rollback     = 12.7;         // Текущая прибыль (в $) всех ордеров, с которой тралим EQUITY
//************************************************************************************************/
bool TrailingEquity()
{  
     if(Equity_Rollback == 0)                           // Если трал эквити не разрешeн
        return(false);                                  // выходим
        
     double CurrentnEQ  = AccountEquity() ;             // Текущий эквити меняется с каждым тиком
     
     // --------- Этап 1 - ожидание начала цикла для получения стартового эквити ---------
       
     if(b+s == 0)                                       // Если нет ордеров (начало очередного этапа)
        {
        CloseEQ = AccountEquity();                      // Запоминаем эквити на начало цикла, пока не появится хоть один ордер.
        return (false);                                 // Трал эквити еще не закончил свою работу.
        }
     
     // ------------------------- Этап 2 - работа трала эквити -----------------------------
     
      if(b+s > 0)                                       // Если появился ордер (начало очередного этапа) 
        {
        if(TrailEQ == false)                            // Если трал эквити еще не начался, то следим за эквити. 
           {  //                                         
           if(CurrentnEQ >= CloseEQ + Equity_Rollback)  // Если текущий эквити оторвался в + от стартового на дистанцию трала и более
               {
               CloseEQ = CurrentnEQ - Equity_Rollback;  // Запоминаем эквити для закрытия всего, который будем подтягивать за растущим эквити.
               TrailEQ = true;                          // Флаг начала трэйлинга подняли. Заработал трал эквити. 
               Alert ("Сработал Трэйлинг эквити");
               return (false);                          // Трал начал работу, но не выполнил еще свою функцию.
               }                                        // Просто передаем слежение за эквити дальнейшему алгоритму на последующих тиках 
           }    
        if(TrailEQ == true)                             // Если трал запущен и уже тралит эквити.
           {                                             
           if(CurrentnEQ > CloseEQ + Equity_Rollback)   // Если текущий эквити отрывается дальше  в + от эквити для закрытия CloseEQ
              CloseEQ = CurrentnEQ - Equity_Rollback;   // Каждый раз величиваем уровень эквити для закрытия CloseEQ
              //---                                        Если текущий эквити падает, эквити на закрытие остается на месте.
           if(CurrentnEQ <= CloseEQ)                    // Если текущий эквити упал до уровня срабатывания трала
              {  
              TrailEQ = false;                           // Флаг начала трэйлинга снимаем.                      
              Alert ("Сигнал на защиту Эквити");
              return (true);                             // Функция сработала.
              }
           } 
        } 
     return (false);                                     // Иначе трал еще трудится    
}
//************************************************************************************************/

</code>

Андрей АМ2, будет время — посмотри. Но в журнале за ошибки у меня молчит.

Пока ехал на работу, возникла идейка как изменить подход к расчету трала эквити. Это не «УДАВКА». Но… Стоит проверить.
В планах еще сделать трал общих БУ по покупкам и продажам раздельно. Вдруг, что-то стоящее выплывет.

Помню, что еще два варианта сокращения ордеров не дописал. Времени не хватило.

avatar

kvashnin007

  • 7 февраля 2025, 09:07