0
Почитал обсуждения советника.
Сделал вывод, что советник Робот GBPUSD — туфта.

Я бы на него не тратил время.
avatar

kvashnin007

  • 28 января 2025, 14:52
0
Андрей, я длохо понимаю идею изучать советники по визуализации и сделкам Если ты вот так «легко» определяешь стратегию, то этот советник уже максимум через полгода станет не актуальным.

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

SL и ТР можно и нужно выкинуть. Так. Еще пара изменений. Ерундовых. Ну и правильные функции + проверки с работой над ошибками. Большую часть изменений я могу за пару дней поправить.
avatar

kvashnin007

  • 28 января 2025, 14:20
0
Да. Советник, судя по картинке, шикарный.
Смущает, что это таки тестер.

Логика, как раз, не читается, ибо советника не имею и не гонял.
Но даже по картинке уже возникают вопросы. Порассуждаем логически.

Советник делает всреднем 100 сделок в день. За четыре года — 9850 сделок. При тех просадках по марже, что на картинке можно предположить, что делает он это минимальными лотами и сделки закрываются довольно быстро. Просадка по марже 6.8%.
прибыльная позиция после закрытия отщипывает от убыточной

Тут я не согласен от слова совсем.
Во-первых со смыслом предложения. Что означает — закрытая позиция отщипывет?
Во-вторых, если имеется ввиду, что кусочки убытков сокращаются кусочками прибыльных ордеров, то мы бы имели убыточных сделок на порядок больше 1.36%.Скорее еще больше.
Судя по практическому равенству ордеров на продажу и покупку, стратегия локовая. Я уже говорил за Lock4.

Дальше. Линия депозата прямая. Логично предположить, что ММ не предусматривает роста лотов от роста депозита, ибо линия была бы экспоненциальной.
Дико смущают абсолютная и относительная просадки. Цифры как-то не коррелируются. Относительная 1.47% к абсолютной 0.89% как бы нормально соотносится, но при этом 7622 к 105 — явно диссонанс. Логично наоборот. В купе с тем, что картинка из тестера, навязчиво возникают мысли о фотошопе.

А то, что авторы в описании ссылаются на возврат части спреда, то это абсолютно справедливо, хотя это к пониманию алгоритма не приближает.

ВЫВОД: КОТ В МЕШКЕ. Хотя, возможно, и породистый.
avatar

kvashnin007

  • 28 января 2025, 13:48
0


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

Сам же советник хорош следующими вещами:

— огромный диапазон размера внешних переменных;
— малое количество подбираемых при оптимизации переменных;
— оптимизировать можно и по ценам закрытия.
avatar

kvashnin007

  • 28 января 2025, 07:07
0
Часть 3

//*************************************************************//
   for(int i=OrdersTotal()-1;i>=0;i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderMagicNumber()==iMagicNumber)
            if(OrderSymbol()==Symbol())
              {
               op=NormalizeDouble(OrderOpenPrice(),Digits());
               tp=NormalizeDouble(OrderTakeProfit(),Digits());
               lt=NormalizeDouble(OrderLots(),2);
               tk=OrderTicket();
               
               //---
               if(OrderType()==OP_BUY && b==1 && tp==0)
                  if(!OrderModify(tk,op,NormalizeDouble(Ask-StopLoss*Point(),Digits()),NormalizeDouble(Ask+iTakeProfit*Point(),Digits()),0,clrRed))
                     Print("OrderModify error #",GetLastError());

               if(OrderType()==OP_SELL && s==1 && tp==0)
                  if(!OrderModify(tk,op,NormalizeDouble(Bid+StopLoss*Point(),Digits()),NormalizeDouble(Bid-iTakeProfit*Point(),Digits()),0,clrRed))
                     Print("OrderModify error #",GetLastError());
               //---
               if(OrderType()==OP_BUY && b>=2)
                 {
                  if(tk==BuyPriceMaxTic || tk==BuyPriceMinTic)
                     if(Bid<AwerageBuyPrice && tp!=AwerageBuyPrice)
                        if(!OrderModify(tk,op,OrderStopLoss(),AwerageBuyPrice,0,clrRed))
                           Print("OrderModify error #",GetLastError());

                  if(tk!=BuyPriceMaxTic && tk!=BuyPriceMinTic && tp!=0)
                     if(!OrderModify(tk,op,0,0,0,clrRed))
                        Print("OrderModify error #",GetLastError());
                 }
               if(OrderType()==OP_SELL && s>=2)
                 {
                  if(tk==SelPriceMaxTic || tk==SelPriceMinTic)
                     if(Ask>AwerageSelPrice && tp!=AwerageSelPrice)
                        if(!OrderModify(tk,op,OrderStopLoss(),AwerageSelPrice,0,clrRed))
                           Print("OrderModify error #",GetLastError());

                  if(tk!=SelPriceMaxTic && tk!=SelPriceMinTic && tp!=0)
                     if(!OrderModify(tk,op,0,0,0,clrRed))
                        Print("OrderModify error #",GetLastError());
                 }
              }
  }
//************************************************************************************************/
//*                                                                                              */
//************************************************************************************************/
void OnDeinit(const int reason)
  {

  }
//************************************************************************************************/
//*                                                                                              */
//************************************************************************************************/
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 slope1 = slope(1,period);
       e1=w1*slope1+w2*e1; 
       e2=w1*e1+w2*e2; 
       e3=w1*e2+w2*e3; 
       e4=w1*e3+w2*e4; 
       e5=w1*e4+w2*e5; 
       e6=w1*e5+w2*e6;
       t3=c1*e6+c2*e5+c3*e4+c4*e3;
        slope1 = t3*5000;  
            
       double slope2 = slope(2,period);
       e1=w1*slope2+w2*e1; 
       e2=w1*e1+w2*e2; 
       e3=w1*e2+w2*e3; 
       e4=w1*e3+w2*e4; 
       e5=w1*e4+w2*e5; 
       e6=w1*e5+w2*e6;
       t3=c1*e6+c2*e5+c3*e4+c4*e3;
        slope2 = t3*5000;      
            
       double slope3 = slope(3,period);
       e1=w1*slope3+w2*e1; 
       e2=w1*e1+w2*e2; 
       e3=w1*e2+w2*e3; 
       e4=w1*e3+w2*e4; 
       e5=w1*e4+w2*e5; 
       e6=w1*e5+w2*e6;
       t3=c1*e6+c2*e5+c3*e4+c4*e3;
       
       slope3 = t3*5000; 
        
  //      BB();     
        
        if(t==reversP)
          {
          if(slope2<slope3 && slope3<slope1 && slope2<0)
            return OP_BUY;
          if(slope2>slope3 && slope3>slope1 && slope2>0)
            return OP_SELL;
          }
        if(t==revers)
          {
          if(slope2<slope3 && slope3<slope1)
            return OP_BUY;
          if(slope2>slope3 && slope3>slope1)
            return OP_SELL;
          }
        if(t==speed)
          {
          if(slope3-slope2 > slope2-slope1)
            return OP_BUY;
          if(slope3-slope2 < slope2-slope1)
            return OP_SELL;
          }
        if(t==vsa)
          {
          if( (slope3*MathAbs(Close[3]-Open[3])-slope2*MathAbs(Close[2]-Open[2])) > 
              (slope2*MathAbs(Close[2]-Open[2])-slope1*MathAbs(Close[1]-Open[1])))
            return OP_BUY;
          if( (slope3*MathAbs(Close[3]-Open[3])-slope2*MathAbs(Close[2]-Open[2])) < 
              (slope2*MathAbs(Close[2]-Open[1])-slope1*MathAbs(Close[1]-Open[1])))
            return OP_SELL;
          }
        if(t==volume)
          {
          if((slope3-slope2)/Volume[2] > (slope2-slope1)/Volume[1])
            return OP_BUY;
          if((slope3-slope2)/Volume[2] > (slope2-slope1)/Volume[1])
            return OP_SELL;
          }
  return -1;
}
//************************************************************************************************/
double slope(int iBar, int nBars)
{
      double sumy=0,
             sumx=0,
             sumx2=0,
             sumxy=0,
             sumy2=0;
      int iLimit = iBar + nBars-1,index=1,counter=nBars;
      while(counter>0)
      {      //Print(index);
         double price=Close[iBar];
                     
         sumy+=price;
         sumxy+=(NormalizeDouble(price*counter,12));
         //Print((NormalizeDouble(Open[iBar]*counter,12)),",",Open[iBar],",",counter);
         sumx+=counter;
         sumx2+=MathPow(counter,2); 
         sumy2+=MathPow(sumy,2); 
         iBar++;   
         counter--;                 
      }      
      double top=NormalizeDouble(sumxy,12)-(nBars*(sumx/nBars)*(sumy/nBars));
      double bottom=sumx2-nBars*(sumx/nBars);
      
      double rTop=nBars*sumxy-(sumx*sumy);
      double rBottom=MathSqrt((nBars*sumx2-MathPow(sumx,2))*(nBars*sumy2-MathPow(sumy,2)));
      double r2=(MathPow(rTop/rBottom,2));
      //Print(rTop/rBottom);
   return NormalizeDouble(top/bottom,12);
}
//----------------------------------------------------------------------
avatar

kvashnin007

  • 27 января 2025, 19:42
0
Часть 2

//*************************************************************//
   double   AwerageBuyPrice=0,AwerageSelPrice=0;
   
 if(iCloseOrder==Awerage)      // All close All
   {  
   if(b>=2) 
     AwerageBuyPrice=NormalizeDouble((BuyPriceMax*BuyPriceMaxLot+BuyPriceMin*BuyPriceMinLot)
                                    /(BuyPriceMaxLot+BuyPriceMinLot)+iMinimalProfit*Point(),Digits());
   if(s>=2) 
     AwerageSelPrice=NormalizeDouble((SelPriceMax*SelPriceMaxLot+SelPriceMin*SelPriceMinLot)
                                    /(SelPriceMaxLot+SelPriceMinLot)-iMinimalProfit*Point(),Digits());
   } 
   //---                                
 if(iCloseOrder==StartClose)  // Start close Start
   {    
   if(b>=2) 
     AwerageBuyPrice=NormalizeDouble((BuyPriceMax*iStartLots+BuyPriceMin*iStartLots)
                                    /(iStartLots+iStartLots)+iMinimalProfit*Point(),Digits());
   if(s>=2) 
     AwerageSelPrice=NormalizeDouble((SelPriceMax*SelPriceMaxLot+SelPriceMin*SelPriceMinLot)
                                    /(SelPriceMaxLot+SelPriceMinLot)-iMinimalProfit*Point(),Digits());
   }  
   //---                               
 if(iCloseOrder==Comby)      // Start close All
   {  
   if(b>=2) 
     AwerageBuyPrice=NormalizeDouble((BuyPriceMax*BuyPriceMaxLot+BuyPriceMin*iStartLots)
                                    /(BuyPriceMaxLot+iStartLots)+iMinimalProfit*Point(),Digits());
   if(s>=2) 
     AwerageSelPrice=NormalizeDouble((SelPriceMax*iStartLots+SelPriceMin*SelPriceMinLot)
                                    /(iStartLots+SelPriceMinLot)-iMinimalProfit*Point(),Digits());
   }                                 
//*************************************************************//
   double BuyLot = 0, SelLot = 0;
 if(!MM)
   {
   if(b==0)
      BuyLot = iStartLots;
   else
      BuyLot = NormalizeDouble(MathCeil((BuyPriceMinLot * CoeffLots)*100)/100,2);
   //---   
   if(s==0)
      SelLot = iStartLots;
   else
      SelLot = NormalizeDouble(MathCeil((SelPriceMaxLot * CoeffLots)*100)/100,2);
   }
  //----------------------------------------------------------
 if(MM)
   {
   if(BuyPriceMinLot == 0 || b==0)
      BuyLot = AccountFreeMargin()*Risk/100;
   else
      BuyLot = NormalizeDouble(MathCeil((BuyPriceMinLot * CoeffLots)*100)/100,2);
      
   if(SelPriceMaxLot == 0 || s==0)
      SelLot = AccountFreeMargin()*Risk/100;
   else
      SelLot = NormalizeDouble(MathCeil((SelPriceMaxLot * CoeffLots)*100)/100,2);
   }
//*************************************************************//

   if(BuyLot>iMaximalLots)      
     BuyLot=iMaximalLots;
   if(SelLot>iMaximalLots)      
     SelLot=iMaximalLots;
     
   if(!CheckVolumeValue(BuyLot) || !CheckVolumeValue(SelLot))
      return;   
//*************************************************************//
   int Dir=Signal();
   if(Dir==OP_BUY)// && Close[1]>High[2])
      if((b==0) || (b>0 && (BuyPriceMin-Ask)>(iPointOrderStep*Point())))
         if(OrderSend(Symbol(),OP_BUY,NormalizeDouble(BuyLot,2),NormalizeDouble(Ask,Digits()),iSlippage,0,0,"",iMagicNumber,0,clrGreen)<0)
            Print("OrderSend error #",GetLastError());

   if(Dir==OP_SELL)// && Close[1]<Low[2])
      if((s==0) || (s>0 && (Bid-SelPriceMax)>(iPointOrderStep*Point())))
         if(OrderSend(Symbol(),OP_SELL,NormalizeDouble(SelLot,2),NormalizeDouble(Bid,Digits()),iSlippage,0,0,"",iMagicNumber,0,clrGreen)<0)
            Print("OrderSend error #",GetLastError());
//*************************************************************//
avatar

kvashnin007

  • 27 января 2025, 19:41
0
Часть 1

#property strict
//************************************************************************************************/
//*                                                                                              */
//************************************************************************************************/
enum type 
  {
   reversP  =1,     // Revers Part
   revers   =2,     // Revers
   speed    =3,     // Speed
   vsa      =4,     // VSA
   volume   =5      // Volume
  };
enum ENUM_ST
  {
   Awerage      = 0,  // All close All
   StartClose   = 1,  // Start close Start
   Comby        = 2   // Start close All
  };
//************************************************************************************************/
input ENUM_ST      iCloseOrder         = Awerage;  // Type close orders
input int          StopLoss            = 20;       // Stop Loss (in pips)
input int          iTakeProfit         = 300;      // Take Profit (in pips)
input bool         MM                  = false;    // Мани Менеджмент
input double       Risk                = 0.5;      // Риск на сделку % в процентах от свободной маржи.
input double       iStartLots          = 0.01;     // Start lot
input double       CoeffLots           = 2.0;      // Увеличение лота
input double       iMaximalLots        = 2.56;     // Maximal Lots 
input int          iPointOrderStep     = 390;      // Point order step (in pips)
input int          iMinimalProfit      = 70;       // Minimal profit for close grid (in pips)
input int          iMagicNumber        = 227;      // Magic Number (in number)
input int          iSlippage           = 30;       // Slippage (in pips)
//---
input int          period              = 6;        //Period
input int          t3_period           = 1;
input double       B                   = 0.03;
input type         t                   = revers;   //Type Signals
double slopeBuffer[];

double e1,e2,e3,e4,e5,e6,
       c1,c2,c3,c4,
       n,
       w1,w2,
       b2,b3,
       t3;
double ExtUp[], ExtDn[], ExtMd[], ExtBuyArrow[], ExtSellArrow[],
       BBUp[], BBDn[], BBMd[], 
       priceUp[], priceDn[], signalUp[], signalDn[];
//************************************************************************************************/
//*                                                                                              */
//************************************************************************************************/
int OnInit()
  {
   Comment("");
//---
   b2=B*B; 
   b3=b2*B; 
   c1=-b3; 
   c2=(3*(b2+b3)); 
   c3=-3*(2*b2+B+b3); 
   c4=(1+3*B+b3+3*b2); 
   n=t3_period;
   
   if(n<1) n=1;
   n=1+0.5*(n-1); 
   w1=2/(n+1); 
   w2=1-w1;
//----
   return(INIT_SUCCEEDED);
  }
//************************************************************************************************/
//*                                                                                              */
//************************************************************************************************/
void OnTick()
  {
   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;

   int
   tk=0,b=0,s=0;

   for(int i=OrdersTotal()-1;i>=0;i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderMagicNumber()==iMagicNumber)
            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;
                    }
                 }
              }
//*************************************************************//
avatar

kvashnin007

  • 27 января 2025, 19:39
0
Кривая симпатичная. Доходность приличная.
Но по этой страничке много не поймешь. Просадка какая, например?
но результаты достойные. Прямую на граике рисовать бесполезно. Кривая экспоненциальная. И сградилась либо за счет небольшого шага, либо, скорее, за счет мультивалютности. Такое в тестер МТ4 не запихнешь.

Мой же советник будет рисовать ступенчатый рост.
avatar

kvashnin007

  • 27 января 2025, 19:37
0
Хотел сам об этом написать, но уже не стал.

Я не торгую, а только готовлю рабочее место пенсионера.
Отсюда: нет у меня торгового советника, который торгует на реале. Да и еще…
Есть только алгоритмы, которые я пока не смог воплотить в рабочий советник.

Одну идею я с помощью фрилансера я воплотил в жизнь. Идея хорошая, исполнение кода приличное. У меня товарищь даже со 100$ за год умудрился заработать около 8000. Видимо потому, что забыл за него. Анализ его заработтка показал, что за роботом надо смотреть. С ним надо работать. Повезло. Не хватило пары пунктов, чтобы робот полностью слился. Это было давно. С тех пор я в свободное время разрабатывал алгоритмы. А этому своему советнику именно поэтому бабули свои уже не доверил бы. Кстати, его благополучно слямзили, немного доработали (объективно в лучшую сторону), поменяли название и выложилив открытом коде в интернет. какая-то там Зебра.

Покумекать: обсудить вслух мысли, выработать алгоритм, опрбовать его.

К чему это я? Вот ты дал сноску на свой советник с маркета. Он торгует стабильно в плюс на реале?
Если ДА, то давай покумекаем над ним и создадим SUPER Raptor Advisor.

Но я вижу по ТЗ и описанию, что советник может и хорош, но ему деньги я бы тоже не доверил. Ибо он голый.
Идея обычная, не самая, но… рабочая. Стопы и тейки в такой стратегии не работают. Но могут выдавать какой-то даже неплохой результат некоторое время удачного стечения. Не по задумке, но может.

А то, что написан «правильными» функциями, не гарантирует стабильность работы. Уж очень он капризен к изменениям рыночных условиий.

Что с ним делать? Свои мысли я выразил.

У меня где-то в загашнике есть куча вариантов советника по такой стратегии. Доберусь до дома выложу сюда какой-нибудь. Правда на mql4. Они в принципе могут работать на реале, но подшаманить их бы не мешало. Я их в свое время забросил. Появились более интересные стратегии. Некоторое время пытался их воплотить, Но…
Понял, что без ООП не получится. А это уже не мое. Не знаю. Сейчас выберусь из дерьма буду искать грамотного фрилансера. Возможно с его помощью что-то и выродится.

Кстати, где-то у вас в базе есть советник, кажется Lock4, при добавлении всего одной строки кода работал стабильно и при приемлемой просадке. Тоже давно это было.

Можно его взять за основу. Сделать два варианта на mql4 и mql5. Я могу поработать с четверкой.
У него была особенность. Стабильно он работал в ценовой полосе. Если цена выходила из нее, советник тупо сидел и ждал, пока цена вернется. Слегка доработать и вуаля.
avatar

kvashnin007

  • 27 января 2025, 12:54
0
Открытые позиции закрываются:

3. при достижении Profit1 крайними ордерами.

Имеется ввиду однонапрвленные ордера?
Думаю, что Да. Тогда позволь свои мысли.

Если усредняющий ордер имеет удвоенный лот от усредняемого то при откате цены на полшага условно профиты этих ордеров сравниваются. Заложили какой-то профит в плюс и, при его достижении закрываем два ордера. Судя по ТЗ в статье, именно так и запланировано.

Что мы имеем?
Отсутствие ордеров, а цена пошла в нашем направлении, но без нас. Обидно, слушай. Могу предложить пару вариантов.

1. Наиболее безопасный: закрываем только убыточный ордер. Депо припало — эквити на месте.Ордер в рынке и с более выгодной позиции.
2. Думаю, самый оптимальный: закрывать убыточный ордер и часть (половину, например) прибыльного. Депо припало на половину от первого варианта, еквити на месте, а тотже стартовый ордер остался, только с более выгодной позиции.
3. Самый жадный вариант, но более нагруженный на маржу: усреднять можно, начиная с третьего ордера. Ворой (средний) ордер остается в рынке. Потом, если что, также усредняется. Единственночто, уже не со стартового лота.
И позиция чуть похуже, чем в двух первых вариантах.

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

Тут тоже несколько вариантов:

1. Трал убытка-прибыли.
2. Локи. Есть идея, как на них еще и быстро заработать. Но нужен надежный индюк.
3. ММ с постоянным контролем всех ордеров для возможного сокращения с минимальной прибылью для освобождения залога. В том числе, встречно разнонаправленные ордера.

И еще мысль. В твоем советнике, к гадалке не ходи, с каждым шагом его длина увеличивается. Стандартное умозаключение.
А логика говорит, что чем дальше уходишь от «истины», тем больше вероятность таки разворота цены.
Я бы наоборот шаг уменьшал. Тем более, если ты хочешь сокращать крайние ордера, надо сокращать расстояние, необходимое для их сокращения.
avatar

kvashnin007

  • 26 января 2025, 16:07
0
Ладно. Куда — понял. А вот что? и зачем?..

Вот родил я граальную идею. Попросил АМ2 за деньги написать советник для торговли. Он написал и я увидел в советнике пару реал функций? Или разместил на маркете свой грааль на продажу, а за это мне кто-то доступ дает к реал функциям.

Что-то не пляшет.
avatar

kvashnin007

  • 24 января 2025, 19:51
0
Вот именно. И висим в бесконечном цикле.

А GetLots((stoploss — open_price) / pnt) — это функция GetLots(int Х).
Х задавайте согласно своим условиям. Хоть Х=12, а хотите: NL((stoploss — open_price) / pnt). А на счет валидности лота позаботьтесь силами самой функции. Нормализуйте как сможете. Главное чтобы терминал схавал.

Но до этого мы еще не дошли. На пути.

Пример ни о чем, но:

<code>//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Lot()
  {
   double lot=Lots;

   if(CountTrades()>0)
     {
      lot=NormalizeDouble(Lots*MathPow(KLot,CountTrades()),2);
     }

   if(lot>MaxLot)
      lot=Lots;

   return(lot);
  }
//+------------------------------------------------------------------+
</code>


Ну или:

//+------------------------------------------------------------------+
//| Расчет лота                                                      |
//+------------------------------------------------------------------+
double Lots()
{
   double _lt=Lot;
   double _ls=MarketInfo(Symbol(),MODE_LOTSTEP);
   if(Risk>0) _lt=NormalizeDouble(AccountBalance()/100*Risk/1000/_ls,0)*_ls;
   if(LastProfit(-1)<0) _lt=NormalizeDouble(LastProfit(1)*LotK/_ls,0)*_ls;
   if(_lt<MarketInfo(Symbol(),MODE_MINLOT))
      _lt=MarketInfo(Symbol(),MODE_MINLOT);
   if(_lt>MarketInfo(Symbol(),MODE_MAXLOT))
      _lt=MarketInfo(Symbol(),MODE_MAXLOT);
   return(_lt);
}
//+------------------------------------------------------------------+


функций определени лота валом, и как правило, все индивидуальные. Думаю наша будет универсальная.
avatar

kvashnin007

  • 24 января 2025, 19:31
0
Это первый вариант, только без ограничения цикла.
avatar

kvashnin007

  • 24 января 2025, 15:52
0
проведите советник в маркет и будете очень близко к своей цели, к реал функциям


Не понял. ПЕРЕВЕДИ. Что, куда и зачем.
avatar

kvashnin007

  • 24 января 2025, 15:49
0
Лот поучился не правильный или еще по какой-то причине не открывается ордер и усе… Висим.
avatar

kvashnin007

  • 24 января 2025, 15:47
0
Слегка подредактировал под себя любимого.

SL, TP выставляются после открытия ордера.
Кроме того SL,TP и Lot определяются (высчитываются с проверкой на валидность во внешних функциях).

<code>#property strict
//-----------
extern int      SL             = 50;       // уровень выставления SL, если 0, то SL не выставляется
extern int      TP             = 50;       // уровень выставления TP, если 0, то TP не выставляется
extern double   Lots           = 0.1;      // объем ордера
extern int      Attempts       = 10;       // кол-во попыток открытия
extern int      Slippage       = 3;        // кол-во попыток открытия
extern int      Magic          = 1961;     // уникальный номер ордера

string txt;
int    slippage, StopLevel;
string symbol;
double pnt, sl, tp;
//+----------------------------------------------------------------------------+
int init()
{
      symbol = Symbol();
      pnt    = Point;
      StopLevel = int (MarketInfo(symbol,MODE_STOPLEVEL));
      sl     = SL*Point;
      tp     = TP*Point;
   return(0);   
}
//+----------------------------------------------------------------------------+
int start()
{
    OpenOrder (OP_BUY, Ask);  
    OpenOrder (OP_SELL, Bid);  
    
  return(0);
}
//+------------------------------------------------------------------+
//|                    Открытие ордера                               |
//+------------------------------------------------------------------+
bool OpenOrder (int direction, double open_price)
{
   double Lot = 0;
   int    ticket = 0, ticket1 = 0, n = 0, i = 0;
   double stoploss  = GetStopLoss(direction, open_price);
   double takeprofit = GetTakeProfit(direction, open_price);
   color  Color= clrWhite;
   
   if (direction == OP_BUY) 
      {
		Lot = GetLots((open_price - stoploss) / pnt);
		Print("Lot22 = ",Lot);   //***************************************************************************************************************************
      Color = clrBlue;
      }
   if (direction == OP_SELL) 
      {
		Lot = GetLots((stoploss - open_price) / pnt);
		Print("Lot22 = ",Lot);   //***************************************************************************************************************************
      Color = clrRed;
      }
   //---   
   for (i = 1; i <= MathMax(1, Attempts); i++)
      {
      RefreshRates();
      ticket = OrderSend(symbol,direction,Lot,open_price,Slippage,0,0,
         IntegerToString(Magic) + " Спред:" + DoubleToStr((Ask - Bid) / pnt, 1), Magic,0,Color);
         
		if(ticket<0)
		   Print(__FUNCTION__"(): Ошибка № ",GetLastError()," при открытии ",direction," - ордера");
		  
      if (ticket > 0)                                                 // Если ордер открыт
         {
         for (n = 1; n <= MathMax(1, Attempts); n++) 
            {
            Sleep(3000);
            RefreshRates();
        // ----------------------------устанавливаем SL и ТР--------------------------------------
        
            ticket1=OrderModify(ticket,OrderOpenPrice(),stoploss,takeprofit,0,Green);
            if (ticket1 > 0) 
               return(true);
            if (ticket1 <= 0 && n >= Attempts)                        // Если исчерпаны все попытки 
               return(false);                                         
            }
         return(true);
         }
      if (ticket <= 0 && i < Attempts)                                // Если не исчерпаны все попытки
         {
         Sleep(3000);                                                 // ждем 3 секунды
         continue;                                                    // и пробуем ещё раз
         }
      if (ticket<=0 && i >= Attempts)                                 // Если исчерпаны все попытки 
         return(false);
      }
   return(true);                                                      // До этого момента не дойдёт, но...
}
//+------------------------------------------------------------------+
double GetTakeProfit(int Dir, double price)
{
      double TakeProfit=0;
         
   return(TakeProfit);
}
//+------------------------------------------------------------------+
double GetStopLoss(int Dir, double price)
{
      double StopLoss=0;
         
   return(StopLoss);
}
//+------------------------------------------------------------------+
double GetLots(double price)
{
      double Lot=0;
         
   return(Lot);
}
//+------------------------------------------------------------------+
</code>


Пока так. Дальше начнем разбираться с лотами и ограничениями. Чуть позже — работой над ошибками.
avatar

kvashnin007

  • 24 января 2025, 12:46
0
Я о том же. Но есть хвастуны. Хвала им.

В свободном доступе есть много интересного кода. Я на нем учился. Сначала доработки- переработки. Потом немного своего. Потом… Я здесь. Несколько индикаторов под себя и для. Современем — большинство в корзину. Несколько советников. Но тоже не ахти. Зато проверил кое-какие мыслишки. Мысли рациональные и логичные, но… Ошибки убивают.

Я здесь не открыл школу обучения программированию. Пытаюсь найти собутыльников для совместного обучения. Кто-то поделится чем-то полезным. Я поделиться. Каждому польза. Плюс гимнастика для серого. Особенно в мои года полезна. Забываю имена любовниц. Теперь они у меня одни котики и зайки.

Да и вообще. Лучше общения только общение по интересам.
avatar

kvashnin007

  • 24 января 2025, 08:43
0
Нет. Цикл в цикле — чушь. Да и еще повизгивает.

Не вникал в вышеуказанный код. Но он с ошибками. Может это повесть о бесплатном сыре…
Хрен его знает. Я обычно пишу функции сам. Не факт, что правильно, но сам. Тот вариант от Хлыстова не стоит внимания. Там много логических помарок. Нашел другой образец. он чист, как Тауфон. Поработаем над ним.
Принципиально алгоритм «настойчивости» ничем не отличается от Хлыстова. Ну кроме того, что расчеты лота, SL и ТР отданы внешним функциям.Что есть гуд. Здесь также SL и ТР выставляются одномоментно с ордером. Что не есть гуд. Я бы поправил.

<code>
//+------------------------------------------------------------------+
//|                    Открытие ордера                               |
//+------------------------------------------------------------------+
bool OpenOrder (int direction, double open_price)
{
   double Lot = 0;
   int    ticket = 0, ticket1 = 0, n = 0, i = 0;
   double stoploss = StopLoss(direction, open_price);
   double takeprofit = TakeProfit(direction, open_price);
   
   if (direction == OP_BUY) 
      {
		Lot = Lots((open_price - stoploss) / _pnt);
		Print("Lot22 = ",Lot);   //***************************************************************************************************************************
      Color = Blue;
      }
   if (direction == OP_SELL) 
      {
		Lot = Lots((stoploss - open_price) / _pnt);
		Print("Lot22 = ",Lot);   //***************************************************************************************************************************
      Color = Red;
      }
   //---   
   for (i = 1; i <= MathMax(1, RetryAttempts); i++)
      {
      RefreshRates();
      ticket = OrderSend(_Symbol,direction,Lot,open_price,slippage,0,0,
         IntegerToString(magic) + " Спред:" + DoubleToStr((Ask - Bid) / _pnt, 1), magic,0,Color);
				 if(ticket<0){
					Print(__FUNCTION__"(): Ошибка № ",GetLastError()," при открытии ",direction," - ордера");
				 }
      if (ticket > 0)                                 // Если ордер открыт
         {
         for (n = 1; n <= MathMax(1, RetryAttempts); n++) 
            {
            Sleep(3000);
            RefreshRates();
                                                      // устанавливаем SL и ТР
            ticket1=OrderModify(ticket,OrderOpenPrice(),stoploss,takeprofit,0,Green);
            if (ticket1 > 0) 
               return(true);
            if (ticket1 <= 0 && n == RetryAttempts)   // Если исчерпаны все попытки 
               return(false);                                         
            }
         return(true);
         }
      if (ticket <= 0 && i < RetryAttempts)           // Если не исчерпаны все попытки
         {
         Sleep(3000);                                 // ждем 3 секунды
         continue;                                    // и пробуем ещё раз
         }
      if (ticket<=0 && i == RetryAttempts)            // Если исчерпаны все попытки 
         return(false);
      }
   return(true);                                      // До этого момента не дойдёт, но...
}
//+------------------------------------------------------------------+
</code>


Да, и функция bool в отличие от void позволяет «бесплатно» проводить дополнительную проверку на исполнение. True или false.

Жена пристает. Завтра исправлю под себя.

avatar

kvashnin007

  • 24 января 2025, 00:14