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

 
MakarFX:

É bom falar quando se sabe o que fazer...

me ajude com conselhos sobre como "obter o máximo de informações úteis que puder".

Eu disse tudo muito claramente. Bem, para você pessoalmente, deixe-me perguntar.

Aqui estão duas funções e ambas passam por ordens históricas

//+------------------------------------------------------------------+
//|  Возвращает пункты убытка закрытых ордеров с начала цикла        |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|  Возвращает кол-во серии убыточных ордеров                       |
//+------------------------------------------------------------------+

Dois ciclos com as mesmas ordens. Você não pode obter tudo que essas funções retornam em um ciclo, certo?

 

Olá!

Estou tentando acrescentar uma inversão de marcha à coruja. Estou fazendo isso conforme descrito nas instruções: https://www.mql5.com/ru/forum/128200

Não tenho erros na compilação, mas meu testador não trabalha com o flip.

O registro dá um erro:

2021.07.29 20:06:34.316 2015.01.08 22:10:00 SMA com código AUDUSD,M5: OrderSend error 130

2021.07.29 20:06:34.316 2015.01.08 22:05:45 SMA com reversão via AUDUSD,M5: OrderSend error 4107

2021.07.29 20:06:34.316 2015.01.08 22:05:45 SMA com flip via AUDUSD,M5: stoploss inválido para a função OrderSend

você pode me dizer qual é o problema aqui?

Eu mesmo penso que as variáveis especificadas em

int InversOrderSend (símbolo de string,int cmd,volume duplo,preço duplo,int slippage,stoploss duplo,takeprofit duplo,string comment,int magic=0,datetime expiration=0,color arrow_color=CLR_NONE)

Não estão relacionados com o código principal.

Já tentei em diferentes terminais, 4 e 5 sinais.

aqui está o código completo:

//+-----------------------------------------------------------------------------------------------+
//|                                                                     Simple Moving Average.mq4 |
//|                                                                 Copyright 2016, Andrey Minaev |
//|                                                     https://www.mql5.com/ru/users/id.scorpion |
//+-----------------------------------------------------------------------------------------------+
#property copyright "Copyright 2016, Andrey Minaev"
#property link      "https://www.mql5.com/ru/users/id.scorpion"
#property version   "1.00"
#property strict

// Параметры советника
extern string sParametersEA = "";     // Параметры советника
extern double dLots         = 0.01;   // Количество лотов
extern int    iStopLoss     = 30;     // Уровень убытка (в пунктах)
extern int    iTakeProfit   = 30;     // Уровень прибыли (в пунктах)
extern int    iSlippage     = 3;      // Проскальзование (в пунктах)
extern int    iMagic        = 1;      // Индентификатор советника
extern double K_Martin     = 2.0;
extern int    OrdersClose  = 5;
extern int    DigitsLot    = 2;
extern int    ReversOrder  = 0;             // Переворот сделок 1-да; 0-нет;
// Параметры индикатора
extern string sParametersMA = "";     // Параметры индикатора
extern int    iPeriodMA     = 14;     // Период усреднения
// Глобальные переменные
double dMA;
//+-----------------------------------------------------------------------------------------------+
int OnInit()
  {
// Если брокер использует 3 или 5 знаков после запятой, то умножаем на 10
   if(Digits == 3 || Digits == 5)
     {
      iStopLoss   *= 10;
      iTakeProfit *= 10;
      iSlippage   *= 10;
     }

   return(INIT_SUCCEEDED);
  }
//+-----------------------------------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

  }
//+-----------------------------------------------------------------------------------------------+
void OnTick()
  {
// Получим значение индикатора
   dMA = iMA(Symbol(), 0, iPeriodMA, 0, MODE_SMA, PRICE_CLOSE, 0);

// Если нет открытых ордеров, то входим в условие
   if(bCheckOrders() == true)
     {
      // Если появился сигнал на покупку, то откроем ордер на покупку
      if(bSignalBuy() == true)
         vOrderOpenBuy();

      // Если появился сигнал на продажу, то откроем ордер на продажу
      if(bSignalSell() == true)
         vOrderOpenSell();
     }
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция проверки открытых оредров |
//+-----------------------------------------------------------------------------------------------+
bool bCheckOrders()
  {
// Переберем в цикле ордера, для проверки открытых ордеров данным советником
   for(int i = 0; i <= OrdersTotal(); i++)
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == iMagic)
            return(false);

   return(true);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на покупку |
//+-----------------------------------------------------------------------------------------------+
bool bSignalBuy()
  {
   if(dMA > Open[1] && dMA < Close[1])
      return(true);

   return(false);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на продажу |
//+-----------------------------------------------------------------------------------------------+
bool bSignalSell()
  {
   if(dMA < Open[1] && dMA > Close[1])
      return(true);

   return(false);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                            Функция открытия ордера на покупку |
//+-----------------------------------------------------------------------------------------------+
void vOrderOpenBuy()
  {
   int iOTi = 0;   // Тикет ордера

   iOTi = ReversOrderSend(Symbol(), OP_BUY, LOT(), Ask, iSlippage, 0, 0, "", iMagic, 0, clrNONE);

// Проверим открылся ли ордер
   if(iOTi > 0)
      // Есди да, то выставим уровни убытка и прибыли
      vOrderModify(iOTi);
   else
      // Если нет, то получим ошибку
      vError(GetLastError());
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                            Функция открытия ордера на продажу |
//+-----------------------------------------------------------------------------------------------+
void vOrderOpenSell()
  {
   int iOTi = 0;   // Тикет ордера

   iOTi = ReversOrderSend(Symbol(), OP_SELL, LOT(), Bid, iSlippage, 0, 0, "", iMagic, 0, clrNONE);

// Проверим открылся ли ордер
   if(iOTi > 0)
      // Есди да, то выставим уровни убытка и прибыли
      vOrderModify(iOTi);
   else
      // Если нет, то получим ошибку
      vError(GetLastError());
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                                    Функция модификации ордера |
//+-----------------------------------------------------------------------------------------------+
void vOrderModify(int iOTi)
  {
   int    iOTy = -1;   // Тип ордера
   double dOOP = 0;    // Цена открытия ордера
   double dOSL = 0;    // Стоп Лосс
   int    iMag = 0;    // Идентификатор советника

   double dSL = 0;     // Уровень убытка
   double dTP = 0;     // Уровень прибыли

// Выберем по тикету открытый ордер, получим некоторые значения
   if(OrderSelect(iOTi, SELECT_BY_TICKET, MODE_TRADES))
     {
      iOTy = OrderType();
      dOOP = OrderOpenPrice();
      dOSL = OrderStopLoss();
      iMag = OrderMagicNumber();
     }

// Если ордер открыл данный советник, то входим в условие
   if(OrderSymbol() == Symbol() && OrderMagicNumber() == iMag)
     {
      // Если Стоп Лосс текущего ордера равен нулю, то модифицируем ордер
      if(dOSL == 0)
        {
         if(iOTy == OP_BUY)
           {
            dSL = NormalizeDouble(dOOP - iStopLoss * Point, Digits);
            dTP = NormalizeDouble(dOOP + iTakeProfit * Point, Digits);

            bool bOM = OrderModify(iOTi, dOOP, dSL, dTP, 0, clrNONE);
           }

         if(iOTy == OP_SELL)
           {
            dSL = NormalizeDouble(dOOP + iStopLoss * Point, Digits);
            dTP = NormalizeDouble(dOOP - iTakeProfit * Point, Digits);

            bool bOM = OrderModify(iOTi, dOOP, dSL, dTP, 0, clrNONE);
           }
        }
     }
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                                      Функция обработки ошибок |
//+-----------------------------------------------------------------------------------------------+
void vError(int iErr)
  {
   switch(iErr)
     {
      case 129:   // Неправильная цена
      case 135:   // Цена изменилась
      case 136:   // Нет цен
      case 138:   // Новые цены
         Sleep(1000);
         RefreshRates();
         break;

      case 137:   // Брокер занят
      case 146:   // Подсистема торговли занята
         Sleep(3000);
         RefreshRates();
         break;
     }
  }
//+-----------------------------------------------------------------------------------------------+

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double LOT()
  {
   int n=0;
   double OL=dLots;
   for(int j = OrdersHistoryTotal()-1; j >= 0; j--)
     {
      if(OrderSelect(j, SELECT_BY_POS,MODE_HISTORY))
        {
         if(OrderSymbol() == Symbol() && OrderMagicNumber() == iMagic)
           {
            if(OrderProfit()<0)
              {
               if(n==0)
                  OL=NormalizeDouble(OrderLots()*K_Martin,DigitsLot);
               n++;
               if(n>=OrdersClose)
                 {
                  Comment("1");
                  return(dLots);
                 }
              }
            else
              {
               if(n==0)
                 {
                  Comment("2");
                  return(dLots);
                 }
               else
                 {
                  Comment("3");
                  return(OL);
                 }
              }
           }
        }
     }
   return(OL);
  }
//------------------------------------------------------------------
int ReversOrderSend (string symbol,int cmd,double volume,double price,int slippage,double stoploss,double takeprofit,string comment,int magic=0,datetime expiration=0,color arrow_color=CLR_NONE)
{
int Ret=0;
double sprd=MarketInfo(symbol,MODE_SPREAD)*Point;
//Print ("----------------------------",sprd);
if (ReversOrder==0) // Открываем ордера без разворота
{
Ret=OrderSend (symbol,cmd,volume,price,slippage,stoploss,takeprofit,comment,magic,expiration,arrow_color);
}
if (ReversOrder==1)
{
///////////////
if (cmd==OP_SELLSTOP) // Переворачиваем ордера OP_SELLSTOP
{
Ret=OrderSend (symbol,OP_BUYLIMIT,volume,price+sprd,slippage,takeprofit-sprd,stoploss-sprd,comment,magic,expiration,arrow_color);
}
if (cmd==OP_BUYSTOP) // Переворачиваем ордера OP_BUYSTOP
{
Ret=OrderSend (symbol,OP_SELLLIMIT,volume,price-sprd,slippage,takeprofit+sprd,stoploss+sprd,comment,magic,expiration,arrow_color);
}
///////////////
if (cmd==OP_SELL) // Переворачиваем ордера OP_SELL
{
Ret=OrderSend (symbol,OP_BUY,volume,price+sprd,slippage,takeprofit-sprd,stoploss-sprd,comment,magic,expiration,arrow_color);
}
if (cmd==OP_BUY) // Переворачиваем ордера OP_BUY
{
Ret=OrderSend (symbol,OP_SELL,volume,price-sprd,slippage,takeprofit+sprd,stoploss+sprd,comment,magic,expiration,arrow_color);
}
//////////////
if (cmd==OP_SELLLIMIT) // Переворачиваем ордера OP_SELLLIMIT
{
Ret=OrderSend (symbol,OP_BUYSTOP,volume,price+sprd,slippage,takeprofit-sprd,stoploss-sprd,comment,magic,expiration,arrow_color);
}
if (cmd==OP_BUYLIMIT) // Переворачиваем ордера OP_BUYLIMIT
{
Ret=OrderSend (symbol,OP_SELLSTOP,volume,price-sprd,slippage,takeprofit+sprd,stoploss+sprd,comment,magic,expiration,arrow_color);
}
}
return (Ret);
}
Предлагаю функцию реверса ордеров, для сливающих советников.
Предлагаю функцию реверса ордеров, для сливающих советников.
  • 2010.08.24
  • www.mql5.com
Помню, поначалу сталкивался с вопросом, как грамотно "перевернуть" ордера с покупки на продажу и наоборот...
 
Alexey Viktorov:

Já o disse com clareza suficiente. Vou lhe fazer uma pergunta pessoal.

Aqui estão duas funções e ambas percorrem o ciclo através de ordens históricas

Há dois loops nas mesmas ordens. Você não pode obter tudo que essas funções retornam em um ciclo, certo?

Alexei, eu já escrevi, eu sei que você é um bom programador!

Mas eu não sou um programador, e o que é "claro o suficiente" para você não é tão claro para mim...

Quanto aos dois loops, para mim"Em um loop obtenho tudo" não é possível, porque eles retornam diferentes tipos de dados.

 
MakarFX:

Alexey, eu já escrevi, eu sei que você é um bom programador!

Mas eu não sou um programador e o que é "claro o suficiente" para você é uma floresta escura para mim...

Quanto aos dois loops, para mim"obter tudo em um loop" não é possível, porque eles retornam tipos de dados diferentes.

Os tipos devolvidos não têm nada a ver com isso. Se houver 2 loops nos mesmos dados com verificações e filtros diferentes, você pode sempre colocar tudo em um loop, mas o código não vai ler tão claro, mas deve funcionar mais rápido) Na fase de depuração eu não faço tudo em um loop. É mais fácil encontrar bugs em diferentes.

 
MakarFX:

Alexey, eu já escrevi, eu sei que você é um bom programador!

Mas eu não sou um programador e o que é "claro o suficiente" para você é uma floresta escura para mim...

Quanto aos dois loops, para mim"Em um loop para obter tudo" não é possível, porque eles retornam diferentes tipos de dados.

Eu tenho duas opções.

  1. Fazer variáveis em nível global. Então, eles estarão disponíveis em todas as funções.
  2. Passe a variável local por referência. Então, se você alterar esta variável, a variável local será alterada.
    /********************Script program start function*******************/
    void OnStart()
     {
      int a = 0;
      f_0(a);
      Print(a);
     }/******************************************************************/
    
    void f_0(int & b)
     {
      b = 100;
     }
    E pode haver até 64 dessas variáveis, Deus me livre de mentir. Se eu estiver errado, alguém pode me corrigir.
  3. Leia a documentação com mais atenção. Está escrito lá em grandes detalhes.
 
MakarFX:

Eu tenho um conflito entre ordens pendentes.

Primeiro resultado. Há um conflito entre pares de moedas e a EA tem um conflito na colocação de pedidos pendentes. Por exemplo, eu coloquei um pedido pendente para EURUSD, a EA seguiu o algoritmo (compra em 1.18901, posição aberta, EA estabeleceu parada em 1.18751, lucro em 1.19051 e pedido de venda em 1.18751) tudo está bem conforme os planos.

Mas agora é hora de abrir um negócio em GBPUSD onde os preços são diferentes e a EA está fazendo tudo certo, exceto para estabelecer uma ordem pendente. Uma ordem de venda em 1,39393 foi acionada e a EA tentou abri-la, fixou uma parada em 1,39633 e tomou 1,39153, mas a ordem de compra em 1,39633 é totalmente duplicada em EURUSD e uma ordem de venda em 1,18751)

Acabo de encontrar outro problema: uma parada em 1.18751 e uma ordem de venda pendente em 1.18901 e take 1.18595 foram abertos em EURUSD. O Expert Advisor não acrescentou a parada acionada, o que está na história.

Estes são os problemas.

 
законопослушный гражданин:

Olá!

Estou tentando dar uma reviravolta nos negócios para a coruja.

O que você quer dizer com isso? Uma certa gama de preços a partir dos quais você compra/vende?

 
SGarnov:

Boa tarde. Ajuda com a EA. De acordo com a estratégia, se uma parada for acionada, então a EA deve acrescentar (o número de pontos) ao próximo set takeaway
da história por ID, mas não o faz por alguma razão.

O que há de errado no código?

if(isLimitOn && OrderSelect(OrderMagicNumber(), SELECT_BY_TICKET, MODE_HISTORY)){
            tpc += stop_loss;
            if(OrderSelect(lastMagic, SELECT_BY_TICKET)){
               if(OrderType() == OP_BUY) {
                  double tp_price = NormalizeDouble((OrderOpenPrice() + Point() * (tp + tpc)), Digits);
                  if(!OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), tp_price, OrderExpiration()))
                     Print("Ошибка модификации ордера:", GetLastError());
               }else if(OrderType() == OP_SELL){
                  double tp_price = NormalizeDouble((OrderOpenPrice() - Point() * (tp + tpc)), Digits);
                  if(!OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), tp_price, OrderExpiration()))
                     Print("Ошибка модификации ордера:", GetLastError());
               }
            }
               
            isLimitOn = false;
         }

Makar apontou corretamente para OrderMagicNumber(), mas entendeu mal o erro. Leia a documentação para a sintaxe desta função... deve ser o índice na lista de pedidos ou o ticket de um determinado pedido, mas não um magik. E OrderTicket() não vai ajudar aqui. Não tente colocá-lo lá.

 
SGarnov:

O que você quer dizer? Uma certa faixa de preços a partir da qual você compra/vende?

O autor do código, como eu o entendo, sugeriu o seguinte:

Se a coruja abre um comércio de compra com stop and take, então seu código abre um comércio de venda ao mesmo tempo no mesmo lugar (levando em conta o spread) também com stop and take em vez de um comércio de compra.

Assim, a lógica de busca de um ponto de entrada da EA não muda, e apenas a direção com propagação leva em conta as mudanças.

isto é exatamente o que eu preciso

 
MakarFX:

Descreva em poucas palavras o que você quer desta EA (a lógica de operação),

Acho que você tem muitas coisas desnecessárias em seu código ou eu não entendo alguma coisa.

as corujas devem abrir negócios de acordo com seu próprio algoritmo

se a parada, a próxima troca com um Martin, e assim por diante até o número de multiplicações que especifiquei (função -OrderClose = .....;).

Mais adiante, se a coruja for desativada junto com o terminal, basta pressionar o botão de "auto-comércio" com outra coruja, então o próximo comércio começará com o lote inicial, não com o último aumentado por um martingale.

Também seria bom anexar-lhe um cronograma, mas esta idéia só agora me ocorreu.

Por exemplo: foi ativado às 10-00 na segunda-feira com o lote inicial, depois foi desligado durante o dia quando algum resultado foi alcançado, e na terça-feira de manhã foi ativado às 10-00 e começou com o lote inicial novamente.

Tudo.

Razão: