0
Не только его. Удвоение лота от последнего.
lot=Lots*MathPow(KLot,CountTrades()); Это формула исходника.

При K_Lot=0 LotStart=1 лотность изменяется от уровня к уровню так
1- старт; дальше 1*(2 в степени 1)=2; 1*(2 в степени 2)=4… Стоп.
В исходнике int CountTrades() не имеет типа, поэтому функция считает все ордера без типа.

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

<code>//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Lot()
  {
   double lot=Lots;
   if(CountTrades()>0)
      lot=NormalizeDouble(Lots*MathPow(KLot,CountTrades()),2);
   if(lot>MaxLot)
      lot=Lots;
   return(lot);
  }
  // lot=Lots*MathPow(KLot,CountTrades()); Счетчик трейдов считает все открытые ордера.
  // Пусть KLot=2.0 и Lots=1.00.
  // Тогда первый ордер откроется просто стартовым лотом.
  // Второй лот уже будет 1.00*(2.0, возведенную в степень CountTrades()=1. 1*(2 в 1-ой ст.)= 2.00 лота.
  // CountTrades()=3.00. 1*(2 в 3-ей степени). Это уже третий лот уже равен 16. А сколько будет 2 в 19-ой ст.?
  // Блин, что-то я не втыкаю. Логарифм какой-то нарисовался. Где-то я пЛОХ. Надо тестить.
  // В моем понимании, наиболее подходящая к классике формула, должна выглядеть где-то так:
  //  lot(OP_BUY)=NormalizeDouble(KLot*LastOpderLot(OP_SELL),2);
  // lot(OP_SELL)=NormalizeDouble(KLot*LastOpderLot(OP_BUY),2);
//+------------------------------------------------------------------+
</code>


Блин… Сам дурак. Почему второй ордер считаю в первой степени, а третий в третьей, а не второй?
avatar

kvashnin007

  • 8 апреля 2022, 01:58
0
И профит на панели нормализовать до двух знаков после запятой.
avatar

kvashnin007

  • 7 апреля 2022, 22:13
0
Теперь оцифрую мысль.
Купили 1 лот. Цена пошла вниз на ширину канала. Продали лотом 1*2=2. Цена не дошла до БУ и и поднялась на уровень «byu», опять покупаем лотом весь Sell*2 минус имеющийся пока Buy=1. Итого SumSelLot*2 и — Sum Buy Lot'
Т.е. 2*2-1=3. Второй ордер на Buy будет не 4 лота, как обычно, а 3.
В результате Лотов на покупку будет 4, а на продажу в два раза меньше — 2 лота.
Следующий откат к Sell лот на продажу будет 4*2-2=6 лотов. 6 лотов и предыдущие открытые 2 лота на продажу, составят 8 лотов, а на покупку останется 4 лота. 1 к 2.

На картинке расчетные лоты в теле треугольников, а справа лоты по классическому расчету.
avatar

kvashnin007

  • 7 апреля 2022, 21:19
0
Нашел, правда, не ту (картинку), что хотел, но тоже…

avatar

kvashnin007

  • 7 апреля 2022, 20:58
0
Здравствуйте SSG.
С нормализацией лота Вы мне ничего нового не сказали. Советник не торговый, а тестовый. Этого достаточно. Но все одно, спасибо. Ладно, без шуток.

Советник набирает позиции на двух образовавшихся как-то (сейчас это не важно, как) уровнях. Сверху Buy снизу Sell. Чтобы советник заработал денег, при выходе цены из канала (например, вверх) надо, чтобы лотов на покупку было бы больше, чем на продажу. Чтобы рост прибыли от них был больше роста убытка противоположных ордеров. Я взял соотношение 1 к 2. При достижении какого-то минимального профита минусовые ордера, чтоб не мешать, закрываются с убытком при положительном (оно всегда такое, но вы поняли) эквити. Зато плюсовые с двойным энтузиазмом (блин, горбатого могила выпрямит) будут повышать эквити.

Так вот, задача этой функции в расчете очередного лота таким образом, чтобы лотов на этом уровне было бы в два раза больше, чем на противоположном.
Обычно, по классике, лот просто увеличивают в *К_Lot раз от последнего. Ну так проще. А проще, в данном случае, не синоним лучшего. Возьмите карандашик и посчитайте: в моем варианте лотов на четверть меньше, а расстояния туда-сюда дл БУ сохраняется. Где-то в глубине души моего ноута должен был сохраниться рисунок с подсчетами. Найду — выложу. А пока на пальцах.
avatar

kvashnin007

  • 7 апреля 2022, 20:34
0
Даю вторую часть.

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PutOrder(int type, double price=0)
  {
   int r=0;
   color clr=clrNONE;
   double lot=0,SL=0;
//   double sl = OrderSL*Point;
//   double sl = Delta*4*KLot*Point;

   if(type==OP_SELLSTOP)
     {
     clr=clrRed;
     lot=Lot(OP_SELL);
//     SL=NormalizeDouble(price-sl,Digits);
     }
   if(type==OP_BUYSTOP)
     {
     clr=clrBlue;
     lot=Lot(OP_SELL);
//     SL=NormalizeDouble(price+sl,Digits);
     }

   r=OrderSend(Symbol(),type,Lot(type),NormalizeDouble(price,Digits),Slip,0,0,"",Magic,0,clr);
   return;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CountTrades()
  {
   int count=0;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()<2)
               count++;
           }
        }
     }
   return(count);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int LastOrderType()
  {
   int type=0;

   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==0)
              {
               type=1; //buy
               break;
              }
            if(OrderType()==1)
              {
               type=2; //sell
               break;
              }
           }
        }
     }
   return(type);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseAll(int ot=-1)
  {
   bool cl;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==0 && (ot==0 || ot==-1))
              {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),Slip,White);
              }
            if(OrderType()==1 && (ot==1 || ot==-1))
              {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),Slip,White);
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double AllProfit()
  {
   double profit=0;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()<2)
               profit+=OrderProfit()+OrderSwap()+OrderCommission();
           }
        }
     }
   return(profit);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Lot(int type)
{
   double lot=Lots;
   
   if(CountTrades()>0 && type==OP_BUY)
      lot=Lots*MathPow(KLot,CountTrades())*3/4;
   if(CountTrades()>0 && type==OP_SELL)
      lot=Lots*MathPow(KLot,CountTrades())*3/4;


      lot=NormalizeDouble(lot, 2);
      
   if(lot>MaxLot)
      lot=Lots;
   return(lot);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CountOrders(int type)
  {
   int count=0;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==type)
               count++;
           }
        }
     }
   return(count);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DelOrder()
  {
   bool del;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()>1)
               del=OrderDelete(OrderTicket());
           }
        }
     }
   return;
  }
//+------------------------------------------------------------------+
//|      Замена  функции double Lot(int type)                        |
//+------------------------------------------------------------------+
double Lot2(int type)
{
   double lot_B=0, lot_S=0, lot=0;
   
   for(int i=OrdersTotal()-1;i>=0;i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderMagicNumber()==Magic)
            if(OrderSymbol()==Symbol())
              {
               double lt = OrderLots();
          
               if(OrderType()==OP_BUY)
                 lot_B=lot_B+lt;       // Суммируем все лоты ордеров на покупку 
               if(OrderType()==OP_SELL)
                 lot_S=lot_S+lt;       // Суммируем все лоты ордеров на продажу 
              } 
       if(type==OP_BUY)                // Если мы хотим посчитать лот очередного ордера на покупку, то
         lot=lot_S*2-lot_B;            // Берем удвоенный суммаррный лот на продажу и  
                                       // вычитаем все, что до этого успели выставить по покупкам.
                                       // В итоге, на уровне покупок у нас будет ровно в 2 раза > продаж.
       if(type==OP_SELL)               // Если мы хотим посчитать лот очередного ордера на продажу, то
         lot=lot_B*2-lot_S;            // Берем удвоенный суммаррный лот на покупку и  
                                       // вычитаем все, что до этого успели выставить по продажам.
                                       // В итоге, на уровне продаж у нас будет ровно в 2 раза > покупок.
           
    return(NormalizeDouble(lot, 2));   // В 2 разза можно заменить на KLot. Тоже интересно получится, если потестить.
}
//+------------------------------------------------------------------+



avatar

kvashnin007

  • 7 апреля 2022, 13:21
0
Еще надо знать, где это у меня.
Ладно я и так понял. Но вроде видел, что-то подлиннее.
Даю первую часть.

//+------------------------------------------------------------------+
//|                                              HedgeMartinStop.mq4 |
//|                                              Copyright 2021, AM2 |
//|                                      http://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, AM2"
#property link      "http://www.forexsystems.biz"
#property version   "1.00"
#property strict

//--- Inputs
extern double         Loss           = 417;      // убыток в валюте
extern double         Profit         = 5;        // профит в валюте
extern double         Lots           = 3.1;      // лот
extern double         KLot           = 2.5;         // увеличение лота
//extern double         OrderSL        = 800;       // Ограничение убытка ордера
extern double         MaxLot         = 10;        // максимальный лот
extern int            Delta          = 55;        // дельта
extern int            Slip           = 30;        // проскальзывание
extern int            Magic          = 123;       // магик
input ENUM_TIMEFRAMES TF_ATR         = PERIOD_M5; // Тайм Фрейм для ATR
extern int            PerATR         = 21;        // Период ATR
extern double         Level          = 0.0009;    // уровень

double buy=0,sel=0;
int num=0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
 return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   double atr=iATR(Symbol(),TF_ATR,PerATR,0);

   if(AllProfit()>Profit || AllProfit()<-Loss)
     {
      CloseAll();
      DelOrder();
     }

   if(CountTrades()<1 && atr>Level)  // Если ордеров на графике нет ATR стало больше уровня
     {
      if(CountOrders(OP_BUYSTOP)<1)  // то, если нет Buy Stop ордеров
        {
         PutOrder(OP_BUYSTOP, buy);
         buy=NormalizeDouble(Bid+Delta*_Point,_Digits);
        }

      if(CountOrders(OP_SELLSTOP)<1)
        {
         PutOrder(OP_SELLSTOP,sel);
         sel=NormalizeDouble(Bid-Delta*_Point,_Digits);
        }
     }

// открытие последующих ордеров
   if(num!=CountTrades())
     {
      if(LastOrderType()==1)
        {
         DelOrder();
         if(CountOrders(5)<1)
            PutOrder(5,sel);
        }

      if(LastOrderType()==2)
        {
         DelOrder();
         if(CountOrders(4)<1)
            PutOrder(4,buy);
        }
      num=CountTrades();
     }
/*   Comment("\n Profit: ",DoubleToString(AllProfit(),2),
           "\n Last Order Type: ",LastOrderType(),
           "\n Count Trades: ",CountTrades());*/
  }
avatar

kvashnin007

  • 7 апреля 2022, 13:16
0
А вот измененный советник для желающих потестить и покритиковать.

Советник HedgeMartinStop с сайта. Изменен порядок расчета цены, снижена нагрузка, увеличена доходность. Советник можно тестировать. Но в нем есть баги. Со стопом, думаю, разберусь сам. А с функцией расчета лота попрошу кого-нибудь из спецов разобраться. Не могу найти ошибку. Функция Lot2() в конце кода.

А как код то добавить?

Хочу добавить код, а сайт выдает кпасное окошко, что комментарий больше 3000 символов.
avatar

kvashnin007

  • 7 апреля 2022, 11:52
0
Советник HedgeMartinStop с сайта. Изменен порядок расчета цены, снижена нагрузка, увеличена доходность. Советник можно тестировать. Но в нем есть баги. Со стопом, думаю, разберусь сам. А с функцией расчета лота попрошу кого-нибудь из спецов разобраться. Не могу найти ошибку. Функция Lot2() в конце кода.

avatar

kvashnin007

  • 7 апреля 2022, 11:46
0
Разобрался. Даю функцию. Для сторонних — она не работает.
avatar

kvashnin007

  • 7 апреля 2022, 10:50
0
//+------------------------------------------------------------------+
//|      Замена  функции double Lot(int type)                        |
//+------------------------------------------------------------------+
double Lot2(int type)
{
   double lot_B=0, lot_S=0, lot=0;
   
   for(int i=OrdersTotal()-1;i>=0;i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderMagicNumber()==Magic)
            if(OrderSymbol()==Symbol())
              {
               double lt = OrderLots();
          
               if(OrderType()==OP_BUY)
                 lot_B=lot_B+lt;       // Суммируем все лоты ордеров на покупку 
               if(OrderType()==OP_SELL)
                 lot_S=lot_S+lt;       // Суммируем все лоты ордеров на продажу 
              } 
       if(type==OP_BUY)                // Если мы хотим посчитать лот очередного ордера на покупку, то
         lot=lot_S*2-lot_B;            // Берем удвоенный суммаррный лот на продажу и  
                                       // вычитаем все, что до этого успели выставить по покупкам.
                                       // В итоге, на уровне покупок у нас будет ровно в 2 раза > продаж.
       if(type==OP_SELL)               // Если мы хотим посчитать лот очередного ордера на продажу, то
         lot=lot_B*2-lot_S;            // Берем удвоенный суммаррный лот на покупку и  
                                       // вычитаем все, что до этого успели выставить по продажам.
                                       // В итоге, на уровне продаж у нас будет ровно в 2 раза > покупок.
           
    return(NormalizeDouble(lot, 2));   // В 2 разза можно заменить на KLot. Тоже интересно получится, если потестить.
}
//+------------------------------------------------------------------+
avatar

kvashnin007

  • 7 апреля 2022, 10:48
0
А как Вы это сотворили?

Я пытаюсь вставить код между кодовыми отметками, а сайт мне говорит, что не более 3000 знаков. Что не так?
avatar

kvashnin007

  • 7 апреля 2022, 10:42
0
Не обратил внимания на качество. Спасибо. Увидел простынь и обрадЫвался.
Инсульт по глазам долбанул, появились проблемы.
Видел у кого-то код выдан в коротком окне со скролом. А как?.. Правда я быстро осваиваюсь.
Сейчас прокомментирую подробнее функцию и выложу.
Спасибо за участие.
avatar

kvashnin007

  • 7 апреля 2022, 10:15
0
Определение переменных за 3-и месяца

avatar

kvashnin007

  • 7 апреля 2022, 09:56
0
За год на дневном ТФ с 1.000 сделал 33.800 при просадке 12%. Тестировать на более высоком качестве я не могу.
Если кто-то сможет, поделитесь, пожалуйста, итогами.

avatar

kvashnin007

  • 7 апреля 2022, 09:54
0
Да я понимаю, что это даже не на каждом тике, но поразмыслить есть над чем. Ну тем, кто пошире в плечах. Ноут у меня — пятилетний уСкоглазик неизвестного имени. При тесте по КТ успеваю на базар сходить. При прогоне по тикам выдает в журнал много красноты. Дефолтный советник тоже не отстает. По-видимому не умею работать с тестером.
avatar

kvashnin007

  • 6 апреля 2022, 22:38
0
Уважаемый SSG. Я сюда пришел учиться. На чужих примерах, то оно лучше, чем на пальцах. Я здесь новенький, хоть и зарегился лет 10 назад. Потерялся. Так что, пожалуйста, возьмите временное шефство над несмышленышем. В смысле иногда подсказывайте куда нос совать, а куда не стоит.
Беру чужие совы, изучаю. Если интересно, ищу слабые места и пытаюсь изменить.
Так потихонечку и обучаюсь.
Вот давиче Вы заказывали (если не ошибаюсь) советник HedgeMartinStop.
Изучил. Он сделан по стратегии защиты ценового канала. Правда, для упрощения расчетов, на отложках. С точки зрения математики советник с нулевым риском. Ну если, конечно, дедушка банкир. Сильно жрет ресурсы.
Здесь подгонешь, а сдвинешь время и… ку-ку. Дэпо маловато. Трамвай не въехал.
Смотрите, сразу, с наскока снизил нагрузку на свободные средства на четверть. Советник при очередном подходе открывает ордер лотом в 2 раза больше предыдущего. Если лот увеличивать таким образом, что бы открываемый лот создавал «перевес» лотов на этом уровне ровно в 2 раза больше, чем на противоположном. В результате: защита канала остается, лотность уменьшается, доходность (ну у меня в грубом тесте так) увеличивается.
Если бы я кодировал, как разговариваю, пил бы молоко вместо кофе. Переписал функцию расчета лота. Все по фэншую. А не работает. Тикеты не правильные. А советник вообще по ним нигде и никогда. Короче, функцию забанил. Она в конце сова осталась. Может кто глянет, где я пЛОХ. Пока просто изменил старую авторскую на 25% (автор, если догонит, фаберже оторвет). Сов работает, но не по фэншую. Надо спецу подсунуть. Дальше, по логике вещей, когда цена отходит от канала на расстояние его ширины, мы попадаем в безубыток. Где-то здесь надо обрубать хв… убыточные ордера против хода. Попробовал выставлять SL чуть больше 2-х ширин канала, так сов у меня (да кто бы сомневался) оттказался вообще ордера открывать. Попробую, чуть попозже ставить стопы на открытые ордера. А пока выложу измененный код.
avatar

kvashnin007

  • 6 апреля 2022, 19:15
0
Здравствуйте. Это не то, что Вы… Это тест.
Я тоже рад новому общению. А вообще было конкретно сказано или спрошено: интересуют ли кого-то некоторые доработки советников АМ2.Если нет, то вопрос №2: Остались ли здесь спецы, которые готовы на безвозмездной основе помочь правильно написать код советника? Упор на слово ПОМОЧЬ. Хотя по себе знаю как тяжко в чужом коде разбираться бывает. Могу дать обширное ТЗ с картинками для понимания. Правда еще не знаю, начать попроще, чтоб шанс был, или сразу…
С уважением из Одессы.
Р.С. Это не демагогия. Мы тут на ней разговариваем.
avatar

kvashnin007

  • 6 апреля 2022, 13:00
0
К выше изложенному сразу идея для сова. Индикатор, например, RSI показал перепроданность. Наш советник (опыт) или еще кто-то там решил открыть BUY по фэншую и выставить тоже по нему (фэншую) SL. А наш советник выставит на место предполагаемого SL отложку OP_BUYLIMIT. Акулы пришли за стопами, а мы им на хвост сели, с самого начала тренда и потихонечку пирамидимся с тралом. Если идея кого-то вдохновляет, могу составить подробное ТЗ.
avatar

kvashnin007

  • 6 апреля 2022, 01:07
0
Проскальзывание (Slip) в тестере вообще не учитывается. Обычно на пяти- трех-знаке берется 30, на 4-х знаке 3.
avatar

kvashnin007

  • 6 апреля 2022, 00:16