0
Сомневаюсь, что нет. Просто глупо.

Полюбопытствуйте kvashnin007.opentraders.ru/74118.html
avatar

kvashnin007

  • 25 июня 2022, 10:32
0
Ещё и разной лотности. Иначе смысла нет от слова вообще.
Я вот считаю траление разнонаправленных ордеров глупостью. Но это я считаю.
Я бы закрывал по каким-то признакам одну сторону и тралил другую.
Ну или как минимум, сокращал одну сторону за счет другой, а остатки тралил бы. Это тоже, что и трал без сокращения.
Вернее это и есть смысл одновременного траления двунаправленных ордеров.
Да и маржа порадуется.
avatar

kvashnin007

  • 25 июня 2022, 10:30
0
Картинка не моя, но очень похожа. Хоть кому-то пригодилась.
Все остальное о другом.
Даже обидно.
Лучше бы на заборе повесили.
avatar

kvashnin007

  • 25 июня 2022, 10:24
+1
Окончание совы. Все не вместилось

AllProf>=LevelStopLoss && LevelStopLoss!=0))
         {
         CloseAllType(OP_BUY);
         CloseAllType(OP_SELL);
         }
       //----------------------------------------------------------------------------------- 
      if(Ask>=BuyPriceMax + OrderStep*Point && s+b<MaxCountOrders-1)
         {
         if(BuyAllProfit + SelMinPriceProfit >= MinTP*SelPriceMinLot && SelMinPriceProfit!=0)
            {
            CloseAllType(OP_BUY);
            CloseTicket(SelPriceMinTic,OP_SELL);
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,NSL(OP_BUY),0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,NL(StartLot*2),NormalizeDouble(Bid,_Digits),Slippage,NSL(OP_SELL),0,"",MagicNumber);
            }
         else
            {
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,NSL(OP_BUY),0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,NSL(OP_SELL),0,"",MagicNumber);
            }
         }
      //---
      if(Bid<=SelPriceMin - OrderStep*Point && s+b<MaxCountOrders-1)
         {
         if(SelAllProfit + BuyMaxPriceProfit >= MinTP*BuyPriceMaxLot && BuyMaxPriceProfit!=0)
            {
            CloseAllType(OP_SELL);
            CloseTicket(BuyPriceMaxTic,OP_BUY);
            tk=OrderSend(NULL,OP_BUY, NL(StartLot*2),NormalizeDouble(Ask,_Digits),Slippage,NSL(OP_BUY),0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,NSL(OP_SELL),0,"",MagicNumber);
            }
         else
            {
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,NSL(OP_BUY),0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,NSL(OP_SELL),0,"",MagicNumber);
            }
         }
}
//+------------------------------------------------------------------+
//| Закрытие позиции по тикету ордера                                |
//+------------------------------------------------------------------+
void CloseTicket(int tic,int type)
{
     if(!OrderSelect(tic, SELECT_BY_TICKET)) 
        Print("OrderSelect() вернул ошибку - ",GetLastError());
     else
        {
        if(type==OP_BUY)
           if(!OrderClose(tic,OrderLots(),NormalizeDouble(Bid,Digits),Slippage))
              Print("Order Close Buy вернул ошибку - ",GetLastError());
        if(type==OP_SELL)
           if(!OrderClose(tic,OrderLots(),NormalizeDouble(Ask,Digits),Slippage))
              Print("Order Close Sell вернул ошибку - ",GetLastError());
        }
}
//+------------------------------------------------------------------+
//| Закрытие всех ордеров по типу                                    |
//+------------------------------------------------------------------+
void CloseAllType(int ot)
{
   bool cl;

   for(int i=OrdersTotal()-1; i>=0; i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
            {
            if(OrderType()==OP_BUY && ot==OP_BUY)
               {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),Slippage);
               }
             if(OrderType()==OP_SELL && ot==OP_SELL)
               {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),Slippage);
               }
            }
}
//+------------------------------------------------------------------+
double NL(double lot) // нормализация лота
{
	double LotStep=MarketInfo(Symbol(), MODE_LOTSTEP);
	int k=0;
	if (LotStep<=0.001) k=3; else if (LotStep<=0.01) k=2; else if (LotStep<=0.1) k=1; // шаг лота

	double MinLot=MarketInfo(Symbol(), MODE_MINLOT);
	double MaxLot=MarketInfo(Symbol(), MODE_MAXLOT);
	return ND(MathMin(MaxLot, MathMax(MinLot, lot)), k); // венули нормализованный лот
}
//+------------------------------------------------------------------+
double NSL(int dir) // Нормализация цены стоплоса
{
	if (StopLoss==0) return 0;
	
	double StopLvl=MarketInfo(Symbol(), MODE_STOPLEVEL)*Point;
	
	if (dir==OP_BUY) 
	   { 
	   double _sl=Ask-StopLoss*Point;
	   return NP(MathMin(_sl, Ask-StopLvl)); 
	   }
	if (dir==OP_SELL) 
	   { 
	   double _sl=Bid+StopLoss*Point;
	   return NP(MathMax(_sl, Bid+StopLvl)); 
	   }
	return 0;
}
//+------------------------------------------------------------------+
double ND(double d, int n=-1) 
{ 
      if (n<0) 
         return NormalizeDouble(d, Digits); 
    return NormalizeDouble(d, n); 
}
//+------------------------------------------------------------------+
double NP(double d) 
{
       double TickSize=MarketInfo(Symbol(), MODE_TICKSIZE); 
       
       if (TickSize==0) 
         TickSize=1; 
    return ND(MathRound(d/TickSize)*TickSize); 
}
//+------------------------------------------------------------------+

avatar

kvashnin007

  • 24 июня 2022, 17:57
+1
Трал просадки дает снижение просадка, а за одно и прибыли.
Короче на любителя. Кому, что предпочтительнее.
Добавил еще заодно трал прибыли. Оба трала при =0 не работают.
Оставил SL и ограничение количества ордеров.

Правда тестер из меня ещё тот. Выкинуть лишнее всегда можно.
Пока, просто отключаю. Количество ордеров =100(так тоже отключается).

//+------------------------------------------------------------------+
//|                                                Arifmetik_KAE.mq4 |
//|                                              Copyright 2022, KAE |
//|                                     https://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, KAE"
#property link      "https://www.forexsystems.biz"
#property strict

input double          Risk                = 0;         // Risk на сделку в процентах от свободной маржи. Ели "0", то StartLot
input double          StartLots           = 0.02;      // Start lot
input int             OrderStep           = 168;       // Order step (in pips)
input int             MinProfit           = 21;        // Minimal profit for close Average orders (in pips)
input int             StopLoss            = 0;         // Stop Loss  (in pips)
input double          LevelStopLoss       = 0;         // Level Trail Loss (in $) если =0, то трал отключён.
input double          LevelStopProfit     = 0;         // Level Trail Profit (in $) если =0, то трал отключён.
input int             MaxCountOrders      = 122;       // Count Orders максимальное число ордеров в рынке.
//---
input int             MagicNumber         = 1961;      // Magic Number 
input int             Slippage            = 30;        // Slippage (in pips)
//---
double op,lt,tp,pr;
int    tk,b,s;
double StoimPunkta, MinTP;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
     StoimPunkta = MarketInfo(Symbol(),MODE_TICKVALUE) / ( MarketInfo(Symbol(),MODE_TICKSIZE) / MarketInfo(Symbol(),MODE_POINT) );
     MinTP = StoimPunkta*MinProfit;
//       Print("MinProfit за один пункт при lot=1.00,  ",+MinTP);
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   double StartLot=StartLots;
   
   if(Risk>0)
      StartLot = AccountFreeMargin()/100*Risk/MarketInfo(Symbol(), MODE_MARGINREQUIRED);
   StartLot = NL(StartLot);

   if(OrdersTotal()==0)
      {
      tk=OrderSend(NULL,OP_BUY, StartLot,ND(Ask),Slippage,NSL(OP_BUY),0,"",MagicNumber);
      
      if(tk<0) 
         return;
      else
         tk=OrderSend(NULL,OP_SELL,StartLot,ND(Bid),Slippage,NSL(OP_SELL),0,"",MagicNumber);
      }
    
   double
   BuyPriceMax=0,SelPriceMin=0,BuyPriceMaxLot=0,SelPriceMinLot=0;

   int
   BuyPriceMaxTic=0,SelPriceMinTic=0;
   
   double
   BuyLotsSum=0,SelLotsSum=0,WeighBuy=0, WeighSell=0,BuyAllProfit=0,SelAllProfit=0,
   BuyMaxPriceProfit=0,SelMinPriceProfit=0;

   b=0;s=0;pr=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();
               pr=OrderProfit()+OrderCommission()+OrderSwap();
               
               if(OrderType()==OP_BUY)
                  {
                  b++;
                  BuyLotsSum   += lt;
//                  WeighBuy     += lt*op;
                  BuyAllProfit += pr;
                  
                  if(op>BuyPriceMax || BuyPriceMax==0)
                     {
                     BuyPriceMax       = op;
                     BuyPriceMaxLot    = lt;
                     BuyPriceMaxTic    = tk;
                     BuyMaxPriceProfit = pr;
                     }
                  }
               // ===
               if(OrderType()==OP_SELL)
                  {
                  s++;
                  SelLotsSum   += lt;
//                  WeighSell    += lt*op;
                  SelAllProfit += pr;
                  
                  if(op<SelPriceMin || SelPriceMin==0)
                     {
                     SelPriceMin       = op;
                     SelPriceMinLot    = lt;
                     SelPriceMinTic    = tk;
                     SelMinPriceProfit = pr;
                     }
                  }
               }
       //----------------------------------------------------------------------------------- 
       double AllProf = BuyAllProfit + SelAllProfit;
       if((AllProf>=LevelStopProfit && LevelStopProfit!=0) || (-
avatar

kvashnin007

  • 24 июня 2022, 17:51
0
Фиаско может с каждым приключиться. Все зависит от условий рынка, параметров и дэпо.
На графике при закрытии тестера дэпо становится равным эквити.
А если просадка по свободной марже накопится больше дэпо, то увидишь кочергу.
Game Over. ФИАСКО, сэр.

Да… и графики этого не показывают. А на реале можно вывести эту инфу на экран. При желании — в виде графика.
avatar

kvashnin007

  • 24 июня 2022, 16:45
+1
Да… советник забыл.

//+------------------------------------------------------------------+
//|                                                Arifmetik_KAE.mq4 |
//|                                              Copyright 2022, KAE |
//|                                     https://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, KAE"
#property link      "https://www.forexsystems.biz"
#property strict

input double          Risk                = 0;         // Risk на сделку в процентах от свободной маржи. Ели "0", то StartLot
input double          StartLots           = 0.02;      // Start lot
input int             OrderStep           = 168;       // Order step (in pips)
input int             MinProfit           = 21;        // Minimal profit for close Average orders (in pips)
input int             StopLoss            = 201;       // Stop Loss  (in pips)
input int             MaxCountOrders      = 22;        // Count Orders максимальное число ордеров в рынке.
//---
input int             MagicNumber         = 1961;      // Magic Number 
input int             Slippage            = 30;        // Slippage (in pips)
//---
double op,lt,tp,pr;
int    tk,b,s;
double StoimPunkta, MinTP;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
     StoimPunkta = MarketInfo(Symbol(),MODE_TICKVALUE) / ( MarketInfo(Symbol(),MODE_TICKSIZE) / MarketInfo(Symbol(),MODE_POINT) );
     MinTP = StoimPunkta*MinProfit;
//       Print("MinProfit за один пункт при lot=1.00,  ",+MinTP);
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   double StartLot=StartLots;
   
   if(Risk>0)
      StartLot = AccountFreeMargin()/100*Risk/MarketInfo(Symbol(), MODE_MARGINREQUIRED);
   StartLot = NL(StartLot);

   if(OrdersTotal()==0)
      {
      tk=OrderSend(NULL,OP_BUY, StartLot,ND(Ask),Slippage,NSL(OP_BUY),0,"",MagicNumber);
      
      if(tk<0) 
         return;
      else
         tk=OrderSend(NULL,OP_SELL,StartLot,ND(Bid),Slippage,NSL(OP_SELL),0,"",MagicNumber);
      }
    
   double
   BuyPriceMax=0,SelPriceMin=0,BuyPriceMaxLot=0,SelPriceMinLot=0;

   int
   BuyPriceMaxTic=0,SelPriceMinTic=0;
   
   double
   BuyLotsSum=0,SelLotsSum=0,WeighBuy=0, WeighSell=0,BuyAllProfit=0,SelAllProfit=0,
   BuyMaxPriceProfit=0,SelMinPriceProfit=0;

   b=0;s=0;pr=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();
               pr=OrderProfit()+OrderCommission()+OrderSwap();
               
               if(OrderType()==OP_BUY)
                  {
                  b++;
                  BuyLotsSum   += lt;
//                  WeighBuy     += lt*op;
                  BuyAllProfit += pr;
                  
                  if(op>BuyPriceMax || BuyPriceMax==0)
                     {
                     BuyPriceMax       = op;
                     BuyPriceMaxLot    = lt;
                     BuyPriceMaxTic    = tk;
                     BuyMaxPriceProfit = pr;
                     }
                  }
               // ===
               if(OrderType()==OP_SELL)
                  {
                  s++;
                  SelLotsSum   += lt;
//                  WeighSell    += lt*op;
                  SelAllProfit += pr;
                  
                  if(op<SelPriceMin || SelPriceMin==0)
                     {
                     SelPriceMin       = op;
                     SelPriceMinLot    = lt;
                     SelPriceMinTic    = tk;
                     SelMinPriceProfit = pr;
                     }
                  }
               }
       //-----------------------------------------------------------------------------------        
      if(Ask>=BuyPriceMax + OrderStep*Point && s+b<MaxCountOrders-1)
         {
         if(BuyAllProfit + SelMinPriceProfit >= MinTP*SelPriceMinLot && SelMinPriceProfit!=0)
            {
            CloseAllType(OP_BUY);
            CloseTicket(SelPriceMinTic,OP_SELL);
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,NSL(OP_BUY),0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,NL(StartLot*2),NormalizeDouble(Bid,_Digits),Slippage,NSL(OP_SELL),0,"",MagicNumber);
            }
         else
            {
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,NSL(OP_BUY),0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,NSL(OP_SELL),0,"",MagicNumber);
            }
         }
      //---
      if(Bid<=SelPriceMin - OrderStep*Point && s+b<MaxCountOrders-1)
         {
         if(SelAllProfit + BuyMaxPriceProfit >= MinTP*BuyPriceMaxLot && BuyMaxPriceProfit!=0)
            {
            CloseAllType(OP_SELL);
            CloseTicket(BuyPriceMaxTic,OP_BUY);
            tk=OrderSend(NULL,OP_BUY, NL(StartLot*2),NormalizeDouble(Ask,_Digits),Slippage,NSL(OP_BUY),0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,NSL(OP_SELL),0,"",MagicNumber);
            }
         else
            {
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,NSL(OP_BUY),0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,NSL(OP_SELL),0,"",MagicNumber);
            }
         }
}
//+------------------------------------------------------------------+
//| Закрытие позиции по тикету ордера                                |
//+------------------------------------------------------------------+
void CloseTicket(int tic,int type)
{
     if(!OrderSelect(tic, SELECT_BY_TICKET)) 
        Print("OrderSelect() вернул ошибку - ",GetLastError());
     else
        {
        if(type==OP_BUY)
           if(!OrderClose(tic,OrderLots(),NormalizeDouble(Bid,Digits),Slippage))
              Print("Order Close Buy вернул ошибку - ",GetLastError());
        if(type==OP_SELL)
           if(!OrderClose(tic,OrderLots(),NormalizeDouble(Ask,Digits),Slippage))
              Print("Order Close Sell вернул ошибку - ",GetLastError());
        }
}
//+------------------------------------------------------------------+
//| Закрытие всех ордеров по типу                                    |
//+------------------------------------------------------------------+
void CloseAllType(int ot)
{
   bool cl;

   for(int i=OrdersTotal()-1; i>=0; i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
            {
            if(OrderType()==OP_BUY && ot==OP_BUY)
               {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),Slippage);
               }
             if(OrderType()==OP_SELL && ot==OP_SELL)
               {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),Slippage);
               }
            }
}
//+------------------------------------------------------------------+
double NL(double lot) // нормализация лота
{
	double LotStep=MarketInfo(Symbol(), MODE_LOTSTEP);
	int k=0;
	if (LotStep<=0.001) k=3; else if (LotStep<=0.01) k=2; else if (LotStep<=0.1) k=1; // шаг лота

	double MinLot=MarketInfo(Symbol(), MODE_MINLOT);
	double MaxLot=MarketInfo(Symbol(), MODE_MAXLOT);
	return ND(MathMin(MaxLot, MathMax(MinLot, lot)), k); // венули нормализованный лот
}
//+------------------------------------------------------------------+
double NSL(int dir) // Нормализация цены стоплоса
{
	if (StopLoss==0) return 0;
	
	double StopLvl=MarketInfo(Symbol(), MODE_STOPLEVEL)*Point;
	
	if (dir==OP_BUY) 
	   { 
	   double _sl=Ask-StopLoss*Point;
	   return NP(MathMin(_sl, Ask-StopLvl)); 
	   }
	if (dir==OP_SELL) 
	   { 
	   double _sl=Bid+StopLoss*Point;
	   return NP(MathMax(_sl, Bid+StopLvl)); 
	   }
	return 0;
}
//+------------------------------------------------------------------+
double ND(double d, int n=-1) 
{ 
      if (n<0) 
         return NormalizeDouble(d, Digits); 
    return NormalizeDouble(d, n); 
}
//+------------------------------------------------------------------+
double NP(double d) 
{
       double TickSize=MarketInfo(Symbol(), MODE_TICKSIZE); 
       
       if (TickSize==0) 
         TickSize=1; 
    return ND(MathRound(d/TickSize)*TickSize); 
}
//+------------------------------------------------------------------+
avatar

kvashnin007

  • 24 июня 2022, 16:40
+1
Сергей просил добавить ограничение количества сделок в рынке, как у Андрея.

Прошу. Только это не спасёт отца русской демократии от фиаско.



//+------------------------------------------------------------------+
//|                                                Arifmetik_KAE.mq4 |
//|                                              Copyright 2022, KAE |
//|                                     https://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, KAE"
#property link      "https://www.forexsystems.biz"
#property strict

input double          Risk                = 0;         // Risk на сделку в процентах от свободной маржи. Ели "0", то StartLot
input double          StartLots           = 0.02;      // Start lot
input int             OrderStep           = 168;       // Order step (in pips)
input int             MinProfit           = 21;        // Minimal profit for close Average orders (in pips)
input int             MaxCountOrders      = 22;        // Count Orders максимальное число ордеров в рынке.
//---
input int             MagicNumber         = 1961;      // Magic Number 
input int             Slippage            = 30;        // Slippage (in pips)
//---
double op,lt,tp,pr;
int    tk,b,s;
double StoimPunkta, MinTP;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
     StoimPunkta = MarketInfo(Symbol(),MODE_TICKVALUE) / ( MarketInfo(Symbol(),MODE_TICKSIZE) / MarketInfo(Symbol(),MODE_POINT) );
     MinTP = StoimPunkta*MinProfit;
       Print("MinProfit за один пункт при lot=1.00,  ",+MinTP);
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   double StartLot=StartLots;
   
   if(Risk>0)
      StartLot = AccountFreeMargin()/100*Risk/MarketInfo(Symbol(), MODE_MARGINREQUIRED);
      StartLot = NL(StartLot);

   if(OrdersTotal()==0)
      {
      tk=OrderSend(NULL,OP_BUY, StartLot,ND(Ask),Slippage,0,0,"",MagicNumber);
      
      if(tk<0) 
         return;
      else
         tk=OrderSend(NULL,OP_SELL,StartLot,ND(Bid),Slippage,0,0,"",MagicNumber);
      }
    
   double
   BuyPriceMax=0,SelPriceMin=0,BuyPriceMaxLot=0,SelPriceMinLot=0;

   int
   BuyPriceMaxTic=0,SelPriceMinTic=0;
   
   double
   BuyLotsSum=0,SelLotsSum=0,WeighBuy=0, WeighSell=0,BuyAllProfit=0,SelAllProfit=0,
   BuyMaxPriceProfit=0,SelMinPriceProfit=0;

   b=0;s=0;pr=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();
               pr=OrderProfit()+OrderCommission()+OrderSwap();
               
               if(OrderType()==OP_BUY)
                  {
                  b++;
                  BuyLotsSum   += lt;
//                  WeighBuy     += lt*op;
                  BuyAllProfit += pr;
                  
                  if(op>BuyPriceMax || BuyPriceMax==0)
                     {
                     BuyPriceMax       = op;
                     BuyPriceMaxLot    = lt;
                     BuyPriceMaxTic    = tk;
                     BuyMaxPriceProfit = pr;
                     }
                  }
               // ===
               if(OrderType()==OP_SELL)
                  {
                  s++;
                  SelLotsSum   += lt;
//                  WeighSell    += lt*op;
                  SelAllProfit += pr;
                  
                  if(op<SelPriceMin || SelPriceMin==0)
                     {
                     SelPriceMin       = op;
                     SelPriceMinLot    = lt;
                     SelPriceMinTic    = tk;
                     SelMinPriceProfit = pr;
                     }
                  }
               }
       //-----------------------------------------------------------------------------------        
      if(Ask>=BuyPriceMax + OrderStep*Point && s+b<MaxCountOrders-1)
         {
         if(BuyAllProfit + SelMinPriceProfit >= MinTP*SelPriceMinLot && SelMinPriceProfit!=0)
            {
            CloseAllType(OP_BUY);
            CloseTicket(SelPriceMinTic,OP_SELL);
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,0,0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,NL(StartLot*2),NormalizeDouble(Bid,_Digits),Slippage,0,0,"",MagicNumber);
            }
         else
            {
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,0,0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,0,0,"",MagicNumber);
            }
         }
      //---
      if(Bid<=SelPriceMin - OrderStep*Point && s+b<MaxCountOrders-1)
         {
         if(SelAllProfit + BuyMaxPriceProfit >= MinTP*BuyPriceMaxLot && BuyMaxPriceProfit!=0)
            {
            CloseAllType(OP_SELL);
            CloseTicket(BuyPriceMaxTic,OP_BUY);
            tk=OrderSend(NULL,OP_BUY, NL(StartLot*2),NormalizeDouble(Ask,_Digits),Slippage,0,0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,0,0,"",MagicNumber);
            }
         else
            {
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,0,0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,0,0,"",MagicNumber);
            }
         }
}
//+------------------------------------------------------------------+
//| Закрытие позиции по тикету ордера                                |
//+------------------------------------------------------------------+
void CloseTicket(int tic,int type)
{
     if(!OrderSelect(tic, SELECT_BY_TICKET)) 
        Print("OrderSelect() вернул ошибку - ",GetLastError());
     else
        {
        if(type==OP_BUY)
           if(!OrderClose(tic,OrderLots(),NormalizeDouble(Bid,Digits),Slippage))
              Print("Order Close Buy вернул ошибку - ",GetLastError());
        if(type==OP_SELL)
           if(!OrderClose(tic,OrderLots(),NormalizeDouble(Ask,Digits),Slippage))
              Print("Order Close Sell вернул ошибку - ",GetLastError());
        }
}
//+------------------------------------------------------------------+
//| Закрытие всех ордеров по типу                                    |
//+------------------------------------------------------------------+
void CloseAllType(int ot)
{
   bool cl;

   for(int i=OrdersTotal()-1; i>=0; i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
            {
            if(OrderType()==OP_BUY && ot==OP_BUY)
               {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),Slippage);
               }
             if(OrderType()==OP_SELL && ot==OP_SELL)
               {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),Slippage);
               }
            }
}
//+------------------------------------------------------------------+
double NL(double lot) // нормализация лота
{
	double LotStep=MarketInfo(Symbol(), MODE_LOTSTEP);
	int k=0;
	if (LotStep<=0.001) k=3; else if (LotStep<=0.01) k=2; else if (LotStep<=0.1) k=1; // шаг лота

	double MinLot=MarketInfo(Symbol(), MODE_MINLOT);
	double MaxLot=MarketInfo(Symbol(), MODE_MAXLOT);
	return ND(MathMin(MaxLot, MathMax(MinLot, lot)), k); // венули нормализованный лот
}
//+------------------------------------------------------------------+
double ND(double d, int n=-1) 
{ 
      if (n<0) 
         return NormalizeDouble(d, Digits); 
    return NormalizeDouble(d, n); 
}
//+------------------------------------------------------------------+


Думаю, что трал убытка тоже улучшит результат.
avatar

kvashnin007

  • 24 июня 2022, 14:28
+1
Если слегка поработаь с расчетом ордеров, то характеристики улучшатся.



//+------------------------------------------------------------------+
//|                                                Arifmetik_KAE.mq4 |
//|                                              Copyright 2022, KAE |
//|                                     https://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, KAE"
#property link      "https://www.forexsystems.biz"
#property strict

input double          Risk                = 0;         // Risk на сделку в процентах от свободной маржи. Ели "0", то StartLot
input double          StartLots           = 0.02;      // Start lot
input int             OrderStep           = 168;        // Order step (in pips)
input int             MinProfit           = 21;        // Minimal profit for close Average orders (in pips)
//---
input int             MagicNumber         = 1961;      // Magic Number 
input int             Slippage            = 30;        // Slippage (in pips)
//---
double op,lt,tp,pr;
int    tk,b,s;
double StoimPunkta, MinTP;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
     StoimPunkta = MarketInfo(Symbol(),MODE_TICKVALUE) / ( MarketInfo(Symbol(),MODE_TICKSIZE) / MarketInfo(Symbol(),MODE_POINT) );
     MinTP = StoimPunkta*MinProfit;
       Print("MinProfit за один пункт при lot=1.00,  ",+MinTP);
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   double StartLot=StartLots;
   
   if(Risk>0)
      StartLot = AccountFreeMargin()/100*Risk/MarketInfo(Symbol(), MODE_MARGINREQUIRED);
      StartLot = NL(StartLot);

   if(OrdersTotal()==0)
      {
      tk=OrderSend(NULL,OP_BUY, StartLot,ND(Ask),Slippage,0,0,"",MagicNumber);
      
      if(tk<0) 
         return;
      else
         tk=OrderSend(NULL,OP_SELL,StartLot,ND(Bid),Slippage,0,0,"",MagicNumber);
      }
    
   double
   BuyPriceMax=0,SelPriceMin=0,BuyPriceMaxLot=0,SelPriceMinLot=0;

   int
   BuyPriceMaxTic=0,SelPriceMinTic=0;
   
   double
   BuyLotsSum=0,SelLotsSum=0,WeighBuy=0, WeighSell=0,BuyAllProfit=0,SelAllProfit=0,
   BuyMaxPriceProfit=0,SelMinPriceProfit=0;

   b=0;s=0;pr=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();
               pr=OrderProfit()+OrderCommission()+OrderSwap();
               
               if(OrderType()==OP_BUY)
                  {
                  b++;
                  BuyLotsSum   += lt;
//                  WeighBuy     += lt*op;
                  BuyAllProfit += pr;
                  
                  if(op>BuyPriceMax || BuyPriceMax==0)
                     {
                     BuyPriceMax       = op;
                     BuyPriceMaxLot    = lt;
                     BuyPriceMaxTic    = tk;
                     BuyMaxPriceProfit = pr;
                     }
                  }
               // ===
               if(OrderType()==OP_SELL)
                  {
                  s++;
                  SelLotsSum   += lt;
//                  WeighSell    += lt*op;
                  SelAllProfit += pr;
                  
                  if(op<SelPriceMin || SelPriceMin==0)
                     {
                     SelPriceMin       = op;
                     SelPriceMinLot    = lt;
                     SelPriceMinTic    = tk;
                     SelMinPriceProfit = pr;
                     }
                  }
               }
       //-----------------------------------------------------------------------------------        
      if(Ask>=BuyPriceMax + OrderStep*Point)
         {
         if(BuyAllProfit + SelMinPriceProfit >= MinTP*SelPriceMinLot && SelMinPriceProfit!=0)
            {
            CloseAllType(OP_BUY);
            CloseTicket(SelPriceMinTic,OP_SELL);
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,0,0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,NL(StartLot*2),NormalizeDouble(Bid,_Digits),Slippage,0,0,"",MagicNumber);
            }
         else
            {
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,0,0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,0,0,"",MagicNumber);
            }
         }
      //---
      if(Bid<=SelPriceMin - OrderStep*Point)
         {
         if(SelAllProfit + BuyMaxPriceProfit >= MinTP*BuyPriceMaxLot && BuyMaxPriceProfit!=0)
            {
            CloseAllType(OP_SELL);
            CloseTicket(BuyPriceMaxTic,OP_BUY);
            tk=OrderSend(NULL,OP_BUY, NL(StartLot*2),NormalizeDouble(Ask,_Digits),Slippage,0,0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,0,0,"",MagicNumber);
            }
         else
            {
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,0,0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,0,0,"",MagicNumber);
            }
         }
}
//+------------------------------------------------------------------+
//| Закрытие позиции по тикету ордера                                |
//+------------------------------------------------------------------+
void CloseTicket(int tic,int type)
{
     if(!OrderSelect(tic, SELECT_BY_TICKET)) 
        Print("OrderSelect() вернул ошибку - ",GetLastError());
     else
        {
        if(type==OP_BUY)
           if(!OrderClose(tic,OrderLots(),NormalizeDouble(Bid,Digits),Slippage))
              Print("Order Close Buy вернул ошибку - ",GetLastError());
        if(type==OP_SELL)
           if(!OrderClose(tic,OrderLots(),NormalizeDouble(Ask,Digits),Slippage))
              Print("Order Close Sell вернул ошибку - ",GetLastError());
        }
}
//+------------------------------------------------------------------+
//| Закрытие всех ордеров по типу                                    |
//+------------------------------------------------------------------+
void CloseAllType(int ot)
{
   bool cl;

   for(int i=OrdersTotal()-1; i>=0; i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
            {
            if(OrderType()==OP_BUY && ot==OP_BUY)
               {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),Slippage);
               }
             if(OrderType()==OP_SELL && ot==OP_SELL)
               {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),Slippage);
               }
            }
}
//+------------------------------------------------------------------+
double NL(double lot) // нормализация лота
{
	double LotStep=MarketInfo(Symbol(), MODE_LOTSTEP);
	int k=0;
	if (LotStep<=0.001) k=3; else if (LotStep<=0.01) k=2; else if (LotStep<=0.1) k=1; // шаг лота

	double MinLot=MarketInfo(Symbol(), MODE_MINLOT);
	double MaxLot=MarketInfo(Symbol(), MODE_MAXLOT);
	return ND(MathMin(MaxLot, MathMax(MinLot, lot)), k); // венули нормализованный лот
}
//+------------------------------------------------------------------+
double ND(double d, int n=-1) 
{ 
      if (n<0) 
         return NormalizeDouble(d, Digits); 
    return NormalizeDouble(d, n); 
}
//+------------------------------------------------------------------+


Но всё это уже другие советники.
Добавляя какие-то функции, можно ещё улучшать характеристики.
Но мне это уже не интересно.
Первоначальная идея не оправдалась в моём понимании.

Есть ребята и пошире в плечах.
avatar

kvashnin007

  • 24 июня 2022, 13:18
+1
Если закосить под алгоритм Андрея, то без настроек получим уже другую картинку.
Последняя дуга — результат безвременно закрытых ордеров.



//+------------------------------------------------------------------+
//|                                                Arifmetik_KAE.mq4 |
//|                                              Copyright 2022, KAE |
//|                                     https://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, KAE"
#property link      "https://www.forexsystems.biz"
#property strict

input double          Risk                = 0;         // Risk на сделку в процентах от свободной маржи. Ели "0", то StartLot
input double          StartLots           = 0.02;      // Start lot
input int             OrderStep           = 168;        // Order step (in pips)
input int             MinProfit           = 21;        // Minimal profit for close Average orders (in pips)
//---
input int             MagicNumber         = 1961;      // Magic Number 
input int             Slippage            = 30;        // Slippage (in pips)
//---
double op,lt,tp,pr;
int    tk,b,s;
double StoimPunkta, MinTP;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
     StoimPunkta = MarketInfo(Symbol(),MODE_TICKVALUE) / ( MarketInfo(Symbol(),MODE_TICKSIZE) / MarketInfo(Symbol(),MODE_POINT) );
     MinTP = StoimPunkta*MinProfit;
       Print("MinProfit за один пункт при lot=1.00,  ",+MinTP);
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   double StartLot=StartLots;
   
   if(Risk>0)
      StartLot = AccountFreeMargin()/100*Risk/MarketInfo(Symbol(), MODE_MARGINREQUIRED);
      StartLot = NL(StartLot);

   if(OrdersTotal()==0)
      {
      tk=OrderSend(NULL,OP_BUY, StartLot,ND(Ask),Slippage,0,0,"",MagicNumber);
      
      if(tk<0) 
         return;
      else
         tk=OrderSend(NULL,OP_SELL,StartLot,ND(Bid),Slippage,0,0,"",MagicNumber);
      }
    
   double
   BuyPriceMax=0,SelPriceMin=0,BuyPriceMaxLot=0,SelPriceMinLot=0;

   int
   BuyPriceMaxTic=0,SelPriceMinTic=0;
   
   double
   BuyLotsSum=0,SelLotsSum=0,WeighBuy=0, WeighSell=0,BuyAllProfit=0,SelAllProfit=0,
   BuyMaxPriceProfit=0,SelMinPriceProfit=0;

   b=0;s=0;pr=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();
               pr=OrderProfit()+OrderCommission()+OrderSwap();
               
               if(OrderType()==OP_BUY)
                  {
                  b++;
                  BuyLotsSum   += lt;
//                  WeighBuy     += lt*op;
                  BuyAllProfit += pr;
                  
                  if(op>BuyPriceMax || BuyPriceMax==0)
                     {
                     BuyPriceMax       = op;
                     BuyPriceMaxLot    = lt;
                     BuyPriceMaxTic    = tk;
                     BuyMaxPriceProfit = pr;
                     }
                  }
               // ===
               if(OrderType()==OP_SELL)
                  {
                  s++;
                  SelLotsSum   += lt;
//                  WeighSell    += lt*op;
                  SelAllProfit += pr;
                  
                  if(op<SelPriceMin || SelPriceMin==0)
                     {
                     SelPriceMin       = op;
                     SelPriceMinLot    = lt;
                     SelPriceMinTic    = tk;
                     SelMinPriceProfit = pr;
                     }
                  }
               }
       //-----------------------------------------------------------------------------------        
      if(Ask>=BuyPriceMax + OrderStep*Point)
         {
         if(BuyAllProfit + SelMinPriceProfit >= MinTP*SelPriceMinLot && SelMinPriceProfit!=0)
            {
            CloseAllType(OP_BUY);
            CloseTicket(SelPriceMinTic,OP_SELL);
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,0,0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,NL(StartLot),NormalizeDouble(Bid,_Digits),Slippage,0,0,"",MagicNumber);
            }
         else
            {
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,0,0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,0,0,"",MagicNumber);
            }
         }
      //---
      if(Bid<=SelPriceMin - OrderStep*Point)
         {
         if(SelAllProfit + BuyMaxPriceProfit >= MinTP*BuyPriceMaxLot && BuyMaxPriceProfit!=0)
            {
            CloseAllType(OP_SELL);
            CloseTicket(BuyPriceMaxTic,OP_BUY);
            tk=OrderSend(NULL,OP_BUY, NL(StartLot),NormalizeDouble(Ask,_Digits),Slippage,0,0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,0,0,"",MagicNumber);
            }
         else
            {
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,0,0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,0,0,"",MagicNumber);
            }
         }
}
//+------------------------------------------------------------------+
//| Закрытие позиции по тикету ордера                                |
//+------------------------------------------------------------------+
void CloseTicket(int tic,int type)
{
     if(!OrderSelect(tic, SELECT_BY_TICKET)) 
        Print("OrderSelect() вернул ошибку - ",GetLastError());
     else
        {
        if(type==OP_BUY)
           if(!OrderClose(tic,OrderLots(),NormalizeDouble(Bid,Digits),Slippage))
              Print("Order Close Buy вернул ошибку - ",GetLastError());
        if(type==OP_SELL)
           if(!OrderClose(tic,OrderLots(),NormalizeDouble(Ask,Digits),Slippage))
              Print("Order Close Sell вернул ошибку - ",GetLastError());
        }
}
//+------------------------------------------------------------------+
//| Закрытие всех ордеров по типу                                    |
//+------------------------------------------------------------------+
void CloseAllType(int ot)
{
   bool cl;

   for(int i=OrdersTotal()-1; i>=0; i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
            {
            if(OrderType()==OP_BUY && ot==OP_BUY)
               {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),Slippage);
               }
             if(OrderType()==OP_SELL && ot==OP_SELL)
               {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),Slippage);
               }
            }
}
//+------------------------------------------------------------------+
double NL(double lot) // нормализация лота
{
	double LotStep=MarketInfo(Symbol(), MODE_LOTSTEP);
	int k=0;
	if (LotStep<=0.001) k=3; else if (LotStep<=0.01) k=2; else if (LotStep<=0.1) k=1; // шаг лота

	double MinLot=MarketInfo(Symbol(), MODE_MINLOT);
	double MaxLot=MarketInfo(Symbol(), MODE_MAXLOT);
	return ND(MathMin(MaxLot, MathMax(MinLot, lot)), k); // венули нормализованный лот
}
//+------------------------------------------------------------------+
double ND(double d, int n=-1) 
{ 
      if (n<0) 
         return NormalizeDouble(d, Digits); 
    return NormalizeDouble(d, n); 
}
//+------------------------------------------------------------------+
avatar

kvashnin007

  • 24 июня 2022, 13:09
0
Это советник для проверки идеи в тестере. Для реала надо дорабатывать проверки на валидность всего и вся.
avatar

kvashnin007

  • 24 июня 2022, 12:44
0
Я же написал, сам не понимаю.
avatar

kvashnin007

  • 24 июня 2022, 12:12
+1
РЕШИЛ ВЫЛОЖИТЬ СВОЙ СОВ, ЧТОБ НЕ ВЫГЛЯДИТЬ ПУСТОБРЕХОМ.

<code>//+------------------------------------------------------------------+
//|                                                Arifmetik_KAE.mq4 |
//|                                              Copyright 2022, KAE |
//|                                     https://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, KAE"
#property link      "https://www.forexsystems.biz"
#property strict

input double          Risk                = 0;         // Risk на сделку в процентах от свободной маржи. Ели "0", то StartLot
input double          StartLots           = 0.01;      // Start lot
input int             OrderStep           = 63;        // Order step (in pips)
input int             MinProfit           = 37;        // Minimal profit for close Average orders (in pips)
//---
input int             MagicNumber         = 1961;      // Magic Number 
input int             Slippage            = 30;        // Slippage (in pips)
//---
double op,lt,tp,pr;
int    tk,b,s;
double StoimPunkta, MinTP;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
     StoimPunkta = MarketInfo(Symbol(),MODE_TICKVALUE) / ( MarketInfo(Symbol(),MODE_TICKSIZE) / MarketInfo(Symbol(),MODE_POINT) );
     MinTP = StoimPunkta*MinProfit;
       Print("MinProfit за один пункт при lot=1.00,  ",+MinTP);
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   double StartLot=StartLots;
   
   if(Risk>0)
      StartLot = AccountFreeMargin()/100*Risk/MarketInfo(Symbol(), MODE_MARGINREQUIRED);
      StartLot = NL(StartLot);

   if(OrdersTotal()==0)
      {
      tk=OrderSend(NULL,OP_BUY, StartLot,ND(Ask),Slippage,0,0,"",MagicNumber);
      
      if(tk<0) 
         return;
      else
         tk=OrderSend(NULL,OP_SELL,StartLot,ND(Bid),Slippage,0,0,"",MagicNumber);
      }
    
   double
   BuyPriceMax=0,SelPriceMin=0,BuyPriceMaxLot=0,SelPriceMinLot=0;

   int
   BuyPriceMaxTic=0,SelPriceMinTic=0;
   
   double
   BuyLotsSum=0,SelLotsSum=0,WeighBuy=0, WeighSell=0,BuyAllProfit=0,SelAllProfit=0,
   BuyMaxPriceProfit=0,SelMinPriceProfit=0;

   b=0;s=0;pr=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();
               pr=OrderProfit()+OrderCommission()+OrderSwap();
               
               if(OrderType()==OP_BUY)
                  {
                  b++;
                  BuyLotsSum   += lt;
//                  WeighBuy     += lt*op;
                  BuyAllProfit += pr;
                  
                  if(op>BuyPriceMax || BuyPriceMax==0)
                     {
                     BuyPriceMax       = op;
                     BuyPriceMaxLot    = lt;
                     BuyPriceMaxTic    = tk;
                     BuyMaxPriceProfit = pr;
                     }
                  }
               // ===
               if(OrderType()==OP_SELL)
                  {
                  s++;
                  SelLotsSum   += lt;
//                  WeighSell    += lt*op;
                  SelAllProfit += pr;
                  
                  if(op<SelPriceMin || SelPriceMin==0)
                     {
                     SelPriceMin       = op;
                     SelPriceMinLot    = lt;
                     SelPriceMinTic    = tk;
                     SelMinPriceProfit = pr;
                     }
                  }
               }
       //-----------------------------------------------------------------------------------        
      if(Ask>=BuyPriceMax + OrderStep*Point)
         {
         if(BuyAllProfit + SelMinPriceProfit >= MinTP*SelPriceMinLot && SelMinPriceProfit!=0)
            {
            CloseAllType(OP_BUY);
            CloseTicket(SelPriceMinTic,OP_SELL);
            tk=OrderSend(NULL,OP_BUY, NormalizeDouble(SelLotsSum-SelPriceMinLot,2),NormalizeDouble(Ask,_Digits),Slippage,0,0,"",MagicNumber);
            }
         else
            {
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,0,0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,0,0,"",MagicNumber);
            }
         }
      //---
      if(Bid<=SelPriceMin - OrderStep*Point)
         {
         if(SelAllProfit + BuyMaxPriceProfit >= MinTP*BuyPriceMaxLot && BuyMaxPriceProfit!=0)
            {
            CloseAllType(OP_SELL);
            CloseTicket(BuyPriceMaxTic,OP_BUY);
            tk=OrderSend(NULL,OP_SELL, NormalizeDouble(BuyLotsSum-BuyPriceMaxLot,2),NormalizeDouble(Bid,_Digits),Slippage,0,0,"",MagicNumber);
            }
         else
            {
            tk=OrderSend(NULL,OP_BUY, StartLot,NormalizeDouble(Ask,_Digits),Slippage,0,0,"",MagicNumber);
      
            if(tk<0) 
               return;
            else
               tk=OrderSend(NULL,OP_SELL,StartLot,NormalizeDouble(Bid,_Digits),Slippage,0,0,"",MagicNumber);
            }
         }
}
//+------------------------------------------------------------------+
//| Закрытие позиции по тикету ордера                                |
//+------------------------------------------------------------------+
void CloseTicket(int tic,int type)
{
     if(!OrderSelect(tic, SELECT_BY_TICKET)) 
        Print("OrderSelect() вернул ошибку - ",GetLastError());
     else
        {
        if(type==OP_BUY)
           if(!OrderClose(tic,OrderLots(),NormalizeDouble(Bid,Digits),Slippage))
              Print("Order Close Buy вернул ошибку - ",GetLastError());
        if(type==OP_SELL)
           if(!OrderClose(tic,OrderLots(),NormalizeDouble(Ask,Digits),Slippage))
              Print("Order Close Sell вернул ошибку - ",GetLastError());
        }
}
//+------------------------------------------------------------------+
//| Закрытие всех ордеров по типу                                    |
//+------------------------------------------------------------------+
void CloseAllType(int ot)
{
   bool cl;

   for(int i=OrdersTotal()-1; i>=0; i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
            {
            if(OrderType()==OP_BUY && ot==OP_BUY)
               {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),Slippage);
               }
             if(OrderType()==OP_SELL && ot==OP_SELL)
               {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),Slippage);
               }
            }
}
//+------------------------------------------------------------------+
double NL(double lot) // нормализация лота
{
	double LotStep=MarketInfo(Symbol(), MODE_LOTSTEP);
	int k=0;
	if (LotStep<=0.001) k=3; else if (LotStep<=0.01) k=2; else if (LotStep<=0.1) k=1; // шаг лота

	double MinLot=MarketInfo(Symbol(), MODE_MINLOT);
	double MaxLot=MarketInfo(Symbol(), MODE_MAXLOT);
	return ND(MathMin(MaxLot, MathMax(MinLot, lot)), k); // венули нормализованный лот
}
//+------------------------------------------------------------------+
double ND(double d, int n=-1) 
{ 
      if (n<0) 
         return NormalizeDouble(d, Digits); 
    return NormalizeDouble(d, n); 
}
//+------------------------------------------------------------------+
</code>
avatar

kvashnin007

  • 24 июня 2022, 12:08
0
Как я и предполагал, идея требует большой коррекции.

Я написал советника по идее sergs.
Результат отработки выглядит — не надо завидЫвать. Поэтому и не выкладываю.



Все логично.
Эквити медленно, но под линейку почти не падает. Сказываются полные замки.
Дэпо по идее также под линейку должно расти. Здесь пока вижу непонятную ломанную линию.
И то, что не изображается — свободная маржа падает с таким же успехом под линейку, но чуть круче. И в тот момент, когда она становится исчезающе мала, должна нарисоваться кочерга.
А пока, при закрытии всех ордеров по окончанию тестирования, дэпо сравнялось с эквити. А так как он падал, то мы в заднице.

Андрей в своём советнике отступил от ТЗ.
После фиксирования прибыли он не выравнивает количество лотов, а просто открывает еще замок. В результате в общем замке разное количество лотов Buy-Sell. Это и даёт возможность хоть как-то работать. Хоть и при этом появилась просадка, от которой автор стремился избавиться.

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

Есть мысль по-другому подойти к расчету ордеров, но это тоже получится другой советник. Считаю — изначально идея сырая. Возможно, мёртвая.

avatar

kvashnin007

  • 24 июня 2022, 11:44
0
Эта задача не выполнима по нескольким причинам.

1. Ордера открываются одновременно. Sell по цене Bid, Buy по цене Ask.
Из-за присутствия спрэда Ask выше Bid. Поэтому ордер Buy будет всегда выше ордера Sell. Это Ваша дань брокеру. Но это в тестере.
Стройте свечи по Ask, а не по Bid. Тогда некоторые ордера на покупку зрительно не будут выходить за свечи.
2. В реале из-за наличия кроме спреда проскальзывания и реквот, чудеса могут стать ещё чудеснее.
3. А в чем смысл? Ордера то все равно закрываются по встречным ценам.

Можно, конечно, добавить в алгоритм сдвиг на спред, но тогда не факт (вернее наоборот), что все ордера откроются.
avatar

kvashnin007

  • 23 июня 2022, 23:59
0
Спасибо.
А с безоткатом надо что-то делать. Толи шаг увеличивать, толи специальные меры предпринимать.
Есть тут одна идейка. Надо подумать.
avatar

kvashnin007

  • 22 июня 2022, 23:54
0
Это только при развороте.
Может стоит закрывать такие ордера при возврате цены к предыдущему уровню?
Хотя думаю, что не следует. Просто выравнивать лоты.
Так и математика сохранится и брокер огорчится.
avatar

kvashnin007

  • 22 июня 2022, 20:33
0
Я тоже так подумал. Правда вся трудоёмкость заключается в неправильно поставленной задаче.
avatar

kvashnin007

  • 22 июня 2022, 20:04
0
Качество не для моего бинокля.
Мне показалось, или просадка меньше 2%?
Это последний вариант советника?

В любом случае удачи.
avatar

kvashnin007

  • 22 июня 2022, 19:57