Функции для реальной торговли и для реальных счетов. Часть №2

Этот топик для всех желающих. Желающих чего? Развиваться совместно. Учиться элементарным вещам, позволяющим самим, без особого знания програмировани, научиться добавлять свои дополнительные хотелки в уже готовые советники для проверки своих идеек.

Главная же цель этого топика научиться заменять те функции, что пишут нам уважаемые програмисты в советниках «для проверки» наших идей,
на функции, позволяющие торговать не только в тестере, но и в реале. Маленький такой счетик на 1000 центов — и изучайте, тренеруйтесь себе
на практике. На реальной практике. 1-4 месяца и вы уже знаете: доверите вы этому советнику свои большие бабки, или… — хрен ему. Идем дальше.
  • +6
  • Просмотров: 2379
  • 2 февраля 2025, 10:35
  • kvashnin007
Понравилcя материал? Не забудьте поставить плюс и поделиться в социальной сети!

18 января 2025
10 февраля 2025

Брокер для ваших роботов, 15 лет на рынке

Комментарии (64)

комментарий был удален 2025-02-02 12:39:28 kvashnin007

комментарий был удален 2025-02-02 12:39:34 kvashnin007

комментарий был удален 2025-02-02 12:39:44 kvashnin007

+
0
avatar

  15  OSS5 Сообщений: 171

  • 2 февраля 2025, 11:48
+
0
Ого. И как это?

Спасибо
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 2 февраля 2025, 12:38
+
0
Итого мы имеем советник, над которым поработаем с целью получить рабочий советник для торговли на рынке.
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 2 февраля 2025, 12:41
+
0
Начнем! Что в начале советника?
Внешние и глобальные переменные.

Вообще, я переменные стараюсь называть понятными именами. Потом легче разбираться с кодом. Вам когда нибудь попадались декомпилированные советники? Кто видел — поймет. Это АКСИОМА.

Глобальные переменные (как и локальные) тоже обзывать надо понятно.

И так, что мы имеем:

//************************************************************************************************/
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.7;
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[];
//************************************************************************************************/


Весело? Не очень.
Начну с enum type. Пытался понаделать разные примочки к основному коду. Положительного эффекта с гулькин… нос. А вот оптимизация зависает от слова совсем.

Предлагаю убрать. Еще немного мусор почистить.

В итоге получится следующая картинка. На прямую заменить строки не получится. Там еще в основном коде поменять кое чего надо. Так что ссылку на версию 1.1 дам. Если получится.

//************************************************************************************************/
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.7;
//---
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[];
//************************************************************************************************/
//*                                                                                              */
//************************************************************************************************/
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 2 февраля 2025, 13:21
+
0
Еще одно правило, которого стараюсь придерживаться:
переменных для оптимизации должно быть как можно неньше. в связи с тем, что мои примочки опирались на индикатор линейной регрессии, необходимость в нем отпала.
Картинка еще красивее:

<code>//************************************************************************************************/
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)
//---
//************************************************************************************************/
//*                                                                                              */
</code>


Что изменилось в работе советника?
Заметного ничего. Так, мелочи.

Слегка подоходнее и с слегка меньшей просадкой.

Зато код советкика сократился процентов на 40. Время оптимизациисократилось более чем в три раза.

Было:



Стало:



Редактирован: 2 февраля 2025, 14:05
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 2 февраля 2025, 14:03
+
0
если текстом:

1. проверки входных переменных которые в настройках в ините
2. проверка включения кнопки автоторговли
3. число попыток открытия закрытия ордера
4. проверки лота ордеров с маркета и отложек
5. проверка спреда за несколько тиков
6. проверка стопов
7. проверка на стоплевел
8. проверка на фризлевел
9. паузы между попытками открыть ордер
10. обработка ошибок
11. отключения советника или удаление с графика при критических ошибках

это только то что по памяти вспомнил
avatar

  35  AM2 Сообщений: 16537 - Андрей

  • 2 февраля 2025, 14:05
+
0
Андрей, спасибо. У меня есть еще чего добавить. В инете максимум обращений к брокеру сводим к глобальным переменным. Далее работаем у себя на поле. И еще… Пока не смотрите на цены открытия. я у себя имею и по тикам. Просто сейчас тики отримают много времени.

<code>string txt,symbol ;
int    slippage, StopLevel, digits;
double pnt, sl$, tp$;
//+----------------------------------------------------------------------------+
int init()
{
      symbol    = Symbol();
      pnt       = SymbolInfoDouble(symbol,SYMBOL_POINT);
      StopLevel = (int)SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL);
      digits    = (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
      sl$       = SL*Point;
      tp$       = TP*Point;
      
      OpenOrder (OP_BUY, Ask);  
      OpenOrder (OP_SELL, Bid);  
    
   return(0);   
}
//+----------------------------------------------------------------------------+
int start()
{
    =Ask;  
    =Bid;  
    
  return(0);
}
//+------------------------------------------------------------------+
</code>

Редактирован: 2 февраля 2025, 20:34
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 2 февраля 2025, 20:31
+
0
enum ENUM_ST StartClose и Comby. Два варианта, которые практически никогда не выбираются при оптимизаии. Т.е. практической пользы от них нет. Вывод: удаляем. Придумал два более действенных варианта сокращения ордеров. Сулят повышение прибыльности. Пробуем.
Попозже. Пока действует только Average (Профитный закрывает убыточный в + MinimalProfit).

Кроме того сокращаются уже два ордера одного направления. Представим картину: открыли сел, а цена пошла вверх. Открыли еще селл удвоенным лотом, а цена раз… и пошла вниз. В какой-то момент закроются два ордера с минимальной прибылью, а цена все валит и валит вниз. Без нас. Обидно.
По-этому ввел внешнюю переменную int CountAwerage, задающую при каком количестве ордеров начинается их сокращение. При CountAwerage=3 сокращаться начнут первый и третий ордера. Второй будет в работе. Скорее всего CountAwerage=2 будет оптимальным. Но мы всегда сможем удалить эту переменную.

Итак на сегодня шапка имеет версию 1.1 и выглялит так:

//+------------------------------------------------------------------+
//|                                                     KAE Grid.mq4 |
//|                                                   Copyright 2025 |
//|                                             kvashnin007@gmil.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025"
#property version   "1.1"
#property strict
//************************************************************************************************/
//*                                                                                              */
//************************************************************************************************/
enum ENUM_ST           // Вариант сокращения ордеров
  {
   Average       = 0,  // Профитный закрывает убыточный в + MinimalProfit
   StartClose    = 1,  // Оставляем Start от профитного закрываем убыточный
   NoProfitClose = 2   // При профите  + MinimalProfit закрываем убыточный
  };
//************************************************************************************************/
input bool         MM                  = false;    // Мани Менеджмент
input double       Risk                = 0.5;      // Риск на сделку % в процентах от свободной маржи.
input double       StartLots           = 0.03;     // Start lot
input double       CoeffLots           = 2.0;      // Увеличение лота
input double       MaximalLots         = 2.56;     // Maximal Lots 
//---
input ENUM_ST      CloseOrder          = Average;  // Type close orders
input int          CountAverage        = 2;        // Минимальное количество ордеров для сокращения
input int          StopLoss            = 0;        // Stop Loss (in pips)
input int          TakeProfit          = 390;      // Take Profit (in pips)
input int          PointOrderStep      = 270;      // Point order step (in pips)
input int          MinimalProfit       = 70;       // Minimal profit for close grid (in pips)
//---
input int          MagicNumber         = 1961;     // Magic Number (in number)
input int          Slippage            = 30;       // Slippage (in pips)
//---
//************************************************************************************************/
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 2 февраля 2025, 19:37
+
0
Я оптимизировал на EURCHF — отличные результаты. На EURUSD просадка значительно выше. Результат принципиально зависит от валюты. От М1 до Н1. тесты проходят с необъяснимыми результатами.
Я оптимизирую по ценам открытия. Потом прогоняю по тикам. Возможно, по-этому результаты не совсем корелируются.

Пробуйте.
Удачи.

Попробую загрузить новый советник вдепозитарий. www.opentraders.ru/downloads/3949/
Хрен там.

Уважаемый OSS5 поделитесь, как это у вас получается?

avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 2 февраля 2025, 20:02
комментарий был удален 2025-02-03 10:00:09 kvashnin007

комментарий был удален 2025-02-03 10:00:18 kvashnin007

+
0
Просто красивая картинка.



В следующий раз добавлю пару вариантов сокращения ордеров.
Введу трал эквити.

А пока… Спать.
Доброй ночи.
Редактирован: 3 февраля 2025, 09:07
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 2 февраля 2025, 20:08
+
0
avatar

  15  OSS5 Сообщений: 171

  • 3 февраля 2025, 04:03
+
0
Благодаря OSS5 мы снова имеем файл в удобном и доступном виде.

www.opentraders.ru/downloads/3950/

Спасибо.

OSS5, поделитесь таки возможностью. Что у меня не так?
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 3 февраля 2025, 07:34
+
0
Никак не могу сюда картинки вставить. Толи форум глючит, может сама винда 11, браузеры не должны (пробовал гугл хром и яндекс и фаерфокс). Может вспышки на солнце какие-нибудь :) .

Андрей, почта в советнике написана правильно или нет ( kvashnin007@gmil.com ), а может все же (kvashnin007@gmail.com). На почту архив с картинками отправлю.
avatar

  15  OSS5 Сообщений: 171

  • 3 февраля 2025, 07:50
+
0
Одна клавиша на компе западает. Именно «ф-a». Вроде просматриваю писанину, а пропустил.
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 3 февраля 2025, 09:04
+
0
Отправил архив со скринами на почту kvashnin007@gmail.com
Надеюсь поможет.
Редактирован: 3 февраля 2025, 08:35
avatar

  15  OSS5 Сообщений: 171

  • 3 февраля 2025, 08:34
+
0
Спасибо.

Все делаю по такому же феншую, а сайт постоянно требует поменять латиницу, видимо, на не ворованную.
Редактирован: 3 февраля 2025, 09:06
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 3 февраля 2025, 09:05
+
0
Пришла мысль во сне: вот был наш ордер крайним, выставили мы ему ТР в безубыток+, а… не случилось. Не сократился он, а появился новый крайний. Думаю, надо восстановить уже не крайнему ТР в правильное положение. Добавил пару строк.

<code>                    if(OrderType()==OP_BUY && b==1 && tp==0)
                      {
                      //--- Выставляем стопы и тейки одиночным ордерам на покупку ---------
                      if(b==1 && tp==0)
                        {
                        sl=0; tp=0;
                        
                        if(StopLoss>0)
                           sl=NormalizeDouble(Ask-StopLoss*Point(),Digits());
                        if(TakeProfit>0)
                           tp=NormalizeDouble(Ask+TakeProfit*Point(),Digits());
                    
                        if(!OrderModify(tk,op,sl,tp,0,clrBlue))
                           Print("OrderModify error №1 #",GetLastError());
                        }
                      //--- Выставляем ТР крайних ордеров на покупку в безубыток + ---------
                      if(b>=CountAverage && (tk==BuyPriceMaxTic || tk==BuyPriceMinTic))
                        if(Bid<AverageBuyPrice && tp!=AverageBuyPrice)
                           if(!OrderModify(tk,op,OrderStopLoss(),AverageBuyPrice,0,clrBlue))
                              Print("OrderModify error №3 #",GetLastError());
                           
                      //--------- Восстановление ТР не крайним ордерам OP_BUY --------------
                      if(tk != BuyPriceMinTic && tk != BuyPriceMaxTic)     
                       if(tp!= NormalizeDouble (op + TakeProfit * Point(), Digits()))
                         if(!OrderModify(tk, op, OrderStopLoss(), NormalizeDouble (op + TakeProfit * Point(), Digits()), 0, clrBlue))
                           Print("OrderModify error №5 #", GetLastError());
                      }
                     //---------------------------------------------------------------------

</code>

Аналогично и ордерам на продажу.

Нашел логические ошибки. Подредактировал.
Редактирован: 3 февраля 2025, 13:22
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 3 февраля 2025, 10:07
комментарий был удален 2025-02-05 06:14:03 kvashnin007

комментарий был удален 2025-02-05 06:14:18 kvashnin007

+
0
Александр, доброго. Киньте пожалуйста сову в депозитарий. У меня таже проблема. Не нравится модераторам мой латинский.
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 4 февраля 2025, 18:29
+
0
Доброе утро.
www.opentraders.ru/downloads/3952/
avatar

  15  OSS5 Сообщений: 171

  • 5 февраля 2025, 04:15
+
0
Утро только настало. То был еще вечер.Спасибо.

Хорошнго дня.
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 5 февраля 2025, 06:13
+
0
Пока такой вариант. Сам по себе уже рабочий. Но… Будем улучшаться. Есть еще куда.



Тестирование «приблизительно». Время 3 месяца.EURCHF.М5. Абс. просадка 24%.

Как я оптимизирую:
SL=0. М5, М15, М30, Н1.
Можно и SL до кучи в оптимизацию включить.
Даже результаты приличные получить.
Но график получается «рваный», что говорит о нестабильности.

Оптимизацию провожу по ценам закрытия.
Выбираю вариант переменных с прибылью ±10% в месяц при минимальной просадке.
Проверяю на тиках. Как правило прибыль увеличивается, а просадка уменьшается.
Редактирован: 3 февраля 2025, 23:12
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 3 февраля 2025, 23:09
+
0
Надоела эта латиница. Особенно ошибки 134.
Решил просто поразмышлять.

1. Такие советники я отношу к «сливным». За ним нужен будет глаз да глаз.
По-этому надо будет предусмотреть вариант(ы) защиты. Мысли есть, но потом.

2. Фиксированный шаг вещь попроще, но, думаю, динамический должен быть круче.
— Можно привязаться к какому нибудь индюку (какая гадость).
— Можно тралить за ценой Лимитку, по какому-нибудь прогрессивному алгоритму.
— Проще сделать «псевдотрал по свечам». Потом попробую.

3. Тренд то вверх, то вниз. А переменные не меняются. Типа универсальные.
Лучше универсального только индивидуально-частное. Во загнул.
Думаю советник надо будет «раздвоить».
Например, МА60 (период подберем) вверх — одна история, вниз — вторая.

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

5. Еще один момент, который почти все и почти всегда упускают.
Кто часто тестирует всякого рода советников, часто замечает красивую линию роста
депозита, которая заканчиватся «кочергой». Вы делаете вывод: настройки гУвно.
На самом деле настройки здесь ни причем. Если посмотрите результаты теста, то увидите,
как в конце периода тестирования закрываются все ордера. Причем, часто в крупный минус.
Если бы период тестирования продлился дольше, возможно, эти ордера дали бы приличный
профит. Ладно. Это все лирика. К чему тобишь я?
Если вам необходимо остановить работу советника (например, чтобы снять деньги
со счета брокера) надо создать кнопку "ХОЧУ ДЕНЕГ", активация которой плавно
закроетвсе ордера по алгоритму советника, не будет открывать новые начальные ордера,
пока кнопку не отожмем назад.

Засыпаю. Мысли тю-тю.
Доброй ночи.
.
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 4 февраля 2025, 01:46
+
0
Вчерашня мысль:
Советник должен сам подхватывать сопровождение ордеров, после перезапуска.

Поразмышляю дальше.
Сегодня про тралы для этого советника.

Тралить SL каждого ордера нельзя. Нарушается логика советника.

Тралить БУ под вопросом. Общий БУ? А в какую сторону?

Тралить БУ отдельно для ордеров на покупку, отдельно на продажу?
В принципе можно. При условии, что цена оторвалась от БУ в плюс на дистанцию трала.
Можно попробовать. Хотя линия роста депозита будет делать скачки вверх.
Ступенчатый рост депозита. При этом логику советника мы не нарушим.
Ибо к тому моменту, когда ордера выйдут в плюс, «крайних» ордеров уже не будет.
ТР обнуляем, чтобы уже не мешал тралу, а тралим общий БУ направления.
Получится виртуальный трал. И stoplevel под ногами не будет путаться.
Есть в этом зерно. Надо пробовать.

Идем дальше. Трал общего профита.
Ститаю это направление наиболее перспективным.

Объясню:
Если дистанцию трала взять большой, то он практически не вмешивается в логику советника.
Но при этом даст прирост в части дохода. Правда линия депо станет несколько рваной.

Если мы возьмем мизерную дистанцию трала, то мы практически вытягиваем в струну
линию роста депозита. Эквити под ней Не увидишь.
Что у нас получится?
Для того, чтобы ордер дал минимальную прибыль достаточно легкого изменения цены.
Такое движение часто при большой волатильности. Поэтому мы часто сможем закрывать ордера
с минимальным профитом. Эквити даже просесть не успел, а у нас уже новые ордера с малым шагом.

Так по зернышку, но часто с минимальной просадкой… Линейка не нужна.
А за возврат спреда вообще… молчать не буду.

Тут де-то, когдато видел трал-удавку. Исполнение отстой, а идея хорошая. Тоже в обсуждение.
Редактирован: 4 февраля 2025, 21:20
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 4 февраля 2025, 21:13
+
0
Попробуйте поработать со стоповыми ордерами. Прогонял пару тестов версии 1.2 и не выдерживает сильный тренд. Можете взять для примера начиная с сентября 2024 года. И наверное нужен трал. Мое видение почему тренд в данном случае не играет на руку: против тренда открываются ордера с мартином, по тренду одиночки с фиксированным ТР.
Редактирован: 4 февраля 2025, 21:24
avatar

  16  Aleh7999 Сообщений: 108

  • 4 февраля 2025, 21:18
+
0
Привет.

Это абсолютно другая стратегия. Тоже имеет право на существование.
В этой же стратегии предпологаются лимитные ордера. Но есть ложка дерьма. И не одна.

Стоповые ордера видит брокер. Это наименьшее зло.
Я в размышлениях про тралы чуть выше высказал одну интересную мысль.
За минимальный профит. При работе с рыночными ордерами, я их могу открывать хоть через пипс, а отложки не ближе levelstop. А это 15-50 раз сужает оперативные просторы.
Я понимаю за проскальзывание, реквоты и прочую дрянь. Но они не зависят от шага ордеров. И тоже, хоть и в меньших размерах, гадят торговле.

А о том, что настройки при тренде вверх или вниз должны отличаться, я писал выше (МА60).

На счет «прогонял». Я тоже прогонял. И получал без особой оптимизации на тиках очень приличные результаты. Я там делился своим методом оптимизации. Посмотрите. Попробуйте.

На счет трала. Писал. И не один вариант. Работаю над этим. Здесь специфика.
Готовый не подойдет. Пробую писать с ноля. Уперся в ошибки. Борюсь.

Далее. Это все же трендовая торговля с усреднением откатов. Открываем ордер по тренду с ТР. Если цена не достига ТР и развернулась усредняемся. Увеличение заработков в этой стратегии за счет откатов. Повышается лотность и улучшается цена позиции. Главное не добаловать при этом до кочерги. Но это уже другой вопрос.

Редактирован: 4 февраля 2025, 23:33
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 4 февраля 2025, 22:44
+
0
Полежал на левом боку, подумал.
Фактически Aleh7999 предлагает элементы локирования. Это не навредит, но значительно усложнит не столько алгоритм, сколь увеличивает количество настроек.

Выводы не утишительные:

Надо делать две отдельные ветви BUY и SELL. Каждую со своим комплектом настроек.
Чтобы они кешировали друг друга, они должны работать параллельно сами по себе
со своими настройками.

Кроме того каждая из ветвей должна иметь свои настройки для тренда вниз и вверх
раздельно. Это даст очень положительный эффект, но гораздо усложнит оптимизацию.

Фактически оптимизировать надо будет четыре советника. Печалька.

Зато… Если… То…

avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 4 февраля 2025, 23:30
+
0
Думаю, надо покончить с одинарным вариантом, а потом уже заняться половой жизнью.
Редактирован: 5 февраля 2025, 20:38
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

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

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

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

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

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

</code>

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

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

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


Редактирован: 7 февраля 2025, 09:14
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 7 февраля 2025, 09:07
комментарий был удален 2025-02-07 22:01:15 kvashnin007

комментарий был удален 2025-02-07 22:01:23 kvashnin007

комментарий был удален 2025-02-07 22:01:31 kvashnin007

+
0
avatar

  15  OSS5 Сообщений: 171

  • 7 февраля 2025, 10:23
комментарий был удален 2025-02-07 22:01:48 kvashnin007

комментарий был удален 2025-02-07 22:02:01 kvashnin007

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

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

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

Редактирован: 7 февраля 2025, 19:19
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 7 февраля 2025, 14:17
+
0
if(CurrentnEQ-CurrentnPR <= Equity_Rollback)

а надо так:
if(CurrentnEQ-CurrentnPR >= Equity_Rollback)

Закрытие когда эквити больше баланса, а у вас наоборот
avatar

  20  alex30774 Сообщений: 782

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

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

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

  8  kvashnin007 Автор Сообщений: 734 - Андрей

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

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

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

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

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


Редактирован: 8 февраля 2025, 11:42
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 8 февраля 2025, 11:18
+
0
Вы чего написали, вы хотя чуть -чуть вдумываетесь в смысл написанного.Методом тыка хороший советник не получиться.
<code>if(CurrentnEQ-CurrentnPR >= Equity_RollbackUp || CurrentnEQ-CurrentnPR <= - Equity_RollbackDown)</code>


1.Параметры Equity_RollbackUp и Equity_RollbackDown ни где больше не упоминаются.Из-за этого и не закрывает.
Вот этот знак
||
означает «или»

Перевожу что вы написали, так сказать ваше условие на закрытие:
Эквити минус баланс больше либо равно Equity_RollbackUp или Эквити минус баланс меньше либо равно Equity_RollbackDown

Простым языком:
Если прибыль больше суммы1 или менше суммы2, то всё закрываем
2.И скрее всего по итогу это условие будет противоричивым.
скорее всего вам нужно вот так:
<code>bool TrailingEquity1()
{  
     double CurrentnEQ  = AccountEquity() ;             // Текущий эквити меняется с каждым тиком.
     double CurrentnPR  = AccountBalance() ;            // Текущий депозит меняется с каждым закрытием ордеров
                                                        //         или их открытием за счет спреда и комиссии.

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


3.Ваша строчка верна только в том случае, если бы вы за место вот этой фразы:
Идея простая. Как только Эквити оторвался от депозита на установленную нами сумму, все закрывается.


написали бы следующую: «Идея простая. Как только Эквити оторвался от депозита на установленную нами сумму, все закрывается.Также советник всё закрывакт как только Эквити просел от депозита на установленную нами сумму».

В таком случае достаточно венести в настройки параметры Equity_RollbackUp, Equity_RollbackDown.

А для вашей фразы верным евляется приведённый выше код.

Но я не телепати не знаю, что вы хотели.
Редактирован: 8 февраля 2025, 22:17
avatar

  20  alex30774 Сообщений: 782

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

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 8 февраля 2025, 11:56
+
0
Уважаемый, Алекс.

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

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

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

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

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

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

Да и еще.

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

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 10 февраля 2025, 08:51
+
0
с какого бадуна вы думаете, что
«скорее всего по итогу это условие будет противоричивым»?

if(CurrentnEQ-CurrentnPR >= Equity_RollbackUp || CurrentnEQ-CurrentnPR <= — Equity_RollbackDown)

потому что вы сами указали, что советник должен работать по следующей идее
Как только Эквити оторвался от депозита на установленную нами сумму, все закрывается.

И для этой идее оно противоречиво, так как только эквити перескочит минимальный порог(Equity_RollbackUp) то советник должен всё закрыть игнорируя максимальный порог(Equity_RollbackDown)
Но я же говорю, что я не телепат: вы сначала написали, так, а потом всё перевернули.

Все идет плавно и последовательно.

Всё идёт плавно и последовательнок тому, что скоро вы свой бездарный труд будете впаривать лохам за очень кругленькую сумму.И я очень сильно обрадуюсь, если хотя бы на ваш счёт сильно ошибусь
avatar

  20  alex30774 Сообщений: 782

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

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

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

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

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


Редактирован: 10 февраля 2025, 12:41
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 10 февраля 2025, 12:40
+
0
Судя по вашим опусам, вы далеки от программирования, как я от Одессы.

А разве вы не из Одессы?
Ну во-первых (опять), Вы все время забываете, что общаетесь с Одесситом.

Взял из вашего сообщения:
Ну смешно, право.
Во-первых я не волшебник, а только учусь.
Во вторых, согласно закона Мура сложность, мощность и пр. вычислений каждый год удваивается. Возведите 2 в пятую степень и вы узнаете на каком калькуляторе я работаю. Вся исходная информация Вам была дана еще до этого.
В-третьих, Вы забыли о таком понятии, как архив котировок.
В-четвертых, ни на один вопрос (это о помощи) Вы не дали ответа. Так в чем помощь, то?
Судя по копи-пасту из какого-то консервативного советника, Вы не понимаете, как работает Ваш советник. Вывод: не до конца уловили идею автора. А Андрей, на которого Вы ссылаетесь, просто исполнил Ваши хотелки. Не удивительно. Судя по тому, что я вижу, кроме него никто не кодит. Я не знаю, где он может найти время на вникание. Это не реально. Но молодец. Сказывается опыт в этом деле.
Ликбез Вы устроить не можете. Компетенций маловато. Логика у Вас, ну… как у моей жены. Ах, как она пельмени делает… Советник подправленный я Вам дал в двух вариантах. Сравните и найдите разницу. Да, сравнивать можно как изнутри, так и снаружи. Это насчет одеяла.
Больше всего мне понравился шестой пункт.
Ну во-первых (опять), Вы все время забываете, что общаетесь с Одесситом.
«Бомбический» алгоритм, это по-нашенски. Профит.
Во-вторых «таинственный» скрипт умеет очень быстро закрывать отрицательные локи. При чем с большой выгодой. Финансовой имеется ввиду. Ставьте вместо SL в рабочей стратегии равновесные замки и при накоплении лимита ордеров или просадки выравниваете по лотам все ордера и в течение 1-3 дней — занимаетесь «разминированием».
В-третьих, Вы так и не ответили, кто такой МЫ.
В-четвертых, Вы не читаете то, что я Вам пишу. Я давно предложил Вам пообщаться в привате на вполне разумных условиях. Подходят — добро пожаловать.


Или вы Одессит, только когда над кем-то подтрунить надо, чтоб в ответ ничего «прилитело»
avatar

  20  alex30774 Сообщений: 782

  • 10 февраля 2025, 14:27
+
0
P.S.ещё раз вот про это
Судя по вашим опусам, вы далеки от программирования

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

Скорее всего вы SSG имеете ввиду, завидую ему, умнее меня оказался: раньше меня понял, что с такими как вы обьщаться, себя не уважать.
avatar

  20  alex30774 Сообщений: 782

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

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

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

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

Удачи вам.


Редактирован: 10 февраля 2025, 15:11
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

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

  8  kvashnin007 Автор Сообщений: 734 - Андрей

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

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

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

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

  8  kvashnin007 Автор Сообщений: 734 - Андрей

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

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

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

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

Часть №1


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

  8  kvashnin007 Автор Сообщений: 734 - Андрей

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


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

            SignalB = false; SignalS = false;

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

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

  8  kvashnin007 Автор Сообщений: 734 - Андрей

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


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

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

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

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 8 февраля 2025, 14:42
+
0
Ничесе повеселился

Часть №4


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


avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 8 февраля 2025, 14:48
+
0
avatar

  15  OSS5 Сообщений: 171

  • 9 февраля 2025, 08:21
+
0
Уважаемый, OSS5.

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

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

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

Спасибо.

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

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

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

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

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

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

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

  8  kvashnin007 Автор Сообщений: 734 - Андрей

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

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

Так. Мысль после тестирования настигла. Это не критично, но все таки.
Редактирован: 10 февраля 2025, 15:32
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

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

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

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

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

Должен получиться не лучший, но рабочий советник для реальной торговли.
Редактирован: 10 февраля 2025, 14:28
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 10 февраля 2025, 12:13
+
0
Да уж. Простыня опять удлинилась до" устанешь крутить".

Давайте перейдем на новую страницу.

kvashnin007.opentraders.ru/132475.html
Редактирован: 10 февраля 2025, 15:39
avatar

  8  kvashnin007 Автор Сообщений: 734 - Андрей

  • 10 февраля 2025, 15:35

Зарегистрируйтесь или авторизуйтесь, чтобы оставить комментарий