Qualquer pergunta de novato, de modo a não desorganizar o fórum. Profissionais, não passem por aqui. Em nenhum lugar sem você - 6. - página 103

 
hoz:

Se for 7,43 e eu não tiver ido para a cama... Então acho que se escreve grail!

Não, não há necessidade de jurar assim :)) Yusuf me deu o Graal. Estou sentado em minhas malas, esperando o maná do céu, estou indo para as Maldivas :)))

 
artmedia70:
Então me mostre o que você fez... Aqui não há telepatas - eles estão de férias.

extern string time1 = "n";// 
extern string time2="m";
extern double lot=0.2;// объявили лот
extern int slippage=2;// объявили макс отклонение от цены





int start()
{
double max;// максимальная цена 6-ти свечей
double min;// минимальная цена 6-ти свечей
int hour1 = TimeHour(StrToTime(time1)); // время часы
int minute1 = TimeMinute(StrToTime(time1));// время минуты


if (hour1 == TimeHour(TimeCurrent()) && minute1 == TimeMinute(TimeCurrent()))// если время подошло то
{
min=Low[iLowest(Symbol(),0,MODE_LOW,6,1)]; // вычисляем минимальную цену последних 6 свечей
max=High[iHighest(Symbol(),0,MODE_HIGH,6,1)]; // вычисляем максимальную цену последних 6 свечей
double volum=max-min;// общий объем локалки последних 6 свечей М5
 int ticket1=-1;
 int ticket2=-1;
if ((volum<=0.0018)==true)// если объем свечей меньше или равно z пунктов 

if (ticket1<0)
{ 
OrderSend ( Symbol (), OP_BUYSTOP, lot,max+Point,3,min-Point,max+0.0022, NULL,0,time2, Red);
Alert(GetLastError());
}
if(ticket2<0)
{
OrderSend( Symbol (), OP_SELLSTOP, lot,min-Point,3,max+Point,min-0.0022, NULL,0,time2, Yellow);
Alert(GetLastError());
}


return;


if (OrderSelect(1,SELECT_BY_POS,MODE_HISTORY)) ///если первый открытый ордер закрылся с профитом 
if(OrderProfit()>0)
{
OrderDelete(OrderTicket());// удаляем второй отложенный
}

}



bool closeorder;//определим переменную закрытия ордеров
closeorder=true;

if (closeorder==true)// вечернее закрытие всех отложенных ордеров, и рыночных позиций
{
int hour2 = TimeHour(StrToTime(time2));// вычисляем время закрытия ордеров
int minute2 = TimeMinute(StrToTime(time2));

if (hour2 == TimeHour(TimeCurrent()) && minute2 == TimeMinute(TimeCurrent()))// если время ***
{// определяем количество открытых позиций, и отложенных ордеров
for(int i=OrdersTotal()-1; i>=0; i--)
 if (OrderSelect(1,SELECT_BY_POS,MODE_TRADES))break; //определяем место где будем искать ( рабочие позиции)
if (OrderType()==OP_BUY ) OrderClose (OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),slippage);// Закрытие ордера бай если такой есть
if (OrderType()==OP_SELL) OrderClose (OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),slippage);//Закрытие ордера селл если такой есть
if (OrderType()==OP_BUYSTOP)
{ 
OrderDelete(OrderTicket()); //удаляем отложенный байстоп
}                    
if(OrderType()==OP_SELLSTOP)
{ 
OrderDelete(OrderTicket()); //удаляем отложенный sellstop
}                    

Fiz o upload do código geral do Expert Advisor, para deixar mais claro o que ele deve fazer... Sei que é uma bagunça, mas ainda não aprendi o contrário =))))
Vou lhe dizer mais uma vez onde é estúpido
abrir uma ordem pendente: abre uma ordem pendente sem a ordem oposta ou um monte inteiro de ordens pendentes em uma direção.
Elimina os pedidos: às vezes está bem à noite, a uma hora claramente especificada, e às vezes em um dia, ou não fecha de todo ...

Bem, a condição é :
Se a primeira ordem pendente em aberto fechar com lucro, a segunda é apagada imediatamente - duvido que a tenha escrito corretamente, mas não posso verificá-la em ação, pois não quero abrir duas posições opostas=(((((
 
artmedia70:
Ao procurar a última ordem fechada, devemos primeiro encontrar a última ordem fechada, mas o cheque para fechá-la no take deve ser retirado do loop, caso contrário, ele verificará o fechamento no take para cada ordem fechada e, se for o caso, lembrará a hora da primeira ordem fechada no take do loop e não a última.


Bem, isto é otimização de código. O resultado não mudará, como eu o vejo. Só leva mais tempo para calcular. Eu consertei o código, mas ainda é o mesmo.

//+-------------------------------------------------------------------------------------+
//| Получаем состояние последней позиции (Открыта или закрыта)                          |
//+-------------------------------------------------------------------------------------+
datetime GetLastOrderState()
{
   datetime lastOrderCloseTime = -1,               // Время закрытия последнего открытого ордера
            lastOOTMarket = -1,          // Время открытия последнего открытого ордера рыночного
            lastOOTHist = -1;            // Время открытия последнего открытого ордера из истории
   
   for (int i=OrdersHistoryTotal()-1; i>=0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
      if (OrderType() > 1) continue;               // Все удалённые отложки нас не интересуют..
  
      if (lastOrderCloseTime < OrderCloseTime())   // Находим время закрытия..
          lastOrderCloseTime = OrderCloseTime();   // ..последней закрытой позиции в истории
      Comment("Время закрытия последнего ордера в истории lastOrderCloseTime = ", lastOrderCloseTime);
   }

   if (MathAbs(OrderTakeProfit() - OrderOpenPrice()) < i_tp * pt) return(0);
      Comment("OrderTakeProfit() - OrderOpenPrice() < i_tp * pt = ", MathAbs(OrderTakeProfit() - OrderOpenPrice()) < i_tp * pt);
   lastOOTHist = OrderOpenTime();   // Тогда время открытия последней закрытой позиции из истории
      Comment("Время закрытия последнего ордера в истории lastOOTHist = ", lastOOTHist);
   
      Comment("Время открытия последнего открытого ордера = ", lastOOTHist);
  
   for (int h=OrdersTotal()-1; i>=0; i--)
   {   
      if (!OrderSelect(h, SELECT_BY_POS, MODE_TRADES)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
      {
         if (lastOOTMarket < OrderOpenTime())
             lastOOTMarket = OrderOpenTime();
  
         if (lastOOTMarket < lastOOTHist)      // Если время открытия последнего открытого ордера (рыночного) ниже последнего открытого ордера из истории..
             lastOrderCloseTime = OrderCloseTime(); // Значит это искомый ордер
      }
   }

   Comment("Время закрытия последнего открытого ордера = ", lastOrderCloseTime);
   return (lastOrderCloseTime);
}

Ainda assim, há algo de errado com ele.

 
ex1m:

Eu tentei mostrar-lhe o código de um EA, sei que é uma bagunça, mas nunca aprendi a fazer de outra maneira))))
Vou lhe dizer mais uma vez onde é estúpido
Abrindo ordens pendentes: abre ou uma ordem pendente sem a ordem oposta ou um monte inteiro de ordens pendentes em uma direção.
Eliminação de pedidos: apaga-os todas as vezes, às vezes à noite, a uma hora claramente especificada, às vezes ao dia, ou não fecha de todo...

Bem, a condição:
Se a primeira ordem pendente em aberto fechar com lucro, a segunda será apagada imediatamente - também duvido que a tenha escrito corretamente, mas não posso verificar no trabalho, pois não quero abrir duas posições opostas=(((((



Para responder a uma pergunta com uma pergunta. Que diabos é isso?

if ((volum<=0.0018)==true)// если объем свечей меньше или равно z пунктов 

Decifre isso para mim, não entendo :)

As verificações para abrir uma posição devem ser feitas após a tentativa de abrir uma posição. Isto é

if (ticket1<0)

Você o coloca depois de enviar um pedido.

O preço tem que ser maior ou menor do que o Asc ou Bid para abrir a posição. É assim para a compra:

 if (OOP > Ask)
 
hoz:


Bem, isto é otimização de código. O resultado não mudará, como eu o vejo. Só leva mais tempo para calcular. Eu consertei o código, mas ainda é o mesmo.

Ainda há algo de errado com ele.

Não, não é otimização de código. Está apenas procurando exatamente o último. Uma vez terminada a busca de todas as ordens fechadas e encontrada a última ordem fechada delas, só então devemos verificar o fechamento pelo take e, se for fechado pelo take, só então faz sentido continuar a busca pelo resto.

Se verificarmos se há uma fechadura dentro do loop, o que obteremos? Receberemos um erro de lógica:
Suponha que tenhamos selecionado um pedido que foi fechado há um ano. Seu tempo será de qualquer forma superior a -1, então verificamos para fechá-lo no momento da tomada (ele é verificado dentro do laço). Sim, fechou no take... O que sua função faz a seguir? Certo - continua a trabalhar com essa ordem fechada no marco há um ano. Deixe-me ver o que mais está errado. Acabei de chegar em casa...

 

Estava escrito: 2. Se a última posição aberta fechar no take, então feche tudo!

Portanto, é assim:

//-----------------------------------------------------------------------------------------------+
bool isCloseByTakeLastOpenPos (string sy, int mn, int delta) {
   datetime t=0;
   int   i, k, j=-1;
   
// Сначала определим, что последняя закрытая позиция была закрыта по тейку (в пределах дельты)
   k=OrdersHistoryTotal()-1;
   for(i=k; i>=0; i--) {
      if (OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) {
         if (OrderMagicNumber()!=mn)   continue;
         if (OrderSymbol()!=sy)        continue;
         if (OrderType()>1)            continue;            // Сначала забыл вписать, подправил
         if (t<OrderCloseTime()) {t=OrderCloseTime(); j=i;}
         }
      }  
   // Нашли последнюю. Проверим её закрытие по тейку
   if (OrderSelect(j,SELECT_BY_POS,MODE_HISTORY)) {                      
      if (OrderProfit()+OrderSwap()+OrderCommission()<=0)   return(false);          // Закрыта с убытком или в ноль
      if (MathAbs(OrderTakeProfit()-OrderClosePrice())>delta*Point) return(false);  // закрыта в профите, но не в пределах дельты
      else t=OrderOpenTime();    // Если последняя закрытая была закрыта по тейку (в пределах дельты), запомним время её открытия
      }
   else {Print("FUNC isCloseByTakeLastOpenPos : не удалось выбрать ордер в истории");return(false);}
// Здесь мы имеем последнюю закрытую позицию в профите и закрытую по тейку (в пределах дельты), ищем дальше
   k=OrdersTotal()-1;
   for(i=k; i>=0; i--) {
      if (OrderSelect(i,SELECT_BY_POS)) {
         if (OrderMagicNumber()!=mn)   continue;
         if (OrderSymbol()!=sy)        continue;
         if (OrderType()>1)            continue;
         if (t<OrderOpenTime()) return(false);  // Выбранная рыночная позиция открыта позже закрытой по тейку
         }
      else {Print("FUNC isCloseByTakeLastOpenPos : не удалось выбрать рыночный ордер");return(false);}
      }
   return(true);  // Найденная закрытая по тейку позиция была открыта позже всех, возвращаем её время открытия
}
//-----------------------------------------------------------------------------------------------+

Passamos para a função o símbolo que queremos verificar, número mágico e delta (distância em pips == diferença entre a tomada do pedido e o preço fechado), assim:

   if (isCloseByTakeLastOpenPos (Symbol(), Magic, 5)) { // Если последняя открытая была закрыта по тейку ...
      // ... тут обрабатываем эту ситуёвину
      }
   else {   // Иначе ...
      // тут обрабатываем, если последняя закрытая была открыта не последней или ...
      // ... последняя закрытая была закрыта с убытком или в профите, но за пределами дельты
      }

Eu não verifiquei esta função, escrevi-a por minha própria mão. Assim, deixo para vocês a procura de erros.

Você pode fazer isto int e usar códigos de retorno. Por exemplo, se a posição que você está procurando não existe ou existe, mas está fechada com prejuízo, retornar -1;
se existe e está fechada com lucro, mas não dentro do delta, retornar 0;
se existe e está fechada com lucro e em Take (dentro do delta), retornar 1...

O espaço para a imaginação é enorme...

 
artmedia70:

Se, por outro lado, verificarmos se a tomada está próxima, o que obtemos? Receberemos um erro lógico:

Suponha que tenhamos selecionado um pedido que foi fechado há um ano. Seu tempo será de qualquer forma superior a -1, então verificamos para fechá-lo no take (é esta verificação dentro do loop). Sim, fechou no take...


Assim, se fizermos loop em todas as ordens, o loop de qualquer forma fará loop em todas as ordens. O tempo de fechamento de cada pedido será comparado com o anteriormente selecionado. Mas é aqui que enfrentamos um problema de desempenho. TakeProfit será constantemente verificado no loop, com cada posição fechada, ao invés de apenas a última. Não é assim!?
 
PapaYozh:

Certo.

Mas existe o Open[], com um preço de abertura.


Entendi, obrigado :)
 
hoz:

Portanto, se você percorrer todos os pedidos, o ciclo irá, de qualquer forma, percorrer todos os pedidos. O horário de fechamento de cada pedido será comparado ao anterior selecionado. Mas é aqui que enfrentamos um problema de desempenho. TakeProfit será constantemente verificado no loop, com cada posição fechada, ao invés de apenas a última. Não é assim?
Eu já escrevi um exemplo da função.
 
hoz:

Portanto, se fizermos loop em todas as ordens, o loop irá de qualquer forma fazer loop em todas as ordens. O horário de encerramento de cada pedido será comparado ao anterior selecionado. Mas aqui temos um problema de desempenho. TakeProfit será constantemente verificado no loop, com cada posição fechada, ao invés de apenas a última. Não é assim!?

Isso é uma falha:

   for (int i=OrdersHistoryTotal()-1; i>=0; i--)
   {
      if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
      if (OrderMagicNumber() != i_magic) continue;
      if (OrderSymbol() != Symbol()) continue;
      if (OrderType() > 1) continue;               // Все удалённые отложки нас не интересуют.. 
  
      if (lastOrderCloseTime < OrderCloseTime())   // Находим время закрытия..
          lastOrderCloseTime = OrderCloseTime();   // ..последней закрытой позиции в истории
      
      if (MathAbs(OrderTakeProfit() - OrderOpenPrice()) < i_tp * pt) return(0); // ЗДЕСЬ ВЫХОДИМ ПРИ ПЕРВОМ ВСТРЕЧНОМ
      
      lastOOTHist = OrderOpenTime();   // Тогда время открытия последней закрытой позиции из истории
   }