0
Советник Shaman_v1.3 опять же склейка из двух частей. Смотрите выше. Там тоже есть проблемы с постоянной модификацией ТР ордеров. Позже решу — отпишусь. Сейчас пока не до этого.
Удачи.
avatar

kvashnin007

  • 3 мая 2024, 15:31
0
Не понял сразу проблему. Постоянная модификация Таким способом не решается. Есть два ордера -есть модификация ТР в БУ+. А если ордеров становится 3, то модифицируем ТР в общий БУ+ первый и третий, а второй мешается под ногами. Я ему должен поставить «родной» ТР. Эту проблему надо решать по-другому. Надо подумать. Решу — отпишусь.
avatar

kvashnin007

  • 3 мая 2024, 07:45
0
Не понял сразу проблему. Постоянная модификация Таким способом не решается. Есть два ордера -есть модификация ТР в БУ+. А если ордеров становится 3, то модифицируем ТР в общий БУ+ Первый и третий, а второй мешается под ногами. Я ему должен поставить «родной» ТР. Эту проблему надо решать по-другому. Надо подумать. Решу — отпишусь.
avatar

kvashnin007

  • 3 мая 2024, 07:02
0
Да. И еще. SL=0. Не настраивайте его сразу. Настраивайте без него. После подбора всего поставьте в настройки только SL в пределах 30-1000. Выберите SL с лучшим соотношением прибыль-просадка.

Удачи. Не забывайте делиться результатами. Это и лично Вам необходимо.
avatar

kvashnin007

  • 2 мая 2024, 22:20
0
Вторая часть v_1.3


//****************  Усреднение ордеров **********************************//
   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();

               if(OrderType()==OP_BUY)
                  { 
                  if(b>=1 && tp==0) // Если есть ордера на покупку и их ТР=0, то выставляем ему ТР.
                                    // Откуда ТР=0? Это новый открытый, а также с обнуленным ТР. Читай дальше, когда обнуляем.
                     if(!OrderModify(tk,op,OrderStopLoss(),NormalizeDouble(Ask+TakeProfit*Point(),Digits()),0,clrNONE))
                        Print("OrderModify error #",GetLastError());
   
                  if(b>=CountAverge)// Если ордеров на покупку не менее, чем мы определили для сокращения
                     {              // то пытаемся сократить крайние из них.
                     if(tk==BuyPriceMaxTic || tk==BuyPriceMinTic)
                        if(Bid<AwerageBuyPrice && tp!=AwerageBuyPrice)
                           if(!OrderModify(tk,op,OrderStopLoss(),AwerageBuyPrice,0,clrNONE))// Dыставляем им ТР в общий БУ+.
                              Print("OrderModify error #",GetLastError());
   
                     if(tk!=BuyPriceMaxTic && tk!=BuyPriceMinTic && tp!=0)// Если появился очередной усредняющий ордер, то 
                        if(!OrderModify(tk,op,0,0,0,clrNONE))             // предыдущему (уже не крайнему) обнуляем ТР.
                           Print("OrderModify error #",GetLastError());   // затем в строках 220-223 вернем ему "родной" ТР. 
                     }
                     
                  if(Revers && Bid<=op-slv)
                     if(OrderSend(Symbol(),OP_SELL,lt,NormalizeDouble(Bid,Digits()),Slippage,0,0," ",MagicNumber,0,clrRed)<0)
                        Print("OrderSend error #",GetLastError());
                  }
               //---                   
               if(OrderType()==OP_SELL)
                  { 
                  if(s>=1 && tp==0)
                  if(!OrderModify(tk,op,OrderStopLoss(),NormalizeDouble(Bid-TakeProfit*Point(),Digits()),0,clrNONE))
                     Print("OrderModify error #",GetLastError());
                        
                  if(s>=CountAverge)
                     {
                     if(tk==SelPriceMaxTic || tk==SelPriceMinTic)
                        if(Ask>AwerageSelPrice && tp!=AwerageSelPrice)
                           if(!OrderModify(tk,op,OrderStopLoss(),AwerageSelPrice,0,clrNONE))
                              Print("OrderModify error #",GetLastError());
   
                     if(tk!=SelPriceMaxTic && tk!=SelPriceMinTic && tp!=0)
                        if(!OrderModify(tk,op,0,0,0,clrNONE))
                           Print("OrderModify error #",GetLastError());

                     if(Revers>0 && Ask>=op+slv)
                        if(OrderSend(Symbol(),OP_BUY,lt,NormalizeDouble(Ask,Digits()),Slippage,0,0," ",MagicNumber,0,clrBlue)<0)
                           Print("OrderSend error #",GetLastError());
                     }
                  }
               }
}
//************************************************************************************************/
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);
}
//************************************************************************************************/
/*СИГНАЛ*/
//------------------------------------------------------------------	
int Signal()                   // Создаем функцию получения сигнала на указанном ТФ и баре
{
        double current_openprice = iOpen (Symbol(),TF , iB);
        double Mashka =iMA(NULL,0,Per_MA,0,0,4,iB) ;
        double Atrium=0;
        
          Atrium  = 0.2 * iATR(NULL,TF_ATR,Per_MA,iB);
         
          if(Bid>=current_openprice)                                               
            {
            SellBuff = (58000000.0 * (Bid  - Mashka) * Atrium);
            BuyBuff  = (58000000.0 * (Low[iB]   - Mashka) * Atrium);
            }
          if(Bid<current_openprice)
            {
            SellBuff = (58000000.0 * (High[iB]  - Mashka) * Atrium);
            BuyBuff  = (58000000.0 * (Bid   - Mashka) * Atrium);
            }
          if (SellBuff >  LevelSell) 
            return OP_SELL;
          
          if (BuyBuff < -LevelBuy) 
            return OP_BUY;
	return -1;                   // Иначе нет сигнала. Возвращаем в int Signai () -1 (никаких сигналов)
}
//************************************************************************************************
double GetProfit()
{  
   double Profit=0;
     
   for(int i=OrdersTotal()-1;i>=0;i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderMagicNumber()==MagicNumber)
            if(OrderSymbol()==Symbol())
              Profit += OrderProfit() + OrderCommission() + OrderSwap();
   return (Profit);
}
//************************************************************************************************
bool CloseAll()
{ 
   for(int i=OrdersTotal()-1;i>=0;i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderMagicNumber()==MagicNumber)
            if(OrderSymbol()==Symbol())
              {
              if(OrderType()==OP_BUY)
                if(!OrderClose(OrderTicket(),OrderLots(),Bid,Slippage))
                  {
                  Sleep(500);
                  i=i+1;//??????????????
                  }
              if(OrderType()==OP_SELL)
                if(!OrderClose(OrderTicket(),OrderLots(),Ask,Slippage))
                  {
                  Sleep(500);
                  i=i+1;//??????????????
                  }
              }
   return true;
}
//************************************************************************************************
bool ClosePlus()
{ 
   for(int i=OrdersTotal()-1;i>=0;i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderMagicNumber()==MagicNumber)
            if(OrderSymbol()==Symbol() && OrderProfit()>0)
              {
              if(OrderType()==OP_BUY)
                if(!OrderClose(OrderTicket(),OrderLots(),Bid,Slippage))
                  {
                  Sleep(500);
                  i=i+1;//??????????????
                  }
              if(OrderType()==OP_SELL)
                if(!OrderClose(OrderTicket(),OrderLots(),Ask,Slippage))
                  {
                  Sleep(500);
                  i=i+1;//??????????????
                  }
              }
   return true;
}
//************************************************************************************************
bool CloseMinus()
{ 
   for(int i=OrdersTotal()-1;i>=0;i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderMagicNumber()==MagicNumber)
            if(OrderSymbol()==Symbol() && OrderProfit()<=0)
              {
              if(OrderType()==OP_BUY)
                if(!OrderClose(OrderTicket(),OrderLots(),Bid,Slippage))
                  {
                  Sleep(500);
                  i=i+1;//??????????????
                  }
              if(OrderType()==OP_SELL)
                if(!OrderClose(OrderTicket(),OrderLots(),Ask,Slippage))
                  {
                  Sleep(500);
                  i=i+1;//??????????????
                  }
              }
   return true;
}
//************************************************************************************************
avatar

kvashnin007

  • 2 мая 2024, 22:12
0
Это не логично.
Добавил одну переменную говорящую, сколько ордеров усреднения позиции нужно для начала сокращения крайних ордеров с минимальным ТР. 2-7. Я предпочитаю 3. Добавил комментариев. Почитайте и сами поймете, что ваши дополнения нарушают логику.

Советник Shaman_v1.3 опять же склейка из двух частей.


//+------------------------------------------------------------------+
//|                                                  Shaman_v1.3.mq4 |
//+------------------------------------------------------------------+
#property strict
//---
enum ENUM_Metod
  {
   Shaman       = 0,  
   ShamanSmart  = 1,  
   Normal       = 2     
  };
input ENUM_Metod      Metod               = Shaman;    // Metod - тип работы советника, метод открытия ордеров.
input bool            Agressor            = true;      // Agressor - функция влияет только на расчет ордеров.
input bool            Revers              = false;     // Вместо SL создает полный замок.
input int             CloseLim            = 5;         // Close Limit - функция оставляет к-во ордеров в каждом направлении.
input int             CountAverge         = 3;         // Количество усредняющих ордеров для сокращения с MinimalProfit.
//---      
input double          StartLots           = 0.05;      // Start lot
input double          CoeffLots           = 1.7;      
input double          MaximalLots         = 2.56;      // Maximal Lot 
input int             StopLoss            = 352;       // Stop Loss (in pips)
input int             TakeProfit          = 737;       // Take Profit (in pips)
input int             PointOrderStep      = 33;        // Point order step (in pips)
input int             MinimalProfit       = 35;        // Minimal profit for close Average orders (in pips)
//---
input ENUM_TIMEFRAMES TF                  = PERIOD_H1; // Тайм Фрейм для расчета входа
input ENUM_TIMEFRAMES TF_ATR              = PERIOD_H1; // Тайм Фрейм для ATR
input int             Per_MA              = 14;
input int             LevelSell           = 22;
input int             LevelBuy            = 62;
//---
input int             MagicNumber         = 1961;      // Magic Number 
input int             Slippage            = 30;        // Slippage 
//---
double SellBuff;
double BuyBuff;
double ShortSig;
double LongSig;
double op,lt,tp,slv;
int    tk,b,s;
int    iB=1;
double BuyPriceMax=0,BuyPriceMin=0,BuyPriceMaxLot=0,BuyPriceMinLot=0,
       SelPriceMin=0,SelPriceMax=0,SelPriceMinLot=0,SelPriceMaxLot=0;
double FullBU,BuyBU,SelBU;
//************************************************************************************************/
int OnInit()
{
     slv = StopLoss*Point;
     Comment("");
  return(INIT_SUCCEEDED);
}
//**********************************************************************************************/
void OnTick()
{//------------------- Сначала изучаем текущую обстановку по ордерам ---------------------------/
   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
   BuyLotsSum=0,SelLotsSum=0,WeighBuy=0, WeighSell=0;

   op=0;lt=0;tp=0;
   FullBU=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++;
                  BuyLotsSum += lt;
                  WeighBuy   += lt*op;
                  
                  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++;
                  SelLotsSum += lt;
                  WeighSell  += lt*op;
                  
                  if(op>SelPriceMax || SelPriceMax==0)
                     {
                     SelPriceMax    = op;
                     SelPriceMaxLot = lt;
                     SelPriceMaxTic = tk;
                     }
                  if(op<SelPriceMin || SelPriceMin==0)
                     {
                     SelPriceMin    = op;
                     SelPriceMinLot = lt;
                     SelPriceMinTic = tk;
                     }
                  }
               }
            //---
            if(b>CloseLim && CloseLim!=0)    // Если ордеров на покупку больше заданного (усредняющие ордера)
              if(OrderClose (BuyPriceMaxTic, BuyPriceMaxLot, Bid , Slippage, clrBlue)) // Закрываем дальний.
                return;                                                                // опять пересчитываем текучку.
                
            if(s>CloseLim && CloseLim!=0)
              if(OrderClose (SelPriceMinTic, SelPriceMinLot, Ask , Slippage, clrRed)) 
                return;
            //---
            if(Metod!=Normal)  
               if ((BuyLotsSum - SelLotsSum) != 0) 
                  FullBU = (WeighBuy - WeighSell)/(BuyLotsSum - SelLotsSum);// Определяем цену общего БУ для всех ордеров
//***************** Определение БУ+MinTP для крайник ордеров одного направления ***************************//
   double   AwerageBuyPrice=0,AwerageSelPrice=0;
   if(b>=CountAverge) AwerageBuyPrice=NormalizeDouble
         ((BuyPriceMax*BuyPriceMaxLot+BuyPriceMin*BuyPriceMinLot)/(BuyPriceMaxLot+BuyPriceMinLot)+MinimalProfit*Point(),Digits());
   if(s>=CountAverge) AwerageSelPrice=NormalizeDouble
         ((SelPriceMax*SelPriceMaxLot+SelPriceMin*SelPriceMinLot)/(SelPriceMaxLot+SelPriceMinLot)-MinimalProfit*Point(),Digits());
//*************************************************************//
   double BuyLot=0,SelLot=0;
   
   if(Agressor && (Metod==Normal || Metod==Shaman))
      {   
      if(BuyPriceMinLot==0) 
         BuyLot=StartLots; 
      else 
         BuyLot=MathCeil(BuyPriceMinLot * 100 * CoeffLots)/100;
         
      if(SelPriceMaxLot==0) 
         SelLot=StartLots; 
      else 
         SelLot=MathCeil(SelPriceMaxLot * 100 * CoeffLots)/100;
      }
   if(!Agressor && (Metod==Normal || Metod==Shaman))
      {   
      if(BuyPriceMinLot==0) 
         SelLot=StartLots; 
      else 
         SelLot=MathCeil(BuyPriceMinLot * 100 * CoeffLots)/100;
         
      if(SelPriceMaxLot==0) 
         BuyLot=StartLots; 
      else 
         BuyLot=MathCeil(SelPriceMaxLot * 100 * CoeffLots)/100;
      }
   if(Metod==ShamanSmart)
      {   
      if(SelPriceMaxLot==0) 
         BuyLot=StartLots; 
      else 
         BuyLot=SelLotsSum*2;
         
      if(BuyPriceMinLot==0) 
         SelLot=StartLots; 
      else 
         SelLot=BuyLotsSum*2;
      }
//*************************************************************//

   if(BuyLot>MaximalLots)      BuyLot=MaximalLots;
   if(SelLot>MaximalLots)      SelLot=MaximalLots;
   if(!CheckVolumeValue(BuyLot) || !CheckVolumeValue(SelLot))
      return;   
//*************************************************************//
   if(Metod==Normal)
      {
      if(Signal()==OP_BUY)
         if((b==0) || (b>0 && Ask<=BuyPriceMin-PointOrderStep*Point()))
            if(OrderSend(Symbol(),OP_BUY,NormalizeDouble(BuyLot,2),NormalizeDouble(Ask,Digits()),Slippage,0,0," ",MagicNumber,0,clrBlue)<0)
               Print("OrderSend error #",GetLastError());
      if(Signal()==OP_SELL)
         if((s==0) || (s>0 && Bid>=SelPriceMax+PointOrderStep*Point()))
            if(OrderSend(Symbol(),OP_SELL,NormalizeDouble(SelLot,2),NormalizeDouble(Bid,Digits()),Slippage,0,0," ",MagicNumber,0,clrRed)<0)
               Print("OrderSend error #",GetLastError());
      }
   //---   
   if(Metod==Shaman || Metod==ShamanSmart)
     {
      if(Signal()==OP_BUY && Ask<FullBU)
         if((b==0) || (b>0 && Ask<=BuyPriceMin-PointOrderStep*Point()))
            if(OrderSend(Symbol(),OP_BUY,NormalizeDouble(BuyLot,2),NormalizeDouble(Ask,Digits()),Slippage,0,0," ",MagicNumber,0,clrBlue)<0)
               Print("OrderSend error #",GetLastError());
   
      if(Signal()==OP_SELL && Bid>FullBU)
         if((s==0) || (s>0 && Bid>=SelPriceMax+PointOrderStep*Point()))
            if(OrderSend(Symbol(),OP_SELL,NormalizeDouble(SelLot,2),NormalizeDouble(Bid,Digits()),Slippage,0,0," ",MagicNumber,0,clrRed)<0)
               Print("OrderSend error #",GetLastError());
     }

avatar

kvashnin007

  • 2 мая 2024, 22:08
0
Логично. Другое дело скидывать советники в файлообменники. Не плодить здесь простыни ради. Как тут скидывать файлы?
avatar

kvashnin007

  • 2 мая 2024, 20:01
0
Вообще-то советник имеет умеренную просадку. Я даже ввел режим Агрессор.
Плюс усредняющие ордера по возможности компенсируются. Закрываются два ордера с минимальным общим ТР.А свечи, которые длинные (импульсные), как правило сразу же откатывают. Можно на одной свече заработать. Я бы не стал ограничиваться одним ордером на свече. Но вы пробуйте. Может в этом что-то есть. В одном месте потеряли, в другом чаще находим.
avatar

kvashnin007

  • 2 мая 2024, 19:56
0
Возможно. Я тут на работе погонял на ценах открытия. С трудом нашел подходящие переменные. Так что не панацея. Давние наблюдения. Но если попробуете, то совет. По ценам открытия на 1000$ подбирайте переменные. А далее по тикам или КТ выделяйте 10000$.
Я там писал: либо перегрузите советник а Вам LevelStopLoss и LevelStopProfit лучше удалить. Либо просто оставить =0 и не подбирать. Иначе советник выдает критическую ошибку.
Удачи.
avatar

kvashnin007

  • 2 мая 2024, 19:40
0
Занят другим.
avatar

kvashnin007

  • 2 мая 2024, 19:31
0
Смотря на каком ТФ. Подбираете на ценах открытия более менее красивый график. Тестируете на тиках.
Если все ОК. даете небольшой диапазон подбора вокруг получившихся значений и подгоняете на тиках.
Не лучший вариант, но реально быстрый.

Удачи.
avatar

kvashnin007

  • 2 мая 2024, 13:04
0
Убрал отключения при профите ±.
Компилируется без ошибок, а в ходе тестирования в журнал выдает критическую ошибку.
Пока нашел, дуб порезал.

Хто плохо разбирается, просто перезапишите сову, склеив две части.

Будет время допишу трал по эквити. Т.е. задаем падение эквити от текущего, ниже которого Все закрывается.
avatar

kvashnin007

  • 2 мая 2024, 13:01
0
Я не тестировал и не смотрел код.
Посмотреть количество подряд отрицательных сделок. Если оно меньше 5, можно удваивать лот после каждой минусовой сделки.
Появится время на вникнуть глубже, вставлю свои четыре копейки одной монетой.
avatar

kvashnin007

  • 28 апреля 2024, 20:58
+2
Что-то я сегодня разошелся. Там выше были бодания по поводу продолжения импульсной свечи и встречного направления. Это натолкнуло на мысль за трал стоп-ордером.
В воздухе витает не продуманная мысль использовать два варианта одновременно. По логике, преимуществ это не даст, но и покоя тоже. Надо пробовать. Что-то в этом есть. Только надо обдумать правильный подход.
А вообще основное наблюдение правильное. Толк из этого получится.
avatar

kvashnin007

  • 28 апреля 2024, 20:50
+1
В погоне за импульсом, думаю, полезен будет немеряно виртуальный трал Stop ордером с сокращением дистанции с каждым тиком.

Тоже — мысль вслух.
avatar

kvashnin007

  • 28 апреля 2024, 20:21
0
Спасибо за подгон.
avatar

kvashnin007

  • 28 апреля 2024, 08:16
0
Так на картинке продажа. А по ТЗ должна быть покупка. Продолжение волатильной свечи.
Если вы задаете увеличение длины, например, 30%, то почему не попробовать открывать сделку на продолжение свечи именно с момента, когда она превысит эти 30%?
А по пробою Max-Min встречной свечи можно пробовать встречный ордер.
Хотя бы, пока очередная свеча не закроется против ордера.

Так, мысли вслух.
avatar

kvashnin007

  • 26 апреля 2024, 17:44
0
Длинная свеча может вывести RSI из зоны перепроданности. Предыдущая свеча должна быть в зоне перепроданности.
avatar

kvashnin007

  • 26 апреля 2024, 17:28
+1
Ладно. Я хоть попытался. Всем удачи.
avatar

kvashnin007

  • 16 апреля 2024, 15:40