Группа "Стол заказов MQL"

Рейтинг 2146



РЕКОМЕНДУЮ




Лучшее от axe44



Крутые памм-счета Комментариев 6
2017-10-24 11:58:58Рейтинг 0

БКС Комментариев 8
2017-08-11 02:57:12Рейтинг 0

торги
2017-01-26 00:01:37Рейтинг 0

HelloDual v3.0 Комментариев 3
2017-11-19 02:21:03Рейтинг 0

Создание советников бесплатно Комментариев 2
2017-07-16 22:54:20Рейтинг 0

Скрипт

Здравия!

Брокер начал мошенничать. Ну как? Ну просто не выполняет приказы.

Стандартный код на отправку ордера


void PutOrder(int type, double price, double stoploss, double takeprofit)
  {
   int r=0,co=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);
     }


   if(AutoLot<=0){lot=Lots;}
   if(AutoLot>0){lot=MoneyManagement();}

   
   r=OrderSend(NULL,type,lot,NormalizeDouble(price,Digits),Slip,sl,tp," Момент ",Magic,TimeCurrent()+Expir*60*60,clr);//
   Sleep (1000);
  // co=GetLastError();
  // if (co!=0) if ( co==2||co==4||co==6||co==129||co==128||co==135||co==136||co==137||co==138||co==139)
   
   return;
  }


Хотел спросить: Возможно ли вернуться к выполнению команды заново или к конкретной строчки?

Спасибо
  • 0
  • Просмотров: 1761
  • 4 августа 2020, 16:06
  • axe44
Понравилcя материал? Не забудьте поставить плюс и поделиться в социальной сети!

Вступите в группу "Стол заказов MQL", чтобы следить за обновлениями
ПРИСОЕДИНИТЬСЯ К ГРУППЕ
присоединиться
  Предыдущая запись в группе
Добавить сигнал к индикатору
Следующая запись в группе  
Сделать стрелку к индикатору Turn_Area
04 августа 2020
05 августа 2020

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

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

+
0
Просто обычный вызов команды «PutOrder(int type, double price, double stoploss, double takeprofit);» продблемы не решает
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 4 августа 2020, 16:34
+
0
При вызове ошибки меджик не учитывается… беда короче
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 4 августа 2020, 17:47
+
0
А если поставить в начале проверку выставлен ли ордер данным скриптом? Если выставлен, то закрываем скрипт. Если нет, то выставить. Когда доходим до выставления, выполняем, возвращаем в начало. Зациклить в общем, пока не найдет свой ордер. Либо после команды выставления ордера, запрашивать установил ли ордер? Если нет, то возвращаем.
avatar

  14  Syte Сообщений: 399

  • 4 августа 2020, 20:08
+
0
При вызове номера ошибки, номер обнуляется. Если робот ничего не делал, соответсвенно должен быть ноль. Там такая система запутанная…
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 4 августа 2020, 20:19
+
0
Скинул в личку, попробуй. Если нужно открыть ордер. Это как вариант
avatar

  14  Syte Сообщений: 399

  • 4 августа 2020, 20:24
+
0
обычно делают функцию количество попыток установки ордера:


//+------------------------------------------------------------------+
//| Установка ордера                                                 |
//+------------------------------------------------------------------+
void PutOrderReal(int type,double price)
  {
   int r=0,err=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);
     }

   if(AccountFreeMarginCheck(Symbol(),type,Lot(type))<=0)
     {
      Print("No enough money!");
      trade=false;
      return;
     }

   for(int k=1; k<=MaxEntry; k++)
     {
      if(!IsTesting() && (!IsExpertEnabled() || IsStopped()))
         break;
      while(!IsTradeAllowed())
         Sleep(5000);
      RefreshRates();

      r=OrderSend(NULL,type,Lots,NormalizeDouble(price,_Digits),Slip,sl,tp,"",Magic,0,clr);
      if(r>0)
        {
         Print("Order is placed successfully: "+" OOP: ",price," SL: ",sl," TP: ",tp);
         break;
        }
      else
        {
         err=GetLastError();
         Print("Error(",err,") Order delete error: ",ErrorDescription(err));

         // Блокировка работы советника
         if(ErrorsAction(err)==2)
           {
            trade=false;
            Print("Stop the Advisor!");
            return;
           }
         // Длительная пауза
         if(ErrorsAction(err)==1)
           {
            Sleep(1000*LongPause);
           }
         //  Небольшая пауза
         if(ErrorsAction(err)==0)
           {
            Sleep(1000*ShortPause);
           }
        }
     }
   return;
  }
avatar

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

  • 4 августа 2020, 20:58
+
0
*drinks*  Только как это решает вопрос например с ошибкой «время запроса истекло и ордер не выставился?
Повторный запрос я реализовал через функцию PutOrderReal(type,price); прямо в функции PutOrderReal(...). Но там ещё одна проблемка. Допустим в одно и тот же момент два советника на разных графиках одновременно выставляю ордера, соотвествеено два запроса никак не обработаются и у двух советников выскакивает ошибка „ордер не принят“. Получается что два робота спамят потом ордерами?
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 4 августа 2020, 21:35
+
0
После выставления ордера запускаеться блок поиска ошибок. Поправьте код если не верный…
<code>

   r=OrderSend(NULL,type,lot,NormalizeDouble(price,Digits),Slip,sl,tp," Момент ",Magic,TimeCurrent()+Expir*60*60,clr);//
   Sleep (5000);
   
   co=GetLastError();
   if (co==0)Alot=0;
   if (r==0)
   {if ( co==128||co==4||co==6||co==129||co==128||co==135||co==136||co==137||co==138||co==141||co==146||co==4107)
   PutOrder(type,price, stoploss, takeprofit, Alot);
   if(co!=0)Print("Текущая ошибка ", co,", Модель: ",Magic);
   }
</code>

Редактирован: 4 августа 2020, 21:44
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 4 августа 2020, 21:41
+
0
запускаетЬся… граматей…
впринципе и ошибку 128 дважды вписал…
ну… вроде сам и исправился
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 4 августа 2020, 21:49
+
0
Если ошибка не учтена, по крайней мере напечатается…
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 4 августа 2020, 21:51
+
0
*think*  С этим вызовом кода ошибки *crazy*  полный дом непоняток.
При первом же вызове ошибки второй робот даже при ошибке получает информацию о её отсутствии… Теперь понятно что одну функцию и МТ4 можно выкинуть — это меджик *shock* , ни и что теперь один терминал — один робот *spokuha* .
Кто не согласен?
Редактирован: 5 августа 2020, 07:45
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 5 августа 2020, 07:40
+
0
А у тебя два робота, между собой данными обмениваются?? Я просто ни как не пойму, для чего это, если это так?
avatar

  14  Syte Сообщений: 399

  • 5 августа 2020, 08:43
+
0
Весь смысл этого в том что если два робота выставили заявку на открытие, брокер обработает в любом случаи только одну. Теперь вопрос: как понять, что 1. Заявка обработана; 2. Заявка ещё в обработке; заявка не принята; 3. Брокер послал куда подальше, так как у него новости и класть он хотел на то, что ты захотел закрыть ордер или заработать.
Ответ очевиден: вызвать код ошибки. Теперь очень интересно как понять двум роботам по чьей заявке выскочила ошибка? К ошибке меджик номер не прикручен, и повторный вызов ошибки выдаёт в любом случаи круглый ноль. Вот не задача, что им двоим делать? А если их пять?
Более того интересный факт, я часто замечал, что и закрытие ордеров не всегда гладко проходит.
И для статистики: у типа *tipatogo*  брокера Альпари при выходе новостей заявки не обрабатываются по 3 часа иногда, и *tipatogo*  брокера Форекс клуб заявки утром обрабатываются часто по 5 минут, если обрабатываются.
Если поставить цикл отправлять заявки до результата, может закончиться депозит.

Как бы это проблема, и я пытаюсь её решить и совместно написать код безотказного выставления ордера
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 5 августа 2020, 10:28
+
0
*wall*  вот бы ещё эту функцию docs.mql4.com/ru/trading/orderopentime прикрутить как надо к R2-D2 *boss* , что бы возвращал хотя бы время последнего ордера в часах для тотального контроля.
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 5 августа 2020, 10:50
+
0
Сколько на Альпари торгую, не видел, что бы не давали открыть ордер. А обязательно по рынку открывать. Может проще в таком случаи отложник выставить?
avatar

  14  Syte Сообщений: 399

  • 5 августа 2020, 11:03
+
0
У меня всё по факту
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 5 августа 2020, 11:35
+
0
Андрей, я знаю что моими кодами иногда пользуешься. Может завершим написание кода?
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 5 августа 2020, 11:37
+
0
:D :D *good* *bravo* 
avatar

  24  ShamanHand Сообщений: 1092 - Наношу добро, причиняю пользу.

  • 5 августа 2020, 12:08
+
0
Ха-ха. Он мне спасибо говорил за найденные ошибки
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 5 августа 2020, 12:20
+
0
эх
avatar

  17  vis Сообщений: 200 - ♫♪♫♪

  • 5 августа 2020, 12:58
+
0
Может функция Кима поможет:
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 10.04.2008                                                     |
//|  Описание : Открывает позицию по рыночной цене.                            |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (NULL или "" - текущий символ)          |
//|    op - операция                                                           |
//|    ll - лот                                                                |
//|    sl - уровень стоп                                                       |
//|    tp - уровень тейк                                                       |
//|    mn - MagicNumber                                                        |
//|    co - комментарий                                                        |
//+----------------------------------------------------------------------------+
void OpenPosition(string sy, int op, double ll, double sl=0, double tp=0, int mn=0, string co="") {
  color    clOpen;
  datetime ot;
  double   pp, pa, pb;
  int      dg, err, it, ticket=0;

  if (sy=="" || sy=="0") sy=Symbol();
  if (op==OP_BUY) clOpen=clOpenBuy; else clOpen=clOpenSell;
  if (co=="") co=WindowExpertName()+" "+GetNameTF(Period());
  for (it=1; it<=NumberOfTry; it++) {
    if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) {
      Print("OpenPosition(): Остановка работы функции");
      break;
    }
    while (!IsTradeAllowed()) Sleep(5000);
    RefreshRates();
    dg=MarketInfo(sy, MODE_DIGITS);
    pa=MarketInfo(sy, MODE_ASK);
    pb=MarketInfo(sy, MODE_BID);
    if (op==OP_BUY) pp=pa; else pp=pb;
    pp=NormalizeDouble(pp, dg);
    ot=TimeCurrent();
    if (MarketWatch)
      ticket=OrderSend(sy, op, ll, pp, Slippage, 0, 0, co, mn, 0, clOpen);
    else
      ticket=OrderSend(sy, op, ll, pp, Slippage, sl, tp, co, mn, 0, clOpen);
    if (ticket>0) {
      if (UseSound) PlaySound(SoundSuccess); break;
    } else {
      err=GetLastError();
      if (UseSound) PlaySound(SoundError);
      if (pa==0 && pb==0) Message("Проверьте в Обзоре рынка наличие символа "+sy);
      // Вывод сообщения об ошибке
      Print("Error(",err,") opening position: ",ErrorDescription(err),", try ",it);
      Print("Ask=",pa," Bid=",pb," sy=",sy," ll=",ll," op=",GetNameOP(op),
            " pp=",pp," sl=",sl," tp=",tp," mn=",mn);
      // Блокировка работы советника
      if (err==2 || err==64 || err==65 || err==133) {
        gbDisabled=True; break;
      }
      // Длительная пауза
      if (err==4 || err==131 || err==132) {
        Sleep(1000*300); break;
      }
      if (err==128 || err==142 || err==143) {
        Sleep(1000*66.666);
        if (ExistPositions(sy, op, mn, ot)) {
          if (UseSound) PlaySound(SoundSuccess); break;
        }
      }
      if (err==140 || err==148 || err==4110 || err==4111) break;
      if (err==141) Sleep(1000*100);
      if (err==145) Sleep(1000*17);
      if (err==146) while (IsTradeContextBusy()) Sleep(1000*11);
      if (err!=135 && err!=138) Sleep(1000*7.7);
    }
  }
  if (MarketWatch && ticket>0 && (sl>0 || tp>0)) {
    if (OrderSelect(ticket, SELECT_BY_TICKET)) ModifyOrder(-1, sl, tp);
  }
}
avatar

  16  ssg Сообщений: 817

  • 5 августа 2020, 15:03
+
0
Ким дотошный мужик и местами от бога. Но в этом коде он упускает одну важную деталь. Попробую объяснить коротко. Код отправляет заявку на окрытие ордера, потом проверяет на наличие ошибок, если ошибок нет, модифицирует ордер (раньше можно было отправить заявку, а потом только вставить туда стоп и прибыль), если есть ошибки, то просто паузы, иногда Алерт. И всё. То есть повторной отправки ордера тут нету. Возможно есть потом, но не тут.

Этот кад похож на беседу брокера и купца:
— ты примешь заявку?
— нет.
— ну тогда попью чая.
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 5 августа 2020, 15:19
+
0
Да, проглядел что нет повторной попытки открытия.Хотя меня эта функция ни разу не подвела.
Тогда простой вариант вариант (можно использовать как заготовку)
//-------------------------------------------------------------------------
bool SendOrder(int tip, double lot, string com)
{
   for (int i=0; i<OrdersTotal(); i++) 
   {  
      if (OrderSelect(i, SELECT_BY_POS))
      {  
         if (OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
         {
            if (OrderComment()==com) return(0);
         }
      }
   }
   int error,nn;
   while(true)
   {
      RefreshRates();
      if (tip==OP_BUY) error = OrderSend(Symbol(),OP_BUY,lot,NormalizeDouble(Ask,Digits),slippage,0,0,com,Magic,0,Blue);
      
      if (tip==OP_SELL) error = OrderSend(Symbol(),OP_SELL,lot,NormalizeDouble(Bid,Digits),slippage,0,0,com,Magic,0,Red);
      
      if (error==-1)
      {
         Print("OrderSend Error ",GetLastError()," Lot ",lot);
         Sleep(1000);
      }
      else return(1);
      nn++;
      if (nn>10) return(0);
   }
   return(1);
}
//-------------------------------------------------------------------

avatar

  16  ssg Сообщений: 817

  • 5 августа 2020, 16:24
+
0
По истории лучше перебирать ордера с конца
<code>for (int i=OrdersTotal(); i>OrdersTotal()-1; i--) </code>

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

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

Я пока обдумываю как проще
Редактирован: 5 августа 2020, 16:41
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 5 августа 2020, 16:41
+
0
Я же писал — это шаблон, нужна доработка.
Можно в разных советниках ставить разное время ожидания Sleep(1000);
Что касается перебора ордеров, то перебираю с конца только при закрытии позиций.
Вот еще одна функция Кима, может пригодиться:
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает время открытия последней открытой позиций.          |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любая позиция)                  |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//+----------------------------------------------------------------------------+
datetime TimeOpenLastPos(string sy="", int op=-1, int mn=-1) {
  datetime t;
  int      i, k=OrdersTotal();

  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==sy || sy=="") {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderOpenTime()) t=OrderOpenTime();
            }
          }
        }
      }
    }
  }
  return(t);
}
avatar

  16  ssg Сообщений: 817

  • 5 августа 2020, 17:30
+
0
Вообще библиотека Кима мне очень помогает:
//+----------------------------------------------------------------------------+
//|                                                           b-Positions.mqh  |
//|                                                                            |
//|                                                    Ким Игорь В. aka KimIV  |
//|                                                       http://www.kimiv.ru  |
//|                                                                            |
//|  08.11.2006  Библиотека функций для работы с позициями.                    |
//+----------------------------------------------------------------------------+
#property library

// ClosePosBySelect                Закрытие одной предварительно выбранной позиции
// ClosePosBySizeLossInCurrency    Закрытие тех позиций, у которых убыток в валюте депозита превысил некоторое значение
// ClosePosBySizeProfitInCurrency  Закрытие тех позиций, у которых профит в валюте депозита превысил некоторое значение
// ClosePosBySortLots              Закрытие позиций в порядке сортировки по размерам лотов
// ClosePosExceptTicket            Закрытие позиций по рыночной цене за исключением одной с переданным тикетом
// ClosePosFirstProfit             Закрытие позиций по рыночной цене сначала прибыльных
// ClosePositions                  Закрытие позиций по рыночной цене
// ClosePosWithMaxProfitInCurrency Закрытие позиции с максимальным положительным профитом в валюте депозита
// DistMarketAndPos                Расстояние в пунктах между рынком и ближайшей позицей
// ExistInHistoryCloseBetween      Существование в истории позиции или ордера, закрытой (удалённого) между датами.
// ExistInHistoryOpenBetween       Существование в истории позиции или ордера, открытой (установленного) между датами.
// ExistInHistoryToDay      Существование ордера или позиции в истории за сегодня
// ExistOPNearMarket        Существование позиции или ордера около рынка
// ExistPosByPrice          Существование позиций по цене открытия
// ExistPositions           Существование позиций
// GetAmountLotFromOpenPos  Сумма лотов открытых позиций
// GetIndexLastPos          Индекс последней открытой позиции или -1
// GetLotLastClosePos       Возвращает размер лота последней закрытой позиции или -1
// GetLotLastPos            Возвращает размер лота последней открытой позиции или -1
// GetMaxLotFromOpenPos         Максимальный размер лота из открытых позиций
// GetMinLotFromOpenPos         Минимальный размер лота из открытых позиций
// GetProfitFromDateInCurrency  Суммарный профит в валюте депозита закрытых с определённой даты позиций
// GetProfitOpenPosInCurrency   Суммарный профит открытых позиций в валюте депозита
// GetProfitOpenPosInPoint      Суммарный профит открытых позиций в пунктах
// GetTicketLastPos             Тикет последней открытой позиции или -1
// GetTypeLastClosePos      Тип последней закрытой позиции или -1
// GetTypeLastOpenPos       Тип последней открытой позиции или -1
// isCloseLastPosByStop     Флаг закрытия последней позиции по стопу
// isCloseLastPosByTake     Флаг закрытия последней позиции по тейку
// isLossLastPos            Флаг убыточности последней позиции
// isTradeToDay             Возвращает флаг торгов сегодня
// MovingInWL               Перенос уровня стопа в безубыток
// NumberOfBarCloseLastPos  Номер бара закрытия последней позиции или -1
// NumberOfBarOpenLastPos   Номер бара открытия последней позиции или -1
// NumberOfLossPosToday     Количество убыточных позиций, закрытых сегодня
// NumberOfPositions        Количество позиций
// OpenPosition             Открытие позиции
// PriceCloseLastPos        Цена закрытия последней закрытой позиций
// PriceOpenLastClosePos    Цена открытия последней закрытой позиций
// PriceOpenLastPos         Цена открытия последней открытой позиций
// PriceOpenNearPos         Цена открытия ближайшей позиции
// SecondsAfterCloseLastPos Количество секунд после закрытия последней позиций
// SecondsAfterOpenLastPos  Количество секунд после открытия последней позиций
// SimpleTrailing           Сопровождение позиций простым тралом
// TakeProfitLastClosePos   Возвращает цену TakeProfit последней закрытой позиций или -1
// TakeProfitLastPos        Возвращает цену TakeProfit последней открытой позиций или -1
// TicketNearPos            Тикет ближайшей к рынку позиции по цене открытия или 0
// TimeOpenLastPos          Время открытия последней открытой позиций
// TypeNearPos              Возвращает тип ближайшей к рынку позиции или -1
avatar

  16  ssg Сообщений: 817

  • 5 августа 2020, 17:32
+
0
OrderOpenTime(); Показывает время в от года до секунды. Нужно вынять номер часа и что бы он совпадал с текущим часом. После, думаю, нужно проверять условия повторно. Ну, хотя бы потому, что рынок может быть закрыт.
Спасибо конечно, но просто взять OrderOpenTime(); не вариант. Нужно его ещё и сравнить.
Если сравнивать с Тайм Корент() получим опять вариант в секундах. Ну может кому то и вариант… Я считаю, что в часах сравнивать проще.
В любом случае кода пока нет
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 5 августа 2020, 19:07
+
0
А может отвязаться от времени и проверку делать опираясь на цену открытия последней позиции?
avatar

  16  ssg Сообщений: 817

  • 5 августа 2020, 20:31
+
0
Я именно об этом и говорю. Открываем последний ордер, узнаём время и сравниваем с текущим.
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 5 августа 2020, 21:38
+
0
Кажеться код готов.
Единственный минус в атолоте. Он выставляет ордер в любом случае, даже если нету денег на минимальный лот.
Для начала два вспомогательных кода. Встречайте!
Автолот:


//+------------------------------------------------------------------+
//| расчёт лота                                                      |
//+------------------------------------------------------------------+
double MoneyManagement()
  {
   double DynamicLot=0;
   double Free_Equity=MathMax( AccountEquity(),AccountBalance());
   if(Free_Equity<=0)return(0);
   double TickValue=MarketInfo(Symbol(),MODE_TICKVALUE);
   double LotStep=MarketInfo(Symbol(),MODE_LOTSTEP);
   double MinLot=MarketInfo(Symbol(),MODE_MINLOT);
   double MxLot=MarketInfo(Symbol(),MODE_MAXLOT);
   if (TickValue*LotStep!=0) DynamicLot=MathFloor((Free_Equity*MathMin(AutoLot/100,100)/100000)/TickValue/LotStep)*LotStep; 
   //Print(DynamicLot,"DynamicLot");
   if(DynamicLot<MinLot)DynamicLot=MinLot;
   if(DynamicLot>MxLot)DynamicLot=MxLot;
   return(DynamicLot);
  }


Проверка на наличие ордеров

//+------------------------------------------------------------------
//| Смотрим историю
//+------------------------------------------------------------------
  
bool Histori(int year,int month, int day, int hour)//
{    
   
   for ( i = OrdersTotal()-1; i>=0; i--)
   {
     if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
         {
         if(year==TimeYear(OrderOpenTime()))
          {
            if(month==TimeMonth(OrderOpenTime()))
             {
               if(day==TimeDay(OrderOpenTime()))
                {
                  if(hour==TimeHour(OrderOpenTime()))
                   {
                     return(true);
                   }
                }
             } 
          }
        }
      }        
   }  
   return(false);
}
  


Ну и сам код выставления ордеров



//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PutOrder(int type, double price, double stoploss, double takeprofit, double Alot)
  {
   int r=0,co=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);
     }
     
   if(Alot==0)//Проверяем А-лот. Если А-лот больше нуля, то ордер не выставился в первый раз. Если А-лот равен нулю, значит выставляем ордер в первый раз и нужно задать параметр автолота.
   {
   if(AutoLot<=0){lot=Lots;}
   if(AutoLot>0){lot=MoneyManagement();}
   
   up=CountOrders(0);
   dn=CountOrders(1);
   
   //закрываем ордера, ставим множитель по мартингейлу
   if(type==0&&dn>0){lot=NormalizeDouble(lot*Klot*dn,Digits);CloseAll(1);}
   if(type==1&&up>0){lot=NormalizeDouble(lot*Klot*up,Digits);CloseAll(0);}
   if(lot<MarketInfo(Symbol(),MODE_MINLOT))lot=MarketInfo(Symbol(),MODE_MINLOT);
   if(lot>MarketInfo(Symbol(),MODE_MAXLOT))lot=MarketInfo(Symbol(),MODE_MAXLOT);
   Sleep(10000);
   
   
   //всё хорошо, все ордера закрылись, теперь запоминаем размер А-лота на всякий случай
   Alot=lot;
   }
   
   //На всякий случай А-лот запомнили не зря
   else 
   {
   lot=Alot;
   
   
   //закрываем ордера, ставим множитель по мартингейлу
   if(type==0&&dn>0){lot=NormalizeDouble(lot*Klot*dn,Digits);CloseAll(1);}
   if(type==1&&up>0){lot=NormalizeDouble(lot*Klot*up,Digits);CloseAll(0);}
   if(lot<MarketInfo(Symbol(),MODE_MINLOT))lot=MarketInfo(Symbol(),MODE_MINLOT);
   if(lot>MarketInfo(Symbol(),MODE_MAXLOT))lot=MarketInfo(Symbol(),MODE_MAXLOT);
   Sleep(10000);
   
   //всё хорошо, все ордера закрылись, теперь запоминаем размер А-лота на всякий случай
   if(Alot<lot)Alot=lot;
   }
   
   //если ордера остались, то повторяем цикл через выставление ордера без выставления ордера
   up=CountOrders(0);
   dn=CountOrders(1);
   if(type==0&&dn>0)PutOrder(type,price, stoploss, takeprofit, Alot);
   if(type==1&&up>0)PutOrder(type,price, stoploss, takeprofit, Alot);
   
   
   
   
   r=OrderSend(NULL,type,lot,NormalizeDouble(price,Digits),Slip,sl,tp," Момент ",Magic,TimeCurrent()+Expir*60*60,clr);//
   Sleep (10000);//ждём 10 секунд
   
   co=GetLastError();//тут проверяем есть ли ошибка
   if (co==0)Alot=0;
   if (r==0)//если ордера нету и есть ошибка, пробуем выставлять ордер повторно
   {if ( co==4||co==6||co==129||co==128||co==135||co==136||co==137||co==138||co==141||co==145||co==146||co==4107)
   PutOrder(type,price, stoploss, takeprofit, Alot);
   }
   
   //выводим на экран номер ошибки и номер робота по меджик номеру
   if(co!=0)Alert("Текущая ошибка ", co,"\r\n" ,", Модель: ",Magic);
   
   //последний аванпост по защите сделки
   Sleep (1000*60*5);//на всякий случай ждём 5 минут, проверяем терминал на наличие выставленого ордера и если его нет , то выставляем ордер
   if(Histori(Year(),Month(),Day(),Hour())==false)PutOrder(type,price, stoploss, takeprofit, Alot);
   
   //Ура! Ордер есть ! Продолжаем работу!
   return;
  }
avatar

  13  axe44 Автор Сообщений: 1149 - Алек

  • 15 августа 2020, 09:58

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