Tutte le domande dei nuovi arrivati su MQL4 e MQL5, aiuto e discussione su algoritmi e codici - pagina 1548

 
SGarnov:

Per facilitarvi prendete il mio codice sorgente, ha una logica che funziona, tranne il problema che ho descritto, non lo capisco bene, la mia testa sta bollendo ma non sto andando da nessuna parte.

Piazzate un ordine in sospeso o due in direzioni diverse?
 
SGarnov:
Ho la sensazione che il robot stia diventando più forte, ma non so cosa farci.

@MakarFX lo sta già facendo. Non mettiamoci in mezzo.

Quello che volevo dire...Scrivi tutto in modo che sia chiaro per te (personalmente/personalmente), non tirare il codice con il copia-incolla.

e uno scheletro di robot molto semplificato assomiglia a questo:

int ticket=-1;             // тикет открытого ордера
bool inited=false;      // признак завершения инициализации

int OnInit()
{
   ticket=-1;
   inited=false;
   // ещё надо проверить параметры, но пока чёрт с ними
   // пробуем загрузить прежнее состояние
   if (LoadState()) {
      // из файла, базы или глоб.переменных загрузились
      if (!CheckState()) {
         // проверили, плохо всё..
         ClearState(); // удалить и поругаться
         Alert("Усё пропало, шеф !");
         return INIT_FAILED();
      }
   }
   return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
   if (inited) {
      // инициализация была проведена, стейт мог уже менятся во время работы
      SaveState(); // сохраняем куда-то там
   }
}

void OnTick()
{
   //// ЧТОБЫ БЫ БЫЛО ХОРОШО, 
   //// НЕ БОЛЕЕ 1-го ПРИКАЗА Open/Close/Modify на тик
   //// И ЗАВЕРШИТЬ ВСЁ ПО БЫСТРОМУ
   if (!inited) {
      // связь есть, тики идут
      // довести инициализацию до нужной кондиции
      if (!DoInit()) {
         // не довелась
         Alert("вот же блин...");
         ExpertRemove();
      } else {
         // в DoInit проставлен корректный ticket
         inited=true;
      }
      return;
   }
   // всё проиничено, ticket или -1 если нет нифига или реально тикет
   //// РАЗБОРЫ С ТИКЕТАМИ
   if (ticket<0) {
      // нет открытых ордеров
      // может открыть/переоткрыть ?
   } else {
      if (!OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) {
         // что-то не так с синхронизацией, просто пропустим тик
         return;
      }
      if (OrderCloseTime()!=0) {
         // ордер закрылся ручками или по стопам/тейкам (или стопаут, приплыли)
         OnCloseOrder();   // обработать, разобраться
         ticket=-1;        // нет у нас больше тикета..
         // в этот тик больше не успеть
         return;
      } else {
         if ((OrderStopLoss()==0 && SL!=0) || (OrderTakeProfit()==0 && TP!=0)) {
            // свежачок - надо ему выстаить Тейк и/или стоп
            
         } else {
            // для реала - проверять сработку Sl/Tp на ГЕПАХ, ЭТО ВАЖНО
         }
      }
   }
   //// РАЗБОРЫ с БАРАМИ
   CheckForOnBar();
   ///  и так далее...
}
void OnTimer()
{
   // тики завершаем быстро-быстро, поэтому открытия баров дополнительно проверяем по таймеру
   CheckForOnBar();
}

la birra fa miracoli e rende le persone più gentili :-)

 
MakarFX:
Piazzate un ordine in sospeso o due in direzioni diverse?
Faccio sempre un ordine in sospeso
 
SGarnov:
Ho sempre messo fuori un singolo in sospeso.

Provalo, chiedilo

//+------------------------------------------------------------------+
//|                                                   SGarnov.v2.mq4 |
//|                                           Copyright 2020, DrMak. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, DrMak."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//--- input parameters
input int      T_Profit = 2;     // Коэффициент Take Profit
input int      S_Loss   = 200;   // Уровень Stop Loss
input double   O_Lots   = 0.01;  // Лоты
input int      SL_Count = 2;     // Количество убыточных ордеров
input int      Slippage = 30;    // Проскальзывание
input int      N_Magic  = 888;   // Magic

datetime T_Start;
double sl_price,tp_price,t_profit,s_loss;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- 
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   t_profit = S_Loss*T_Profit;
   tp_price = NormalizeDouble(t_profit * Point(), Digits)+GetPointLoss();
//---
   s_loss   = MathMax(S_Loss, MarketInfo(_Symbol, MODE_STOPLEVEL));
   sl_price = NormalizeDouble(s_loss * Point(), Digits);

   // Удаляем отложенный ордер после профита
   if(CountOrders(-1)==1) DeletePending();
   // Проверяем серию убыточных ордеров
   if(GetLossOrders()<=SL_Count)
     {
      // Устанавливаем отложенный ордер
      SendPending();
     }

   // Проверяем наличие ордеров BUY
   if(CountOrders(0)>0)
     {
      // Устанавливаем StopLoss/TakeProfit
      ModifyOrder();
     }

   // Проверяем наличие ордеров SELL
   if(CountOrders(1)>0)
     {
      // Устанавливаем StopLoss/TakeProfit
      ModifyOrder();
     }
  }
//+------------------------------------------------------------------+
//| Модификация ордера                                               |
//+------------------------------------------------------------------+
void ModifyOrder()
  {
   int ticket=0;
   for(int pos=OrdersTotal()-1;pos>=0;pos--)
     {
      if(OrderSelect(pos,SELECT_BY_POS)==true)
        {
         if(OrderSymbol()==_Symbol)
           {
            if(OrderStopLoss()==0)
              {
               if(OrderType()==OP_BUY)
                 {
                  if(OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()-sl_price, OrderOpenPrice()+tp_price, OrderExpiration()))
                    {Print("Ордер модифицирован");}
                  else
                    {Print("Ошибка модификации ордера:", GetLastError());}
                 }
               if(OrderType()==OP_SELL)
                 {
                  if(OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()+sl_price, OrderOpenPrice()-tp_price, OrderExpiration()))
                    {Print("Ордер модифицирован");}
                  else
                    {Print("Ошибка модификации ордера:", GetLastError());}
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Подсчет ордеров по типу                                          |
//+------------------------------------------------------------------+
//|  0 - ордера типа BUY          1 - ордера типа SELL               |
//|  2 - ордера типа BUYLIMIT     3 - ордера типа SELLLIMIT          |
//|  4 - ордера типа BUYSTOP      5 - ордера типа SELLSTOP           |
//|  6 - ордера типа Balance     -1 - Все типы ордеров               |
//+------------------------------------------------------------------+
int CountOrders(int or_ty=-1) 
  {
   int cnt=0;
   for(int pos=OrdersTotal()-1;pos>=0;pos--)
     {
      if(OrderSelect(pos,SELECT_BY_POS)==true)
        {
         if(OrderSymbol()==_Symbol)
           {
            if(or_ty<0 || or_ty==OrderType()) cnt++;
           }
        }
     }
   return(cnt);
  }
//+------------------------------------------------------------------+
//| Установка отложенного ордера                                     |
//+------------------------------------------------------------------+
void SendPending()
  {
   double op=0;
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS)==true)
        {
         if(CountOrders(-1)==1)
           {
            if(OrderType()==OP_BUY)
              {
               if(OrderStopLoss() != 0)
                 {
                  op=OrderStopLoss();
                  if(OrderSend(_Symbol,OP_SELLSTOP,O_Lots,op,Slippage,0,0,NULL,N_Magic))
                    {Print("Отложенный ордер установлен");}
                  else
                    {Print("Ошибка установки отложеного одера: ", GetLastError());}
                 }
              }
            if(OrderType()==OP_SELL)
              {
               if(OrderStopLoss() != 0)
                 {
                  op=OrderStopLoss();
                  if(OrderSend(_Symbol,OP_BUYSTOP,O_Lots,op,Slippage,0,0,NULL,N_Magic))
                    {Print("Отложенный ордер установлен");}
                  else
                    {Print("Ошибка установки отложеного одера: ", GetLastError());}
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Удаление отложенного ордера                                      |
//+------------------------------------------------------------------+
void DeletePending()
  {
   for(int i = OrdersTotal() - 1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS)==true)
        {
         if(CountOrders(-1)==1)
           {
            if(OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP)
              {
               if(OrderMagicNumber() == N_Magic)
                 {
                  if(OrderDelete(OrderTicket()))
                    {Print("Отложенный ордер удален");}
                  else
                    {Print("Ошибка удаления отложеного одера: ", GetLastError());}
                 }
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Возвращает время начала цикла                                    |
//+------------------------------------------------------------------+
datetime TimeStart()
  {
   datetime ts=0;
   if(OrdersTotal()!=0)
     {
      for(int pos=OrdersTotal()-1;pos>=0;pos--)
        {
         if(OrderSelect(pos,SELECT_BY_POS)==true)
           {
            if(OrderSymbol()==_Symbol)
              {
               if(OrderMagicNumber()!=N_Magic)
                 {
                  ts=OrderOpenTime();
                 }
              }
           }
        }
     }
   else
   if(OrdersTotal()==0)
     {
      for(int pos=0; pos<OrdersHistoryTotal(); pos++)
        {
         if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
           {
            if(OrderSymbol()==_Symbol)
              {
               if(OrderType()==OP_BUY || OrderType()==OP_SELL)
                 {
                  if(OrderProfit()>0)
                    {
                     if(ts<OrderCloseTime())
                       {
                        ts=OrderCloseTime();
                       }
                    }
                 }
              }
           }
        }
     }
   return(ts);
  }
//+------------------------------------------------------------------+
//|  Возвращает пункты убытка закрытых ордеров с начала цикла        |
//+------------------------------------------------------------------+
double GetPointLoss()
  {
   double result=0,b=0,s=0;;
   int i=OrdersHistoryTotal();
   for(int pos=0; pos<i; pos++)
     {
      if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
        {
         if((OrderSymbol()==_Symbol))
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(OrderProfit()<0)
                 {
                  if(OrderCloseTime()>TimeStart())
                    {
                     if(OrderType()==OP_BUY&&OrderProfit()<0)
                       {
                        b+=OrderOpenPrice()-OrderClosePrice();
                       }
                     if(OrderType()==OP_SELL&&OrderProfit()<0)
                       {
                        s+=OrderClosePrice()-OrderOpenPrice();
                       }
                    }
                 }
              }
           }
        }
     }
   return(b+s);
  }
//+------------------------------------------------------------------+
//|  Возвращает кол-во серии убыточных ордеров                       |
//+------------------------------------------------------------------+
int GetLossOrders()
  {
   int cnt=0;
   int i=OrdersHistoryTotal();
   for(int pos=0; pos<i; pos++)
     {
      if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
        {
         if((OrderSymbol()==_Symbol))
           {
            if(OrderCloseTime()>TimeStart())
              {
               if(OrderProfit()<0) cnt++;
              }
           }
        }
     }
   return(cnt);
  }
//+------------------------------------------------------------------+
 
MakarFX:

Provalo, chiedilo

È attivo e funzionante, vi farò sapere, grazie per il vostro aiuto.
 
SGarnov:
Vi farò sapere cosa succede. grazie per l'aiuto.

Qualcuno può spiegare la ragione di questo comportamento?

Apro un ordine

2021.07.29 18:53:57.436 '60744458': order was opened : #1639674290 sell 0.01 USDJPY at 109.519 sl: 0.000 tp: 0.000

allora l'Expert Advisor lo modifica

2021.07.29 18:53:57.647 '60744458': modify order #1639674290 sell 0.01 USDJPY at 109.519 sl: 0.000 tp: 0.000 -> sl: 109.919 tp: 108.719

e poi succede questa merda

2021.07.29 18:53:58.313 '60744458': order #1639674290 sell 0.01 USDJPY closing at 0.000 failed [Off quotes]
2021.07.29 18:53:57.647 '60744458': close order #1639674290 sell 0.01 USDJPY at 109.519 sl: 0.000 tp: 0.000 at price 0.000

La cosa interessante è che accade su USDJPY e solo vendere su altre coppie

 
MakarFX:

Qualcuno può spiegare la ragione di questo comportamento?

Apro un ordine

allora l'Expert Advisor lo modifica

e poi succede questa merda

La cosa interessante è che succede solo su USDJPY e tutto va bene sugli altri

Se vuoi capire qualcosa, devi imparare come ottenere il massimo di informazioni utili in cicli minimi...

 
Alexey Viktorov:

Per capire qualcosa, impara a tirare fuori le informazioni più utili nel minor numero di cicli...

È bene parlare quando si sa cosa fare...

aiuto con consigli su come "ottenere il massimo dalle informazioni utili"

 
MakarFX:

Qualcuno può spiegare la ragione di questo comportamento?

Apro un ordine

allora l'Expert Advisor lo modifica

e poi succede questa merda

La cosa interessante è che accade su USDJPY e solo vendere su altre coppie

È così che funziona il consulente di cui hai scritto il codice?
 
SGarnov:
È così che funziona l'EA di cui hai scritto il codice?
Va bene, il problema era il terminale.