Quaisquer perguntas de recém-chegados sobre MQL4 e MQL5, ajuda e discussão sobre algoritmos e códigos - página 1546

 
MakarFX:
Você tem um EA que suporta pedidos feitos manualmente?
Sim. Eu coloco os pedidos pendentes manualmente ou apenas abro um negócio, e então o Expert Advisor trabalha.
 
SGarnov:
Tentei inseri-lo, mas não o compila. O código inteiro, se necessário, colocarei uma captura de tela da compilação. Acho que pode haver outro problema, meu TP é definido em relação ao STOP por coeficiente (variável externa), talvez ele possa ser alterado para ajuste manual e será mais fácil para a EA adicionar?

A função

  double GetPointLastLoss(){
            datetime t=0;
            double result=0,p=0,tp=0;
            int i=OrdersHistoryTotal(),magic=0;
         for(int pos=0; pos<i; pos++)
         {
          if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
         {
          if((OrderSymbol()==_Symbol) && (OrderMagicNumber()==magic))
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(t<OrderCloseTime())
                 {t=OrderCloseTime(); p=OrderProfit(); tp=OrderType();
                  if(tp==OP_BUY&&p<0)
                    {
                     result=OrderOpenPrice()-OrderClosePrice();
                    } else {result=0;}
                  if(tp==OP_SELL&&p<0)
                    {
                     result=OrderClosePrice()-OrderOpenPrice();
                    } else {result=0;}
                 }
              }
           }
        }
     }
   return(result);
  }

do escopo global. magic=0 para compilação.

magic=0

	          
 
Galim_V:

A função

removido do escopo global. magic=0 para compilação.

Removido, sem erros de compilação, apenas 1 aviso aparece na terceira linha de função na coluna tp=0 com audição na variável externa int tp=0. Eu não entendo bem o que o programador não gosta. Todo código está anexado, se não for difícil corrigi-lo, a verdade está em algum lugar próximo.

input int takeProfitC = 2;// Коэффициент Take Profit
input int stop_loss = 100;//Уровень Stop Loss
input int stop_count = 2;//Количество Stop Loss
input double lots = 0.01;//Лоты
input int slippage = 30;//Проскальзывание
input int datePeriod = 48;// Время удержания при SL


int tp = 0;
int tpc = 0;
double tp_price_old = 777;
int stopLossCount = 0;
datetime startOrder = 0;
int pending_ticket = 0;
int lastMagic = 0;
bool isLimitOn = false;
bool isStart = True;
datetime startTime = 0;
bool isFinal = false;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
//
   //OrderSend(Symbol(), OP_SELL, 0.01, 0.76228, 300, 0, 0);
   //OrderSend(Symbol(), OP_SELLSTOP, 0.01, 0.77057, 300, 0, 0);
   //OrderSend(Symbol(), OP_BUYSTOP, 0.01, 0.76928, 300, 0, 0);
   tp = stop_loss * takeProfitC;
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
//--

}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {
//---
//Comment("StopCount: " + stopLossCount + "\n" + "CurrentStopC: " + stop_count);
   for(int i = OrdersTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)) {
         if(OrderSymbol() == Symbol()) {
         int magic = OrderMagicNumber();
            if((OrderType() == OP_BUY || OrderType() == OP_SELL) && OrderOpenTime()) {
               int ticket = OrderTicket();
               if(!findPending(ticket)) {
                  if(OrderSelect(ticket, SELECT_BY_TICKET) && (((TimeCurrent() <= (startTime + datePeriod * 3600))) || isStart)) {
                     if(OrderType() == OP_BUY) {
                        double sl_price = NormalizeDouble(OrderOpenPrice() - Point() * MathMax(stop_loss, MarketInfo(Symbol(), MODE_STOPLEVEL)), Digits);
                        double tp_price = NormalizeDouble((OrderOpenPrice() + Point() * (tp)), Digits);
                        if(!OrderModify(OrderTicket(), OrderOpenPrice(), sl_price, tp_price, OrderExpiration())) {
                           Print("Ошибка модификации ордера:", GetLastError());
                        } else {
                           if(stopLossCount < stop_count && tp_price != tp_price_old){
                              pending_ticket = OrderSend(Symbol(), OP_SELLSTOP, lots, sl_price, slippage, 0, 0, NULL, OrderTicket());
                              lastMagic = ticket;
                              isLimitOn = true;
                              if(isStart){
                                 startTime = TimeCurrent();
                                 isStart = false;
                              }
                              tp_price_old = tp_price;
                              stopLossCount++;                         
                           }
                        }
                     } else if(OrderType() == OP_SELL) {
                        double sl_price = NormalizeDouble(OrderOpenPrice() + Point() * MathMax(stop_loss, MarketInfo(Symbol(), MODE_STOPLEVEL)), Digits);
                        double tp_price = NormalizeDouble((OrderOpenPrice() - Point() * (tp)), Digits);
                        if(!OrderModify(OrderTicket(), OrderOpenPrice(), sl_price, tp_price, OrderExpiration())) {
                           Print("Ошибка модификации ордера:", GetLastError());
                        } else {
                          if(stopLossCount < stop_count && tp_price != tp_price_old){
                              pending_ticket = OrderSend(Symbol(), OP_BUYSTOP, lots, sl_price, slippage, 0, 0, NULL, OrderTicket());
                              lastMagic = ticket;
                              isLimitOn = true;
                              if(isStart){
                                 startTime = TimeCurrent();
                                 isStart = false;
                              }
                              stopLossCount++;
                              tp_price_old = tp_price;  
                          }
                        }
                     }
                  }
               }
         }
         if(startTime > 0 && (TimeCurrent() >= (startTime + datePeriod * 3600))){
            deletePending(lastMagic);
            isFinal = true;
         }
            
         if(lastMagic != 0 && !IsSell() && !IsBuy() && magic == lastMagic) {
            tpc = 0;
            startTime = 0;
            stopLossCount = 0;
            deletePending(lastMagic);
            isStart = true;
            }
         }
     }
   }
   if((startTime > 0 || isFinal) && !IsSell() && !IsBuy()){
            tpc = 0;
            startTime = 0;
            stopLossCount = 0;
            isStart = true;
            isFinal = false;
   }
}
//+----------------------------------------------------------------------------+
//|  Возвращает пункты убытка последнего закрытого ордера в пунктах            |
//+----------------------------------------------------------------------------+
double GetPointLastLoss(){
            datetime t=0;
            double result=0,p=0,tp=0;
            int i=OrdersHistoryTotal(),magic=0;
         for(int pos=0; pos<i; pos++)
         {
          if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
         {
          if((OrderSymbol()==_Symbol) && (OrderMagicNumber()==magic))
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(t<OrderCloseTime())
                 {t=OrderCloseTime(); p=OrderProfit(); tp=OrderType();
                  if(tp==OP_BUY&&p<0)
                    {
                     result=OrderOpenPrice()-OrderClosePrice();
                    } else {result=0;}
                  if(tp==OP_SELL&&p<0)
                    {
                     result=OrderClosePrice()-OrderOpenPrice();
                    } else {result=0;}
                 }
              }
           }
        }
     }
   return(result);
  }                                                                
//+------------------------------------------------------------------+
bool findPending(int ticket) {
   for(int i = OrdersTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)) {
         if(OrderMagicNumber() == ticket) {
            return true;
         }
      }
   }

   for(int i = OrdersHistoryTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
         if(OrderMagicNumber() == ticket) {
            return true;
         }
      }
   }
   return false;
}
//+------------------------------------------------------------------+
void deletePending(int magic) {
   for(int i = OrdersTotal() - 1; i >= 0; i--) {
      if(OrderSelect(i, SELECT_BY_POS)) {
         if(OrderMagicNumber() == magic) {
            if(OrderType() != OP_BUY && OrderType() != OP_SELL) {
               if(!OrderDelete(OrderTicket())) {
                  Print("Ошибка удаления отложеного одера: ", GetLastError());
               }
            }
            break;
         }
      }
   }
}
//+------------------------------------------------------------------+
bool IsSell()
{
   int count = 0;
   for (int trade = OrdersTotal () -1; trade >= 0; trade--)
   {
      if (OrderSelect (trade, SELECT_BY_POS, MODE_TRADES) 
          && OrderSymbol() == Symbol()
          && OrderType() == OP_SELL)
      {
         count++;
      }
      
   }
   if (count == 0)
      return false;
   else
      return true;
}
//+------------------------------------------------------------------+
bool IsBuy()
{
   int count = 0;
   for (int trade = OrdersTotal () -1; trade >= 0; trade--)
   {
      if (OrderSelect (trade, SELECT_BY_POS, MODE_TRADES) 
          && OrderSymbol() == Symbol()
          && OrderType() == OP_BUY)
      {
         count++;
      }
      
   }
   if (count == 0)
      return false;
   else
      return true;
}
 
SGarnov:

Removido, sem erros de compilação, apenas 1 aviso aparece na terceira linha de função na coluna tp=0 com audição na variável externa int tp=0. Eu não entendo bem o que o programador não gosta. Todos os códigos anexados, se não for difícil corrigir, a verdade está em algum lugar próximo.

É assim que parece

//+------------------------------------------------------------------+
//|                                                   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   = 100;   // Уровень Stop Loss
input double   O_Lots   = 0.01;  //Лоты
input int      Input4;
input int      Input5;
input int      Input6;

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;
   s_loss   = MathMax(S_Loss, MarketInfo(Symbol(), MODE_STOPLEVEL));
   // Проверяем наличие ордеров BUY
   if(CountOrders(_Symbol, 0)>0)
     {
      // Проверяем последний закрытый ордер SELL на наличие убытка в пунктах
      if(GetPointLastLoss(1)>0)
        {
         // Если убыток есть, то добавляем пункты убытка
         sl_price = NormalizeDouble(Point() * s_loss, Digits);
         tp_price = NormalizeDouble(GetPointLastLoss(1)+Point() * t_profit, Digits);
         ModifyOrder(_Symbol, sl_price, tp_price);
        }
      else
        {
         // Если убытка нет
         sl_price = NormalizeDouble(Point() * s_loss, Digits);
         tp_price = NormalizeDouble(Point() * t_profit, Digits);
         ModifyOrder(_Symbol, sl_price, tp_price);
        }
     }
   // Проверяем наличие ордеров SELL
   if(CountOrders(_Symbol, 1)>0)
     {
      // Проверяем последний закрытый ордер BUY на наличие убытка в пунктах
      if(GetPointLastLoss(0)>0)
        {
         // Если убыток есть, то добавляем пункты убытка
         sl_price = NormalizeDouble(Point() * s_loss, Digits);
         tp_price = NormalizeDouble(GetPointLastLoss(0)+Point() * t_profit, Digits);
         ModifyOrder(_Symbol, sl_price, tp_price);
        }
      else
        {
         // Если убытка нет
         sl_price = NormalizeDouble(Point() * s_loss, Digits);
         tp_price = NormalizeDouble(Point() * t_profit, Digits);
         ModifyOrder(_Symbol, sl_price, tp_price);
        }
     }
  }
//+--------------------------------------------------------------------------------------------------------------------+
//| Подсчет ордеров по типу                                                                                            |
//+--------------------------------------------------------------------------------------------------------------------+
//|  0 - ордера типа BUY          1 - ордера типа SELL                                                                 |
//|  2 - ордера типа BUYLIMIT     3 - ордера типа SELLLIMIT                                                            |
//|  4 - ордера типа BUYSTOP      5 - ордера типа SELLSTOP                                                             |
//|  6 - ордера типа Balance     -1 - Все типы ордеров                                                                 |
//+--------------------------------------------------------------------------------------------------------------------+
int CountOrders(string symb="", int or_ty=-1) 
  {
   int cnt=0;
   if(symb=="0") symb=_Symbol;
   for(int pos=OrdersTotal()-1;pos>=0;pos--)
     {
      if(OrderSelect(pos,SELECT_BY_POS)==true)
        {
         if(OrderSymbol()==symb || symb=="")
           {
            if(or_ty<0 || or_ty==OrderType()) cnt++;
           }
        }
     }
   return(cnt);
  }
//+----------------------------------------------------------------------------+
//| Модификация ордера                                                         |
//+----------------------------------------------------------------------------+
//|    sl - ценовой уровень стопа                                              |
//|    tp - ценовой уровень тейка                                              |
//+----------------------------------------------------------------------------+
void ModifyOrder(string symb="", double sl=0, double tp=0)
  {
   if(symb=="0") symb=_Symbol;
   for(int pos=OrdersTotal()-1;pos>=0;pos--)
     {
      if(OrderSelect(pos,SELECT_BY_POS)==true)
        {
         if(OrderSymbol()==symb || symb=="")
           {
            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                                                  |
//+----------------------------------------------------------------------------+
double GetPointLastLoss( int or_ty=-1)
  {
   datetime t=0;
   double result=0,p=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(t<OrderCloseTime())
                 {t=OrderCloseTime(); p=OrderProfit(); or_ty=OrderType();
                  if(or_ty==OP_BUY&&p<0)
                    {
                     result=OrderOpenPrice()-OrderClosePrice();
                    } else {result=0;}
                  if(or_ty==OP_SELL&&p<0)
                    {
                     result=OrderClosePrice()-OrderOpenPrice();
                    } else {result=0;}
                 }
              }
           }
        }
     }
   return(result);
  }
//+------------------------------------------------------------------+

Você não precisa de magia alguma em seu caso

 
MakarFX:

É mais ou menos isso mesmo.

No seu caso, a magia não é de todo necessária.

Obrigada, testará e apresentará um relatório. Espero que funcione como o meu, mas acrescenta uma parada (se for acionada) ao novo take.

Para que são necessários os parâmetros externos Input4; 5; 6?

 
SGarnov:
Obrigado, vou testá-la e apresentar um relatório. Espero que funcione como o meu, mas acrescenta uma parada (se ela for acionada) a um novo take.

Aqui só há modificações. Não há nenhuma supressão ou inversão de ordem.

Se você descrever o que a EA deve fazer, eu tentarei ajudar.

 
SGarnov:

Para que são necessários os parâmetros externos Input4; 5; 6?

Eu esqueci de apagar
 
MakarFX:

Se você descrever o que a EA deve fazer, eu tentarei ajudar.

Eu coloco uma ordem de compra pendente - a EA está funcionando - a ordem pendente aciona - a EA "vê" isto e coloca um stop loss nesta ordem em aberto:

stop loss (parâmetro externo é definido em configurações);

Take Profit(parâmetro externo é definido nas configurações usando a proporção de, por exemplo, 1 para 2);

ordem de venda pendente no nível de stop loss.

Possíveis cenários.

Variante 1.

A) Se o preço chegar à Takei - o Consultor Especialista remove a Stop Loss e uma ordem de Venda pendente;

Variante 2.

B) Se a parada de perda for acionada e a EA "passar à história", então:

Uma ordem de venda é aberta e o Expert Advisor re-posiciona esta ordem:

stop loss (parâmetro externo é definido em configurações)

Tire Lucro + um Stop Loss acionado do histórico;

uma ordem de compra pendente no nível de stop loss.

O preço atinge o take - o Expert Advisor remove o stop loss e a ordem de compra pendente.

E vice versa, se o trabalho começar com uma ordem de venda pendente.

E assim o assessor trabalha até parar seu trabalho com o parâmetro externo Stop Loss Number (no meu caso é 2, significa que a variante 2 será repetida 3 vezes e o assessor deixará de trabalhar no futuro e apagará todas as ordens pendentes, a primeira parada não é levada em conta).

Se o takei não for alcançado e a variante 2 for repetida, então 2 paradas são adicionadas ao takei e assim por diante, depende do parâmetro externo definido"Stop Loss count".


O código, que coloquei funciona como deveria, exceto pelo problema, que descrevi (não vê no histórico 1 parada ou 2 paradas, o que deveria acrescentar ao take).

Assim.

 
SGarnov:

Eu coloquei uma ordem de compra pendente - a EA está funcionando - a ordem pendente aciona - a EA "vê" isto e coloca um stop loss nesta ordem em aberto:

stop loss (parâmetro externo é definido em configurações);

Take Profit(parâmetro externo é definido nas configurações usando a proporção de, por exemplo, 1 para 2);

ordem de venda pendente no nível de stop loss.

Possíveis cenários.

Variante 1.

A) Se o preço chegar à Takei - o Consultor Especialista remove a Stop Loss e uma ordem de Venda pendente;

Variante 2.

B) Se a parada de perda for acionada e a EA "passar à história", então:

Uma ordem de venda é aberta e o Expert Advisor re-posiciona esta ordem:

stop loss (parâmetro externo é definido em configurações);

Tire Lucro + um Stop Loss acionado do histórico;

uma ordem de compra pendente no nível de stop loss.

O preço atinge o take - o Expert Advisor remove o stop loss e a ordem de compra pendente.

E vice versa, se o trabalho começar com uma ordem de venda pendente.

E assim o assessor trabalha até parar seu trabalho com o parâmetro externo Stop Loss Number (no meu caso é 2, significa que a variante 2 será repetida 3 vezes e o assessor deixará de trabalhar no futuro e apagará todas as ordens pendentes, a primeira parada não é levada em conta).

Se o takei não for alcançado e a variante 2 for repetida, então 2 paradas são adicionadas ao takei e assim por diante, depende do parâmetro externo definido"Stop Loss count".


O código, que coloquei funciona como deveria, exceto pelo problema, que descrevi (não vê no histórico 1 parada ou 2 paradas, o que deveria acrescentar ao take).

É assim.

"Número de Stop Losses" - em uma fila ou para o dia atual?

 
MakarFX:

"Número de Stop Losses" - em uma fila ou para o dia atual?

O número de paradas consecutivas em um par de moedas.

A fim de analisar o histórico, o Expert Advisor inicialmente rotula as ordens com suas identificações, mas não as encontra no histórico, pensei que a OrderMagikNumber() irá procurá-las. Talvez por causa do fato de que, na história, a EA pára de "vê-los" a partir de diferentes pares de moedas?

colocar a fonte novamente? Tudo o que ele precisa fazer é corrigir a "busca de stop trades da história e fazer com que ela se acrescente ao recém colocado take".
Razão: