Функции для реальной торговли и для реальных счетов. Ким - хорошо, а мы на что?

Уважаемые друзья. Господа и, надеюсь, дамы.

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

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

27 мая 2024
02 февраля 2025

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

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

+
0
Так как я плохо знаком с mql5, общаться будем в основном на языке mql4.
Возможно, в наших рядах появится кто-то более продвинутый и возмет на себя нагрузку по «переводу» нашего «птичего» mql4 на более продвинутый язык. Будем только рады.
Редактирован: 18 января 2025, 10:46
avatar

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

  • 18 января 2025, 10:16
+
0
Пока хочу начать с общих рассуждений.

У кого нет идей — у того нет ни малейшего понятия, как работает рынок. Ну а как оттуда денег поиметь… Желание есть. А как? Кто-то работает лапками и, даже, более менее успешно. Это люди, которые лучше остальных познают торговлю. Мое же мнение (и не только мое) — лапами с малыми деньгами ни хрена не заработаешь. Робот неустанно, днем и ночью, без выходных, без неВРов… Нег.., пардон, темнокожий человек. Четко выполняющий заложенные в его голову инструкции.

Алгоритм.

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

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

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

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

И еще одна ВАЖНАЯ вещь. По закону падающего бутерброда, все пойдет не так, как вы расчитываете. Посему надо ограничивать или страховать потери. Надо всегда знать, как вы будете реагировать на «баба Яга против».

Но это больше алгоритм, включая SL, trail, ММ и другие извращения.

В этом же топике я хочу затронуть вопросы борьбы с брокером. Его палками в колеса. Проверки, работа над ошибками типа GetLastError().

Редактирован: 18 января 2025, 12:05
avatar

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

  • 18 января 2025, 11:56
+
0
С чего-то надо начинать. Предлагаю кому-нибудь дать свой советник, написанный упрощенно для проверки идеи. Советник желателен посложнее. Многофункциональный. На его примере мы можем заняться заменой функций Что-то я предложу. Что-то другие. Поищем варианты.

В конечном итоге топика должен получиться файл с функциями для замены.
avatar

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

  • 18 января 2025, 12:20
комментарий был удален 2025-01-20 13:26:11 kvashnin007

+
0
Андрей, спасибо за внимание. Но Здесь не требуется дописать под реал что-то конкретное. Это сможет сделать каждый, самостоятельно напрямую обратившись к программистам.

Идея топика в ЛИКБЕЗе. В обучении самостоятельно делать тривиальные вещи. Я бы был благодарен, если ли бы Вы взялись в топике переводить функции на mql5, периодически поглядывая сюда, возможно, внося какие-либо комментарии или исправления. Добавления.

Топику просто необходим грамотный и ответственный специалист.
Редактирован: 18 января 2025, 16:03
avatar

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

  • 18 января 2025, 16:02
комментарий был удален 2025-01-20 13:26:34 kvashnin007

комментарий был удален 2025-01-20 13:26:50 kvashnin007

+
+1
Поражен.

Всем подай кнопку «Рубить бабло».

Нет такой, наивные.

Только своими головой и руками.
avatar

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

  • 19 января 2025, 17:15
+
0
Ну да ладно.
Поведем караван.

Удобная штука: имеешь набор функций. Проверенных не раз. С всевозможными проверками, повторами, работой над ошибками. А в OnTick() точишь себе алгоритм. Если это, то выполняем ту-то функцию. Кроме того, что удобно, так и еще читаемость кода улучшается, а значит ошибок меньше и бороться с ними проще. Только есть несколько ТОЛЬКО.

Возьмем, например, всем вам до боли знакомую функцию Открытия рыночного и, для универсальности, выставления отложенных ордеров от АМ2:

<code>
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PutOrder(int type,double price,double lot)
  {
   int r=0;
   color clr=Green;
   double sl=0,tp=0;

   if(type==1 || type==3 || type==5)
     {
      clr=Red;
      if(StopLoss>0)
         sl=NormalizeDouble(price+StopLoss*_Point,_Digits);
      if(TakeProfit>0)
         tp=NormalizeDouble(price-TakeProfit*_Point,_Digits);
     }

   if(type==0 || type==2 || type==4)
     {
      clr=Blue;
      if(StopLoss>0)
         sl=NormalizeDouble(price-StopLoss*_Point,_Digits);
      if(TakeProfit>0)
         tp=NormalizeDouble(price+TakeProfit*_Point,_Digits);
     }

   r=OrderSend(NULL,type,lot,NormalizeDouble(price,_Digits),Slip,sl,tp,Comm,Magic,0,clr);
   return;
  } 
//+------------------------------------------------------------------+
</code>


Обычная так себе функция. В чем универсальность? Да одна функция на все случаи жизни. Удобно таки.
Хочешь ордер по рынку — укажи тип 0 или 1, хочешь выставить отложку — 2,3,4 или 5, соответственно выбору.
Ах да, цену открытия надо выставлять. А какая она у единицы? Или нуля? А, не дай бог, и поболее. Тут надо напрячся. А почему не написать PutOrder (OP_BUY), вместо PutOrder (0)? Мало того, что красным цветом пойдет так и лишний раз и напрягаться не надо. Хотя это одна и таже команда. Ну Lot можно по-разному. Иногда проще в теле, а иногда лучше отдать его расчет отдельной функции. Часто, если алгоритм предполагает дележ ордеров на группы, указывают в скобках еще int magic.

Теперь — «обвязка» ордера. SL,TP, Slippage и т.д.

Тут тоже хватает нюансов.
Кто-то хочет, чтобы настройки советника были одинаковыми для четырех и пяти знаковых терминалов.
Поэтому _Point часто превращают в глобальную переменню double pnt, например. Для чего? Да просто: если пятизнак, то _Point увеличивают *10. А в связи с тем, что эта величина постоянная, pnt задают один раз в OnInit(). Плюс к этому, не надо будет каждый раз обращаться к терминалу с запросом величины Point(). Исходя из этих же соображений я бы ввел еще переменную string symbol. И один раз бы в OnInit() приравнял бы ее Symdol(). Аналогично и с _Digits.

Особое внимание надо обратить на SL и ТР. Первым делом, в связи с тем, что эти переменные не меняются по ходу работы советника, я бы ввел глобальные переменные _double sl, tp; по аналогии, о чем выше в OnInit() сразу один бы раз перевел в стоимост, избегая дальнейших лишних телодвижений. Т.е. в OnInit() sl=StopLoss*_Point и tp=TakeProfit*_Point. Аналогично можно поступить и с другими пунктовыми переменными, которые остаются неизменным по ходу работы советника. Например, Step, Trail, BU и т.д.

В связи с тем, что было выше писано, функция от Андрея должна выглядеть приблизительно ТАК:

<code>//+------------------------------------------------------------------+
//|                                                       Locker.mq4 |
//|                                              Copyright 2022, AM2 |
//|                                     https://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, AM2"
#property link      "https://www.forexsystems.biz"
#property version   "1.00"
#property strict

//--- Inputs
extern int    StopLoss      = 23;        // лось   в пунктах
extern int    TakeProfit    = 78;        // язь    в пунктах
extern int    Slippage      = 3;         // реквот в пунктах

strig  symbol; 
int    digits, slippage;
double pnt,sl,tp;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
      symbol = Symbol(); 
      digits = Digits;
      pnt    = Point;
   
      if(digits==3 || digits==5)
        {
        tp       = TakeProfit*pnt*10;
        sl       = StopLoss*pnt*10;     
        slippage = Slippage*pnt*10;
        }
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Comment("");
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   if(CountTrades()==Count && !TimeSession(StartHour,StartMin,EndHour,EndMin,TimeCurrent()))
      {
      if(Sell)
         PutOrder(OP_BUY,Ask,Lot);
      if(Buy)
         PutOrder(OP_SELL,Bid,Lot);
      }
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PutOrder(int type,double price,double lot)
  {
   int r=0;
   color clr=Green;

   if(type==OP_SELL || type==OP_SELLLIMIT || type==OP_SELLSTOP)
     {
      clr=Red;
      if(StopLoss>0)
         sl=NormalizeDouble(price+sl,digits);
      if(TakeProfit>0)
         tp=NormalizeDouble(price-tp,digits);
     }

   if(type == OP_BUY || type == OP_BUYLIMIT || type==OP_BUYSTOP)
     {
      clr=Blue;
      if(StopLoss>0)
         sl=NormalizeDouble(price-sl,digits);
      if(TakeProfit>0)
         tp=NormalizeDouble(price+tp,digits);
     }

   r=OrderSend(NULL,type,lot,NormalizeDouble(price,digits),slippage,sl,tp,Comm,Magic,0,clr);
   return;
  }
//+------------------------------------------------------------------+</code>


В результате мы имеем функцию, для проверки идей в более удобоваримом виде и объективно, хоть не на много, но таки быстрее. Особенно важно при тестировании.

А функцию для работы на реале мы попробуем слепить в следующий раз.
Редактирован: 20 января 2025, 16:29
avatar

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

  • 20 января 2025, 16:02
+
0
А для чего вам функция PutOrder? Советник Moving Average в тестере работает намного быстрее советников от АМ2.
Если любите играться с советниками в тестере, то пишите без функции PutOrder, то есть напрямую.
avatar

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

  • 21 января 2025, 10:50
+
0
Алекс, доброго дня, вечера, жизни.

Рад, что хоть кто-то…

Поэтому отвечу на вопрос.

Начну с названия топика: Функции…
Их много. Думаю, что прибегали хоть раз к услугам АМ2. Если так, то вы видели его вариант PutOrder(). Ну вот вы родили толкову мысль, с помощью Андрея получили советник для тестера, потестировали, чуть поправили алгоритм и… Сами охренели.

Как красиво пишет зараза. Куплю жене сапоги. Положили на счет котлету и на всю начали зарабатывать, зеленея от надежды. А что-то идет не по феншую. Вы его и так и сяк. А он все херет и хренет. Не понятненько… "- Андрей, а чего так-то?" Так советник то для тестера. Под реал адаптировать надо. Пару копеек и любой каприз.
А уверенность в работоспособности поубавилась до нуля. Зачем тратить деньги? Так вот и пропадают хорошие идеи.

А если бы вы позанимались в моем топике, то сами бы привели советник в реальное состояние. Погоняли бы его в этом измененном состоянии, а затем бы делали оргвыводы. Если бы вы получили приемлемые результаты, то и с деньгами бы расставались бы осознанно.

Это так. Лирика о смысле топика.

Теперь по существу.

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

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

А советники я изучаю чисто по коду. Там все написано. В отличие от тестера.

А вы, чтоб быть объективным, а не голословным, замените в советнике Moving Average код открытия ордера на функцию PutOrder и сравните скорости. Ну если, конечно, умеете. В противном случае — ко мне в топик. Вопросы только обогащают общение.
avatar

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

  • 21 января 2025, 17:42
+
0
Скорость работы советника для меня не важна.Это я вам по советовал, так как мне показалось, что для вас она имеет значение.
Для меня на первом месте адекватность работы советника, чтобы советник не пропускал сигналы и всегда входил в сделки.
К сожалению функции отвечающим моим требованиям в свободном доступе нет.Я у многих програмистов проверил.Брал ихние советники и прописывал для всех одинаковые условия.И у всех были пропущенные сделки.
В маркете в котигории бесплатные попадались хорошие советники, под них как раз и подгонял советники с открытым кодом.Но у этих авторов не было советников с открытым кодом.

А вы, чтоб быть объективным, а не голословным, замените в советнике Moving Average код открытия ордера на функцию PutOrder и сравните скорости. Ну если, конечно, умеете. В противном случае — ко мне в топик. Вопросы только обогащают общение.

У каждого своё понимание о скорости.У меня количество баров за минуту.Тоесть сколько советник пройдёт баров за минуту в режиме тестирования.Но я на это внимание не особо обращаю.
avatar

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

  • 21 января 2025, 18:37
+
0
Глупо спрашивать: как просчитать это количество.

Но согласен, что каждому свое. А на счет пропуска сделок — для этого и топик.
Расчитывал на похожих на вас, пробовавших всякое и имеющих результаты. Вот бы общаком и вывели максимально оптимальное.

У меня есть своих пара мыслей, как заставить брокера открыть, выставить, поставить и пр. Но прежде надо быть уверенным, что ты не нарушаешь никакие правила. Топик и об этом.
Редактирован: 21 января 2025, 19:19
avatar

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

  • 21 января 2025, 19:06
+
+1
Глупо спрашивать: как просчитать это количество.

1.Запускаете тестирование,
2.потом ставите на паузу
3.ставите вертикальную линию
4.затем снимаете с паузы и через минуту ставите вторую вертикальную линию
5.теперь считаете количество баров между вертикальными линиями

Если за минуту будет меньше 25 баров(такое бывает при использовании некоторых пользовательских индикаторов)советник может пропустить сделку, если тоговать на таймфреймах 1М,5М
avatar

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

  • 21 января 2025, 19:26
+
0
Наверно можно и так. Но у меня есть советник, который лучше всего работает на дневках. А за три месяца делает до семиста сделок. Есть советники, которые привязываются именно к TF. Видимо поэтому мне никогда в голову не приходил такой способ.

Но, как говорил выше, каждому свое.
avatar

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

  • 21 января 2025, 19:48
+
0
И да. Вы правы. Скорость для меня имеет значение. Особенно в тестировании. Здесь тоже есть варианты. Например работать по ценам закрытия минутных свечей.

Но это должно быть продолжением топика.
Редактирован: 21 января 2025, 19:16
avatar

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

  • 21 января 2025, 19:13
+
0
Функция открывающая и (или) выставляющая отложенные ордера довольно индивидуальна. И, в зависимости от контекста, может сильно отличаться своим функционалом. Кто-то сразу в функцию закладывает условия, при которой производятся те или иные действия. Кто-то сразу выставляет SL и ТР. Кто-то еще что-то.

Посему найти вариантов — немеряно. Но я считаю, что эта функция должна быть заточена исключительно для открытия и (или) высталения ордеров. Условия же, при которых… должны быть в теле в OnInit().
Счета ECN не допускают открытие ордеров сразу со SL и (или) ТР. Открыл — выставил. Поэтому, считаю правильным выставлять ограничения после открытия ордера ВСЕГДА. Это подойдет для любого случая. За что и будет отвечать отдельная функция. Например, PutSL_TP(). Возможен вариант работы и вовсе без ограничений сверху-снизу.
Возможен и вариант с виртуальными SL и ТР. Например, по касании соответствующей линии, или по какому либо индюку. Вариантов тоже тьма.
Но повторюсь: эта тьма желатена к прописке в основном теле OnInit().

Единственное, что всегда надо предусматривать, чтобы таки ордера выставлялись или открывались гарантированно.
А для этого неоходимо, чтобы все цены были нормализованны. Чтобы SL и ТР были на допустимом удалении. Чтобы денег хватало на открытие ордера.

Есть и другие «козни брокера». Их то и надо предусмотреть и преодолеть.

Но это попозже.

Продолжение следует.
Редактирован: 21 января 2025, 10:18
avatar

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

  • 21 января 2025, 10:13
+
0
Продолжаем.

Хочу предложить к рассмотрению функцию, предложенную Владимиром Хлыстовым (cmillion).Она с болшей вероятностью открывает ордера. Можно потом добавить и отложки. Но это потом.

<code>//--------------------------------------------------------------------
void OPENORDER(int ord,double Price,double LOT)
{
      int rez,err=0;
      double SL=0,TP=0;
      
      while (true)
         {  
         rez=true;
         RefreshRates();
         
         if (ord==OP_BUY) 
            {
            if (takeprofit>=STOPLEVEL) TP  = NormalizeDouble(Price + takeprofit*Point,Digits); else TP=0;
            if (stoploss>=STOPLEVEL)   SL  = NormalizeDouble(Price - stoploss*Point,Digits);   else SL=0;     
            rez=OrderSend(Symbol(),OP_BUY, LOT,Price,slippage,SL,TP,"http://cmillion.ru",Magic,0,Blue);
            }
         if (ord==OP_SELL) 
            {
            if (takeprofit>=STOPLEVEL) TP = NormalizeDouble(Price - takeprofit*Point,Digits); else TP=0;
            if (stoploss>=STOPLEVEL)   SL = NormalizeDouble(Price + stoploss*Point,Digits);   else SL=0;              
            rez=OrderSend(Symbol(),OP_SELL,LOT,Price,slippage,SL,TP,"http://cmillion.ru",Magic,0,Red);
            }
         if (rez==-1)
            {  
            txt=StringConcatenate(txt,"\nError ",GetLastError());
            if (ord== 1) txt = StringConcatenate(txt,"  OPENORDER BUY ","  Ask =",DoubleToStr(Ask,Digits),"   Price =",DoubleToStr(Price,Digits)," (",NormalizeDouble((Price-Ask)/Point,0),")  SL =",DoubleToStr(SL,Digits)," (",NormalizeDouble((Price-SL)/Point,0),")  TP=",DoubleToStr(TP,Digits)," (",NormalizeDouble((TP-Price)/Point,0),")  STOPLEVEL=",STOPLEVEL);
            if (ord==-1) txt = StringConcatenate(txt,"  OPENORDER SELL ","  Bid =",DoubleToStr(Bid,Digits),"   Price =",DoubleToStr(Price,Digits)," (",NormalizeDouble((Bid-Price)/Point,0),")  SL =",DoubleToStr(SL,Digits)," (",NormalizeDouble((SL-Price)/Point,0),")  TP=",DoubleToStr(TP,Digits)," (",NormalizeDouble((Price-TP)/Point,0),")  STOPLEVEL=",STOPLEVEL);
            Print(txt);
            err++;Sleep(1000);RefreshRates();
            }
         else 
            {
            Comment("Ордер ",rez," успешно выставлен ");
            return;
            }
         if (err >attempts)
             return;
         }
   return;
}                  
//--------------------------------------------------------------------

</code>


А пока, что мы видим?

Функция while (true) Будет пытаться attempts раз выставить ордер. Вы можете сами указать сколько это раз. Если не сможет, то вообще выйдет из OPENORDER().

Но это уже к психотерапевту.

Перед походом, на всякий случай, проверте валидность выдаваемого лота. Журнал вам в помощь. А вообще-то, проверять надо всегда.

SL и ТР здесь сразу выставляются. Что не совсем комильфо. Думаю лучше обнулить. А выставление ограничений можно сделать отдельной функцией. Тоже настойчиво.

Это потом, а пока, думаю, функция должна выглядеть примерно так.

<code>//--------------------------------------------------------------------
void OPENORDER_2(int ord,double Price,double LOT)
{
      int rez,err=0;
      double SL=0,TP=0;
      
      while (true)
         {  
         rez=true;
         RefreshRates();
         
         if (ord==OP_BUY) 
            rez=OrderSend(Symbol(),OP_BUY, LOT,Price,slippage,0,0,"",Magic,0,Blue);
         if (ord==OP_SELL) 
            rez=OrderSend(Symbol(),OP_SELL,LOT,Price,slippage,0,0,"",Magic,0,Red);
         if (rez==-1)
            {  
            txt=StringConcatenate(txt,"\nError ",GetLastError());
            if (ord== 1) 
               txt = StringConcatenate(txt,"  OPENORDER BUY ","  Ask =",DoubleToStr(Ask,Digits),"   Price =",DoubleToStr(Price,Digits)," (",NormalizeDouble((Price-Ask)/Point,0),")  SL =",DoubleToStr(SL,Digits)," (",NormalizeDouble((Price-SL)/Point,0),")  TP=",DoubleToStr(TP,Digits)," (",NormalizeDouble((TP-Price)/Point,0),")  STOPLEVEL=",STOPLEVEL);
            if (ord==-1) 
               txt = StringConcatenate(txt,"  OPENORDER SELL ","  Bid =",DoubleToStr(Bid,Digits),"   Price =",DoubleToStr(Price,Digits)," (",NormalizeDouble((Bid-Price)/Point,0),")  SL =",DoubleToStr(SL,Digits)," (",NormalizeDouble((SL-Price)/Point,0),")  TP=",DoubleToStr(TP,Digits)," (",NormalizeDouble((Price-TP)/Point,0),")  STOPLEVEL=",STOPLEVEL);
            Print(txt);
            err++;
            Sleep(1000);
            RefreshRates();
            }
         else 
            {
            Comment("Ордер ",rez," успешно выставлен ");
            return;
            }
         if (err >attempts)
             return;
         }
   return;
}                  
//--------------------------------------------------------------------

</code>


Ограничения, если нужны выставим другой функцией.
Редактирован: 23 января 2025, 15:07
avatar

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

  • 23 января 2025, 14:56
+
0
Функция while


Опять метаквотовцы учебник переписали: раньше while был оператром, а теперь стал функцией.Вечно я за ними не успеваю.

Лучше не пользуйтесь функциями Хлыстова.На советник «простой советник» много жалоб в интернете было.Даже у меня к совеве питензии были: советник торгует хорошо первую неделю, а во вторую перестаёт открывать сделки, переустанавливаешь советник и вновь начинает открывать сделки и так до следующей недели
avatar

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

  • 23 января 2025, 17:29
+
0
Лучше язвить, чем язву иметь. Метаквотовцам передавайте наше с кистью.

Меня всегда интересуют причинно-следственные связи.

Простой советник от того и простой. Жаловаться на него, то же, что и на отсутствие зонта во время дождя. Т.е. бесполезно. Человек с колена поделился мыслью. Не нравится — проходи мимо. А если он тебе в жилу, разберись сам, чего понедельник тяжелый день. У меня тоже, как правило.

К стати не смотрел, но уверен: там орднра открываются не таким образом.

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

Тут у нас девушка обитает. Почему-то мама OXY назвала. Так вот, ее коды гораздо симпатичнее и продуманнее, чем коды АМ2. Так она тоже не брезгует подобными подходами. Сейчас что-нибудь найду.

Блин. В моем бардаке сходу хрен что найдешь. Попался Хлыстов первым, вот его и взял.
Не важно. Взял пример. Работаю над ним. Кто-то предложит другой вариант (может гораздро лучше) поработаем и с ним. А пока что конкурентции ноль.

Всех благ.


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

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

  • 23 января 2025, 19:21
+
0
Тут у нас девушка обитает. Почему-то мама OXY назвала

OXY, потому что Оксана Беренко
www.mql5.com/ru/users/cat7?ysclid=m69khejyvq136296018


кстати АМ2, он же Андркй Корнишкин
www.mql5.com/ru/users/am2


Лучше язвить, чем язву иметь
Я не язвлю, а деликатно(чтобы вас не обидеть) намекаю

Тут у нас девушка обитает. Почему-то мама OXY назвала. Так вот, ее коды гораздо симпатичнее и продуманнее, чем коды АМ2.
.

АМ2 я не защищаю, просто его советники упрощены(для того чтоб быстрее работали в тестере стратегий, (для некоторых это важнее), чтоб проверить стратегию и как можно быстрее проверить советник с разными настройками), как говориться каждому своё.
Советники которые размещаются «в столе заказов» не предназначены для торговли на реале, а скорее как предварительный набросок, как говориться. Не надо ждать от них чуда.
Вот здесь Бишоп разъесняет
zakaz.opentraders.ru/42058.html


А вот немного размышлений от АМ2
mql.opentraders.ru/33776.html

mql.opentraders.ru/31257.html


P.S.Если лень всё это читать, то вдвух словах: не один программист не напишет бесплатно что-то хорошее.
Редактирован: 23 января 2025, 21:39
avatar

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

  • 23 января 2025, 21:14
+
0
Я о том же. Но есть хвастуны. Хвала им.

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

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

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

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

  • 24 января 2025, 08:43
+
0
Хочу предложить к рассмотрению функцию, предложенную Владимиром Хлыстовым (cmillion).Она с болшей вероятностью открывает ордера. Можно потом добавить и отложки. Но это потом.

В этой функции нет проверки на ошибки, точнее говоря нет конромер(противодействий)на ошибки и еёиспользование довольно опасно.
Может случиться реквот(или другая ошибка) и советник не закроет сделку по обратному сигналу и тогда будет убыток.
avatar

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

  • 24 января 2025, 11:32
+
0
Дойдем, добавим.
avatar

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

  • 24 января 2025, 18:58
+
0
Это код под МТ4?
avatar

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

  • 23 января 2025, 15:37
+
0
Да. МТ5 не мой вариант.
Редактирован: 23 января 2025, 16:22
avatar

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

  • 23 января 2025, 16:21
+
0
Не факт, что брокера можно заставить таки открыть ордер, но чем настойчивее это действие, тем больше шансов.
По-этому можно еще больше обнаглеть. Завернуть одну просьбу в другую. Да, немного помедленнее. Но более убедительно.
А если учесть, что тестер при оптимизации, если нет ошибок, то с первого захода открывает сделки,
то те же 5-100 сделок в месяц ну никак не повлияют скорость работы советника.

Обратимся все к тому же Володе Хлыстову. Есть у него в свободном пользовании скрипт для открытия ордеров:

<code>#property copyright "Copyright © 2014, Хлыстов Владимир"
#property link      "cmillion@narod.ru"
#property show_inputs
#property strict
//--------------------------------------------------------------------
extern int      stoploss       = 50,       //уровень выставления SL, если 0, то SL не выставляется
                takeprofit     = 50,       //уровень выставления TP, если 0, то TP не выставляется
                MaxOrders      = 1,        //кол-во ордеров
                Magic          = 123456;   //уникальный номер ордера
extern double   LotBuy         = 0.1;      //объем ордера если 0 то не откоывать
extern double   LotSell        = 0.1;      //объем ордера если 0 то не откоывать
extern int      attempts       = 10;       //кол-во попыток открытия
extern int      Slippage       = 3;        //кол-во попыток открытия

string txt;
int n,slippage;
double STOPLEVEL;
//--------------------------------------------------------------------
int start()
{
      STOPLEVEL=MarketInfo(Symbol(),MODE_STOPLEVEL);
      
      slippage = Slippage;
      
      if (Digits==3 || Digits==5) 
         slippage=Slippage*10;
   
      for (int i=1; i<=MaxOrders; i++)
         {
         if (LotBuy>0)
            OPENORDER (OP_BUY,NormalizeDouble(Ask,Digits),LotBuy,i);
         if (LotSell>0)
            OPENORDER (OP_SELL,NormalizeDouble(Bid,Digits),LotSell,i);
         }
      Comment("Скрипт закончил свою работу, выставлено ",n," ордеров  ");
   return(0);
}
//--------------------------------------------------------------------
void OPENORDER(int ord,double Price,double LOT,int i)
{
      int error,err=0;
      double SL=0,TP=0;
      
      while (true)
         {  
         error=true;
         RefreshRates();
         
         if (ord==OP_BUY) 
            {
            if (takeprofit>=STOPLEVEL) TP  = NormalizeDouble(Price + takeprofit*Point,Digits); else TP=0;
            if (stoploss>=STOPLEVEL)   SL  = NormalizeDouble(Price - stoploss*Point,Digits);   else SL=0;     
            error=OrderSend(Symbol(),OP_BUY, LOT,Price,slippage,SL,TP,"http://cmillion.ru",Magic,0,Blue);
            }
         if (ord==OP_SELL) 
            {
            if (takeprofit>=STOPLEVEL) TP = NormalizeDouble(Price - takeprofit*Point,Digits); else TP=0;
            if (stoploss>=STOPLEVEL)   SL = NormalizeDouble(Price + stoploss*Point,Digits);   else SL=0;              
            error=OrderSend(Symbol(),OP_SELL,LOT,Price,slippage,SL,TP,"http://cmillion.ru",Magic,0,Red);
            }
         if (error==-1)
            {  
            txt=StringConcatenate(txt,"\nError ",GetLastError());
            if (ord== 1) txt = StringConcatenate(txt,"  OPENORDER BUY ",i,"   Ask =",DoubleToStr(Ask,Digits),"   Price =",DoubleToStr(Price,Digits)," (",NormalizeDouble((Price-Ask)/Point,0),")  SL =",DoubleToStr(SL,Digits)," (",NormalizeDouble((Price-SL)/Point,0),")  TP=",DoubleToStr(TP,Digits)," (",NormalizeDouble((TP-Price)/Point,0),")  STOPLEVEL=",STOPLEVEL);
            if (ord==-1) txt = StringConcatenate(txt,"  OPENORDER SELL ",i,"   Bid =",DoubleToStr(Bid,Digits),"   Price =",DoubleToStr(Price,Digits)," (",NormalizeDouble((Bid-Price)/Point,0),")  SL =",DoubleToStr(SL,Digits)," (",NormalizeDouble((SL-Price)/Point,0),")  TP=",DoubleToStr(TP,Digits)," (",NormalizeDouble((Price-TP)/Point,0),")  STOPLEVEL=",STOPLEVEL);
            Print(txt);
            Comment(txt,"  ",TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS));
            err++;Sleep(1000);RefreshRates();
            }
         else 
            {
            Comment("Ордер ",error," успешно выставлен ",TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS));
            n++;
            return;
            }
         if (err >attempts)
             return;
         }
   return;
}                  
//--------------------------------------------------------------------
</code>


Здесь у него Цикл в цикле. Циклы, если обращаются за данными к брокеру, тормоза. Основные. Но в данном случае — вещь полезная и не ручник.

Правда у него здесь основной цикл пытается запустить программу открытия ордеров столько раз, сколько указываем в
MaxOrders. По идее: сколько ордеров укажешь, столько и откроет. Но все они одинаковые. В чем смысл? Не понятненько.
При этих настройках скрипт откроет один ордер на покупку по цене Ask и один ордер на продажу по цене Bid.
Ну да ладно. Это его скрипт и для его целей. Наша задача извлечь свою выгоду.

Но это в следующий раз
.


Редактирован: 23 января 2025, 19:26
avatar

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

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

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

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


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

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


Редактирован: 24 января 2025, 00:22
avatar

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

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

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

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

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


Пока так. Дальше начнем разбираться с лотами и ограничениями. Чуть позже — работой над ошибками.
Редактирован: 24 января 2025, 12:49
avatar

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

  • 24 января 2025, 12:46
+
0
Вот вам ещё пища для размышления.Небольшой пример:
-----------------------------------------

bool open=false;
int ticket = 0;
while(!open && !IsStopped())
{
  ticket=OrderSend(Symbol(),OP_BUY,lot,Ask,300,0,0,"",Magic,0,Lime);
  if(ticket > 0) open = true;
}
----------------------------------------------------------------------------

Здесь цикл while будет посылать запросы на открытие ордера до его успешной установки. 

---------------------------------------------------------------------------------------------
avatar

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

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

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

  • 24 января 2025, 15:47
+
0
А как он получится правильным
Lot = GetLots((stoploss - open_price) / pnt);


допустим стоплосс у вас 1.04689
цена открытия 1.04539
тогда лот равен 0.00150 а если разделить на pnp(Point), то размер лота получется равным 150
avatar

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

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

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

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

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

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

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

   if(lot>MaxLot)
      lot=Lots;

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


Ну или:

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


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

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

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

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

  • 24 января 2025, 15:52
+
0
В данном случае будут открываться сразу рыночные ордера?
avatar

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

  • 24 января 2025, 13:46
+
0
будут, если при этом не будет реквота или другой ошибки при которой заявка будет отклонена.
avatar

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

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

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

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


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

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

  • 24 января 2025, 15:49
+
0
avatar

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

  • 24 января 2025, 15:53
+
0
Ладно. Куда — понял. А вот что? и зачем?..

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

Что-то не пляшет.
Редактирован: 24 января 2025, 19:52
avatar

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

  • 24 января 2025, 19:51
+
0
Что-то не пляшет


там вы будете исправлять до тех пор, пока не будет реал. будете искать образцы кода, читать статьи и др.
avatar

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

  • 24 января 2025, 21:27
+
0
И с чего начать?
avatar

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

  • 25 января 2025, 06:39
+
0
И с чего начать

С подготовки болванки советника, затем будете навешивать недостающие функции, проверки и т.д.
avatar

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

  • 25 января 2025, 09:27
+
0
хочу пройти тот же путь только на мкл 5.
начал с этой статьи: www.mql5.com/ru/articles/385#base

потом продолжил: www.mql5.com/ru/articles/2555

целый день писал, оформлял, проверки проходил. прошел валидацию:



делал советник по тренду с усреднением, мультивалютный и с выводом крайних ордеров в плюс:





продукт: www.mql5.com/ru/market/product/130892
Редактирован: 26 января 2025, 00:09
avatar

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

  • 25 января 2025, 09:58
+
0
Открытые позиции закрываются:

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

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

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

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

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

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

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

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

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

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

  • 26 января 2025, 16:07
+
0
Я бы наоборот шаг уменьшал. Тем более, если ты хочешь сокращать крайние ордера, надо сокращать расстояние, необходимое для их сокращения.


кэф в советнике можно поставить меньше 1 и будет уменьшать шаг.

присылайте советник который торгует в плюс стабильно на реале и можно будет покумекать, а все что выше только мысли вслух
avatar

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

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

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

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

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

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

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

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

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

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

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

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

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

  • 27 января 2025, 12:54
+
0
К чему это я? Вот ты дал сноску на свой советник с маркета. Он торгует стабильно в плюс на реале?


основа советника с этого сигнала: www.mql5.com/ru/signals/2271402

avatar

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

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

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

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

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

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

double e1,e2,e3,e4,e5,e6,
       c1,c2,c3,c4,
       n,
       w1,w2,
       b2,b3,
       t3;
double ExtUp[], ExtDn[], ExtMd[], ExtBuyArrow[], ExtSellArrow[],
       BBUp[], BBDn[], BBMd[], 
       priceUp[], priceDn[], signalUp[], signalDn[];
//************************************************************************************************/
//*                                                                                              */
//************************************************************************************************/
int OnInit()
  {
   Comment("");
//---
   b2=B*B; 
   b3=b2*B; 
   c1=-b3; 
   c2=(3*(b2+b3)); 
   c3=-3*(2*b2+B+b3); 
   c4=(1+3*B+b3+3*b2); 
   n=t3_period;
   
   if(n<1) n=1;
   n=1+0.5*(n-1); 
   w1=2/(n+1); 
   w2=1-w1;
//----
   return(INIT_SUCCEEDED);
  }
//************************************************************************************************/
//*                                                                                              */
//************************************************************************************************/
void OnTick()
  {
   double
   BuyPriceMax=0,BuyPriceMin=0,BuyPriceMaxLot=0,BuyPriceMinLot=0,
   SelPriceMin=0,SelPriceMax=0,SelPriceMinLot=0,SelPriceMaxLot=0;

   int
   BuyPriceMaxTic=0,BuyPriceMinTic=0,SelPriceMaxTic=0,SelPriceMinTic=0;

   double
   op=0,lt=0,tp=0;

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

   for(int i=OrdersTotal()-1;i>=0;i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
         if(OrderMagicNumber()==iMagicNumber)
            if(OrderSymbol()==Symbol())
              {
               op=NormalizeDouble(OrderOpenPrice(),Digits());
               lt=NormalizeDouble(OrderLots(),2);
               tk=OrderTicket();
               if(OrderType()==OP_BUY)
                 {
                  b++;
                  if(op>BuyPriceMax || BuyPriceMax==0)
                    {
                     BuyPriceMax    = op;
                     BuyPriceMaxLot = lt;
                     BuyPriceMaxTic = tk;
                    }
                  if(op<BuyPriceMin || BuyPriceMin==0)
                    {
                     BuyPriceMin    = op;
                     BuyPriceMinLot = lt;
                     BuyPriceMinTic = tk;
                    }
                 }
               // ===
               if(OrderType()==OP_SELL)
                 {
                  s++;
                  if(op>SelPriceMax || SelPriceMax==0)
                    {
                     SelPriceMax    = op;
                     SelPriceMaxLot = lt;
                     SelPriceMaxTic = tk;
                    }
                  if(op<SelPriceMin || SelPriceMin==0)
                    {
                     SelPriceMin    = op;
                     SelPriceMinLot = lt;
                     SelPriceMinTic = tk;
                    }
                 }
              }
//*************************************************************//
avatar

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

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

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

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

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

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

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

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

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

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

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

  }
//************************************************************************************************/
//*                                                                                              */
//************************************************************************************************/
bool CheckVolumeValue(double volume)
  {
//--- минимально допустимый объем для торговых операций
   double min_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN);
   if(volume<min_volume)
      return(false);

//--- максимально допустимый объем для торговых операций
   double max_volume=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MAX);
   if(volume>max_volume)
      return(false);

//--- получим минимальную градацию объема
   double volume_step=SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_STEP);

   int ratio=(int)MathRound(volume/volume_step);
   if(MathAbs(ratio*volume_step-volume)>0.0000001)
      return(false);

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

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

  • 27 января 2025, 19:42
+
0


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

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

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

Редактирован: 29 января 2025, 11:19
avatar

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

  • 28 января 2025, 07:07
+
0
Вот этот вариант работы совы, это ваш или Андрея?
avatar

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

  • 31 января 2025, 19:08
+
0
Мой туля. Тот, что здесь в склейке выше.
avatar

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

  • 31 января 2025, 19:20
+
0
вот тоже интересный советник. пока еще не знаю как работает: www.mql5.com/ru/market/product/123850
avatar

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

  • 28 января 2025, 09:13
+
0
очень интересный советник. логика хорошо читается. прибыльная позиция после закрытия отщипывает от убыточной
avatar

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

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

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

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

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

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

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

ВЫВОД: КОТ В МЕШКЕ. Хотя, возможно, и породистый.
Редактирован: 28 января 2025, 16:18
avatar

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

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

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

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

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

  • 28 января 2025, 14:20
+
0
Почитал обсуждения советника.
Сделал вывод, что советник Робот GBPUSD — туфта.

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

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

  • 28 января 2025, 14:52
+
0
А как собрать все три части в рабочий код, чтобы в живую посмотреть работу в тестере?
avatar

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

  • 28 января 2025, 21:01
+
0
Это не оптимизированный вариант, но рабочий. При желании займемся оптимизацией и правильными функциями. Вобщем топик для того и делался. Правда желающих поучаствовать четыре человека.Ты да Я, да Мы с Тобой.

Открываешь в редакторе любой советник. Жмешь «Сохранить как» «Мой кассовый аппарат».
Удаляешь весь код этого советника.
Потом на пустое место последовательно копируешь три части кода.

Жмешь «Компилировать».

В терминале окажется нужный советник под названием «Мой кассовый аппарат».
Оптимизировать можно по контрольным точкам. Перепроверять по тикам.

Удачи.

Редактирован: 29 января 2025, 00:06
avatar

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

  • 28 января 2025, 23:58
+
0
Все что вы написали я делал, но у меня при компилировании выбивает ошибку. Я не программист от слова ВООБЩЕ. Поэтому в проблеме сам не разберусь*fool* 
avatar

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

  • 31 января 2025, 18:40
+
0
Как сюда файлы кидать?
Или почту дайте.
Редактирован: 31 января 2025, 19:23
avatar

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

  • 31 января 2025, 19:22
+
0
почта business_7999@yahoo.com
avatar

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

  • 31 января 2025, 19:26
+
0
Смотрел на картинку…



смотрел…

Можно получить похожую. Просадка, правда, будет чуть побольше. Сделок в минус будет 30%.

Это вариант «лесенки» с малым шагом и тралом минимальной прибыли. Должен получиться частотник сеточного типа с локированием. Две независимые ветви (возможно полностью). Получится двойное локирование.
Без индикаторов. С минимальным количеством переменных для оптимизации.
Редактирован: 29 января 2025, 18:27
avatar

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

  • 28 января 2025, 23:49
+
0
А что, Анндрей?
Слабо рискнуть репутацией?
avatar

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

  • 29 января 2025, 00:23
+
0
А что, Анндрей?
Слабо рискнуть репутацией?


присылайте видео работы советника в тестере.

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

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

  • 29 января 2025, 09:03
+
0
Что касается отыгрыша импульса, то смысл в работе по импульсу если и есть, то не уловим. Я не за новости с бешенным спредом. Импульсным движением почти всегда снимают или пробивают уровни. С последующим возвратом не менее 50% от импульса.

Свойства импульса:

— За тик цена меняется больше, чем «обычно».
— Тиковый объем тоже растет до некоторых пор. Потом цена растет за счет других трейдеров
(рали) с понижением объема. Просто за счет снятия блокирующих стен из множества
ордеров. Можно смотреть по стакану. Неудобно.
— Чаще всего образуется дисбаланс, но о нем мы узнаем позже. Значительно позже.
Но цену отката можно прикинуть.

Остается ерунда. Отловить импульс, в конце его выставить обратный ордер и вовремя выйти из сделки с максимальной прибылью.

Отловить импульс.
Есть хороший индикатор Similar, который позволяет вылавливать импульсы. Слегка доработать. Сделать уровни динамическими. Например по Болинджеру. Но это таки индикатор.
Я разрабатывал алгоритм работы по времени. Смысл в том, что каждую единицу времени, например 10 милисекунд, мы сравниваем значение цены с предыдущим значением. Если разрыв в цене больше заданного значения, то выставляем отложенный ордер (рисуем линию) на откат на небольшом расстоянии Step от текущей цены. Дальше тралим эту линию за ценой. Причем дистанция сокрашается. Можно с множителем, можно — пара пипсов с каждым тиком, а можно привязать к стоимости изменения цены за тик. Когда иссякает ралли количество тиков падает быстрее, чем цена. Берем соотношение умножанм на дистанцию. При касании линии ценой открываем рыночный ордер.

Да. Думаю, тебе это малоинтересно.
Редактирован: 29 января 2025, 19:49
avatar

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

  • 29 января 2025, 19:48
+
0
вчера смотрел советник секрет импульс, но даже близко сделать не удалось.


Тут с наскока не выйдет.

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

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

Дам картинки. Должны натолкнуть на мысли.

ПЕРВАЯ: как определять имбаланс по уму.



ВТОРАЯ: как определять импульсную свечу, тоже, по уму.



Посмотри. Может натолкнет на здравые мысли.
avatar

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

  • 29 января 2025, 23:16
+
0
Импульс часто сопровождаетя скачком спреда. По-этому не помешает его контроль.
Это были неуловимые сигналы для работы, по росту импульса.
Не забывай за работу на откате.
avatar

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

  • 29 января 2025, 23:28
+
0
ответ от гигачата :D 

нужно написать функцию открытия ордеров для реальных счетов на MQL5

Открытие ордера на реальном счете в MetaTrader 5 требует использования функций API для отправки торговых команд через торговый сервер. В MQL5 это делается с помощью встроенных функций, которые позволяют отправлять запросы на открытие ордеров, установку стоп-лоссов и тейк-профитов, а также закрытие позиций.

Вот пример простой функции для открытия рыночного ордера на покупку (BUY) или продажу (SELL):

#include <Trade\Trade.mqh>

CTrade trade; // Объект для выполнения торговых операций

bool OpenMarketOrder(const string symbol, const ENUM_ORDER_TYPE order_type,
                     const double volume, const double stoploss=0, 
                     const double takeprofit=0)
{
   // Создаем структуру для параметров ордера
   MqlTradeRequest request;
   ZeroMemory(request);

   // Заполняем параметры запроса
   request.action = TRADE_ACTION_DEAL;
   request.symbol = symbol;
   request.volume = volume;
   request.type_filling = ORDER_FILLING_FOK;

   switch(order_type) {
      case ORDER_TYPE_BUY:
         request.price = SymbolInfoDouble(symbol, SYMBOL_ASK);
         break;
      case ORDER_TYPE_SELL:
         request.price = SymbolInfoDouble(symbol, SYMBOL_BID);
         break;
      default:
         Print("Неверный тип ордера", order_type);
         return false;
   }

   // Устанавливаем стоп-лосс и тейк-профит, если они заданы
   if(stoploss > 0) {
      request.sl = stoploss;
   }
   if(takeprofit > 0) {
      request.tp = takeprofit;
   }

   // Отправляем запрос на открытие ордера
   bool result = trade.Send(request);

   if(result) {
      Print("Ордер успешно открыт");
   } else {
      Print("Ошибка при открытии ордера: ", trade.ResultRetcode(), " - ", trade.ResultComment());
   }

   return result;
}
Как работает эта функция:
Создание объекта CTrade: Используется объект trade, который позволяет выполнять торговые операции.
Заполнение структуры MqlTradeRequest: Структура содержит все необходимые параметры для создания торгового запроса.
Установка типа ордера: В зависимости от переданного параметра order_type устанавливается цена исполнения ордера (либо по цене ASK для покупки, либо по BID для продажи).
Отправка запроса: С помощью метода Send() отправляется запрос на открытие ордера.
Обработка результата: Если операция прошла успешно, выводится сообщение об успешном открытии ордера. В случае ошибки возвращается код ошибки и комментарий.
Пример использования функции:

void OnStart() {
   // Открываем ордер на покупку 0.01 лота по паре EURUSD без стоп-лосса и тейк-профита
   OpenMarketOrder("EURUSD", ORDER_TYPE_BUY, 0.01);
}

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

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

  • 29 января 2025, 16:17
+
0
Не люблю обращениц к библиотекам. Все равно — черный ящик.
Предпочитаю функции в советнике. Там все видно и понятно. Можно подкорректировать под свои нужды легким движением руки. А так…
Смотрел как-то код библиотеки. Универсальность — это слабость. Потеря времени. И для меня не удобно и не прозрачно. Да иеще убедиться перед… Код протестировать перед… Как?

Длин. МТ4 длиннее и тяжелее, но проще и работает понятно как. Да и чушь, что в mql5 невозможно писать свои функции ручками.
Редактирован: 29 января 2025, 18:25
avatar

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

  • 29 января 2025, 18:23
+
0
По лесенкам могу скинуть ТЗ. Один день и готово.
avatar

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

  • 29 января 2025, 18:26
+
0
Я хочу написать советник на основе нейросетей.
Потихоньку разбираюсь
avatar

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

  • 29 января 2025, 19:48
+
0
Много хочешь. Тормознись на чем-то. Сделай. Иди дальше.
Нейросети против вероятностей проигрывают.
avatar

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

  • 29 января 2025, 19:54
комментарий был удален 2025-01-29 23:19:41 kvashnin007

+
0
Гигачат набросал основу для советника
На нейросетях. Буду прогнозировать цену
Закрытия на неделю и торговать в этом направлении
Редактирован: 30 января 2025, 12:21
avatar

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

  • 30 января 2025, 12:18
+
0
Андрей, а зачем ты мне все это рассказываешь? Цель то в чем?
Редактирован: 30 января 2025, 19:01
avatar

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

  • 30 января 2025, 18:46
+
0
Прогнозировать цену — глупая затея.
Только математика и вероятности.
Прогнозы для лохов. Их все равно отимеют.
Еще и быстрее и по самое не хочу.

От нейросетей здесь та же польза, что и от экстраполяции.

Обрати лучше внимание на смартмани. Там хоть проанализированы особенности действий крупняка, который, чтобы заработать, будет поступать именно так.
По другому не получится. Садишься с ним в вагон и… на Майами.
Редактирован: 30 января 2025, 19:01
avatar

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

  • 30 января 2025, 18:57
+
0
Для себя я выделил 4-и совы: Roll (работает на отложках), Cnopochnyi usrednitell, TrendDetector и cm-rollback 3.00. Три первых писал Андрей. Roll по моей просьбе. Это RollBack который я все шлифую. cm-rollback 3.00 — это труд Владимира Хлыстова (cmillion).
avatar

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

  • 31 января 2025, 19:22
+
0
Простыня большая. открываю новую страницу
kvashnin007.opentraders.ru/132447.html
avatar

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

  • 2 февраля 2025, 10:36

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