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

 
Alexey Viktorov:

Eu estava falando de meu próprio chip de memória. :)))

Sobre não se lembrar de tais insignificâncias, que podem ser facilmente reverificados ao escrever o código, esclarecidos, feitos conforme necessário e esquecidos novamente.

Estou vendo! :)
 
Artyom Trishkin:
Tenho notado que as pessoas muitas vezes pedem a função de arrasto ou breakeven. Esbocei uma função para desenho de parada no nível de breakeven e posição de parada móvel de acordo com o valor de algum indicador, que desenha suas linhas no gráfico de preços (МАшашка ou parabólico, por exemplo) passado para a função.

#property strict // в самое начало кода вашей программы (если нету там ещё)


// Функцию - за пределы остальных функций программы
//+------------------------------------------------------------------+
//| Трейлинг по значению + перенос стопа на уровень безубытка        |
//+------------------------------------------------------------------+
void TrailingByLevel(string symbol_name,           // Имя символа
                     int magic_number,             // Magic ордера
                     double level_of_trail,        // Уровень, на который ставим стоп (например МА или Parabolic SAR)
                     int trailing_start,           // Профит в пунктах для старта трала
                     int trailing_step,            // Шаг трала в пунктах
                     int trailing_stop,            // Отступ стоплосс от уровня МА или SAR в пунктах
                     int profit_for_breakeven=15,  // Профит в пунктах для переноса стопа в безубыток
                     int breakeven_level=5,        // Уровень безубытка в пунктах
                     bool use_trail=true,          // Флаг использования трала
                     bool use_breakeven=false      // Флаг использования безубытка
                     )
   {
   int lv=StopLevel(symbol_name)+1;                // Получаем значение Stop Level по символу + 1 пункт (из отдельной функции)
   for(int i=OrdersTotal()-1; i>=0; i--) {
      if(OrderSelect(i,SELECT_BY_POS)) {
         if(OrderMagicNumber()!=magic_number)   continue;         //Если Магик не наш - идем к следующему ордеру
         if(OrderSymbol()!=symbol_name)         continue;         //Если Символ не наш - идем к следующему ордеру
         //--- покупки
         if(OrderType()==OP_BUY) {
            int    digits=(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS);
            double point=(SymbolInfoDouble(symbol_name,SYMBOL_POINT));
            double pb=SymbolInfoDouble(symbol_name,SYMBOL_BID);
            double profit=pb-OrderOpenPrice();                    // Профит позиции в цене (без комиссий и свопов)
            //--- безубыток
            if(use_breakeven) {
               //--- если профит в цене больше заданного
               if(profit>=profit_for_breakeven*point) {
                  int err=ERR_NO_ERROR;
                  double sl=NormalizeDouble(OrderOpenPrice()+breakeven_level*point,digits);
                  if(pb-lv*point>sl && OrderStopLoss()<sl) {
                     // Сюда вписываем свою функцию модификации. Можно конечно и стандартной обойтись:
                     // OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),OrderExpiration(),clrModify); ...
                     // ... но в ней не предусмотрены проверки кодов возврата торгового сервера и их обработка
                     //ModifyOrder(-1,sl,-1,err);
                     }
                  if(err==ERR_MARKET_CLOSED) return;
                  }
               }
            //--- трал
            if(use_trail) {
               //--- если профит в пунктах больше заданного, или изначально задан меньше ноля
               if(profit>=trailing_start*point || trailing_start==EMPTY) {
                  int err=ERR_NO_ERROR;
                  double sl=NormalizeDouble(level_of_trail-trailing_stop*point,digits);  // вычисляем новый уровень стоплосс по значению, переданному в функцию
                  //--- Если новое значение СЛ не ближе Stop Level и если новое положение СЛ больше старого+шаг СЛ, то модифицируем стоп позиции
                  if(pb-lv*point>sl && OrderStopLoss()+trailing_step*point<sl) {
                     // Сюда вписываем свою функцию модификации. Можно конечно и стандартной обойтись:
                     // OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),OrderExpiration(),clrModify); ...
                     // ... но в ней не предусмотрены проверки кодов возврата торгового сервера и их обработка
                     //ModifyOrder(-1,sl,-1,err);
                     }
                  if(err==ERR_MARKET_CLOSED) return;
                  }
               }
            }

         //--- Продажи
         if(OrderType()==OP_SELL) {
            int    digits=(int)SymbolInfoInteger(symbol_name,SYMBOL_DIGITS);
            double point=(SymbolInfoDouble(symbol_name,SYMBOL_POINT));
            double pa=SymbolInfoDouble(symbol_name,SYMBOL_ASK);
            double profit=OrderOpenPrice()-pa;                    // Профит позиции в цене (без комиссий и свопов)
            //--- безубыток
            if(use_breakeven) {
               //--- если профит в цене больше заданного
               if(profit>=profit_for_breakeven*point) {
                  int err=ERR_NO_ERROR;
                  double sl=NormalizeDouble(OrderOpenPrice()-breakeven_level*point,digits);
                  if(pa+lv*point<sl && (OrderStopLoss()>sl || OrderStopLoss()==0)) {
                     // Сюда вписываем свою функцию модификации. Можно конечно и стандартной обойтись:
                     // OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),OrderExpiration(),clrModify); ...
                     // ... но в ней не предусмотрены проверки кодов возврата торгового сервера и их обработка
                     //ModifyOrder(-1,sl,-1,err);
                     }
                  if(err==ERR_MARKET_CLOSED) break;
                  }
               }
            //--- трал
            if(use_trail) {
               //--- если профит в пунктах больше заданного, или изначально задан меньше ноля
               if(profit>=trailing_start*point || trailing_start==EMPTY) {
                  int err=ERR_NO_ERROR;
                  double sl=NormalizeDouble(level_of_trail+trailing_stop*point,digits);  // вычисляем новый уровень стоплосс по значению, переданному в функцию
                  //--- Если новое значение СЛ не ближе Stop Level и если новое положение СЛ больше старого+шаг СЛ, то модифицируем стоп позиции
                  if(pa+lv*point<sl && (OrderStopLoss()-trailing_step*point>sl || OrderStopLoss()==0)) {
                     // Сюда вписываем свою функцию модификации. Можно конечно и стандартной обойтись:
                     // OrderModify(OrderTicket(),OrderOpenPrice(),sl,OrderTakeProfit(),OrderExpiration(),clrModify); ...
                     // ... но в ней не предусмотрены проверки кодов возврата торгового сервера и их обработка
                     //ModifyOrder(-1,sl,-1,err);
                     }
                  if(err==ERR_MARKET_CLOSED) break;
                  }
               }
            }
         }
      }
}
//+------------------------------------------------------------------+
int StopLevel(string symbol_name) {
   int sp=(int)SymbolInfoInteger(symbol_name,SYMBOL_SPREAD);
   int lv=(int)SymbolInfoInteger(symbol_name,SYMBOL_TRADE_STOPS_LEVEL);
   return((lv==0)?sp*2:lv);
   }
//+------------------------------------------------------------------+
Em geral, se alguma coisa - pergunte. Ou correto.

Você pode me ajudar a refinar minha EA ? Eu tenho um EA que faz paradas, mas não sabe como arrastar para parar as perdas. Eu não entendo nada, então espero a ajuda de um especialista.

Arquivos anexados:
 

Você precisa de uma função para determinar o peso de um elemento de uma matriz. Quanto maior for o número de outros elementos próximos (e mais próximos) de um determinado elemento, maior será o seu peso. Talvez tal função já exista. Algo como determinar o peso de um elemento em uma amostra através da concentração de elementos na amostra. Obrigado.

 

Olá! Não consigo entender por que no testador MQL4 ele passaporuma iteração e depois pára? A TimeCurrent() não está sendo atualizada? Como faço para atualizá-lo? Quero que minha EA trabalhe não por carrapatos, mas a cada segundo, ou melhor, 5 vezes por segundo.

  int start()                                     // Спец. функция start
  {
    while(!IsStopped())
     {
      RefreshRates();
      if(RefreshRates()==true||MyTimer(1))
        {
         код советника
        }  
     }
    return(0);
  }


bool MyTimer(int Delay) //функция для работы советника по заданому интервалу времени, а не по тикам
{
  RefreshRates();
  static datetime Time1, Time2;
  bool Result = False;
  
  if(MathMod(TimeSeconds(TimeCurrent()), Delay) == 0.0)
  {
    Time1 = TimeCurrent();
    if(Time1 != Time2)
    {  
      Time2 = Time1;
      Result = True;
    }
  }
  return(Result);
}
 
Jenya77769:

Olá! Não consigo entender por que no testador MQL4 ele passaporuma iteração e depois pára? A TimeCurrent() não está sendo atualizada? Como faço para atualizá-lo? Você precisa de um EA com várias moedas para trabalhar a cada segundo, ou melhor, 5 vezes por segundo, em vez de trabalhar com carrapatos.

Como você administra esta EA ? ou seja, a partir do diretório de especialistas ?

A função start() (o nome antigo, o moderno OnTick) é executada para cada tick, ou seja, deve ser executada após o final do tick. E você o tem em um loop ?

 
Maxim Kuznetsov:

você está administrando isso como consultor ou o quê? ou seja, do diretório de especialistas?

A função start() em EAs (nome antigo, OnTick moderno) funciona em cada tick, ou seja, deve terminar quando o tick estiver terminado. E você o tem em um loop ?

Aqui no tutorial é permitido e há um exemplo com uma função de "início" em loop

https://book.mql4.com/ru/special/index

О сложных программах - Учебник по MQL4
О сложных программах - Учебник по MQL4
  • book.mql4.com
О сложных программах - Учебник по MQL4
 
Jenya77769: Aqui no livro didático isto é permitido e há um exemplo com uma função de partida em loop

É claro que você pode fazer um loop it, é claro. Mas no próximo TIC é desejável deixar ir. Caso contrário, o TIC será perdido. Você precisa disso?

 
LRA:

Para loop, é claro, é possível. Mas até o próximo TIC é desejável que seja lançado. Caso contrário, o TIC será perdido. É necessário?


Por que está perdido? A nova informação do tick pode ser recuperada comRefreshRates(); bem no loop infinito

 
Jenya77769: As informações sobre o novo tick podem ser obtidas usando oRefreshRates(); função bem no loop infinito

O RefreshRates(); função só verifica. Retorna verdadeiro se os dados foram atualizados. Você pode fazer isso enquanto(!RefreshRates(); - esperando o tick

 
LRA:

O RefreshRates(); função só verifica. Ele retorna verdadeiro se os dados foram atualizados. Você pode fazer isso enquanto(!RefreshRates()); - esperando por um tick

Refresca (não confunda as pessoas) e devolve a bandeira se a atualização for bem sucedida ou falhar.

Você pode passar sem ele se obtiver dados usando SymbolInfoDouble(), SymbolInfoTick()

Razão: