assessor especializado - perguntas diversas - página 24

 

Já está no exemplo.

Quando você fecha a ordem você usa o valor de retorno booleano da função OrderClose(), e se a função foi bem sucedida, você pode remover os objetos relacionados com a ordem.

                           bool close=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),3,clrBlue);
                             {
                              if(close==0)
                                {
                                 Alert(" Order Close Error! # "+IntegerToString(OrderTicket()));
                                }
                              if(close==1)
                                {
                                 Alert(" Order: "+IntegerToString(OrderTicket())+" Closed due to TP Profit = "+DoubleToString(OrderProfit(),2));
                                 ObjectDelete(0,"#"+IntegerToString(OrderTicket())+"-TP");
                                 ObjectDelete(0,"#"+IntegerToString(OrderTicket())+"-SL");
                                }
                             }
 
Marco vd Heijden:

Já está no exemplo.
Quando você fecha a ordem você usa o valor de retorno booleano da função OrderClose(), e se a função foi bem sucedida, você pode remover os objetos relacionados com a ordem.

Eu já sei, já tentei. Talvez eu tenha feito algo errado. Vou tentar mais uma vez, mas antes de perguntar, não gostaria de usar OrderClose(). ( às vezes eu fecho os pedidos manualmente )
P: Então, posso apagar objetos de pedido após o fechamento do pedido sem OrderClose()?

Obrigado de antemão.

 

Bem, o valor de retorno da função Encerrar() decide se a ação foi bem sucedida ou não, se você fechar o pedido manualmente você terá que projetar e usar um mecanismo ligeiramente diferente.

Você pode fazer uma cópia sombra da lista de pedidos e compará-la com a lista real, e sempre que algo mudar porque você fechou um pedido manualmente, procure pelo que mudou e depois remova esses objetos.

Mas uma maneira mais fácil pode ser verificar se o OrderTicket() ainda existe no pool de ordens ativo, então quando ele desaparece porque você fechou a ordem manualmente, os objetos serão removidos automaticamente.

Portanto, depende de como você deseja configurá-lo.

Neste ponto eu diria que você teria que tentar olhar além do que você quer fazer com ele eventualmente porque a direção que você tomar está de alguma forma relacionada a tarefas adicionais que você pode querer adicionar mais tarde.


Como a criação dos Objetos já está totalmente automatizada, sugiro que você faça o mesmo para a remoção dos objetos, então você não precisa se preocupar com isso no futuro.

Para isso, você pode simplesmente usar

OrdersHistoryTotal()

E o conjunto da história

MODE_HISTORY

É simples, o histórico de pedidos é escaneado, e a cada ciclo o código procurará ver se existe algum objeto relacionado ao número OrderTicket(), e se houver uma correspondência, os objetos são automaticamente apagados.

Para fazer isso, basta adicionar outro loop, mas desta vez sobre o pool do histórico.

Veja o exemplo.

//+------------------------------------------------------------------+
//|                                                ObjectsRemove.mq4 |
//|      Copyright 2017, Marco vd Heijden, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, Marco vd Heijden, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

static input int takeprofit=500;// Take Profit
static input int stoploss=500;  // Stop Loss
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create timer
   EventSetTimer(1);

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy timer
   EventKillTimer();

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   for(int order=OrdersTotal(); order>=0; order--)
     {
      bool selected=OrderSelect(order,SELECT_BY_POS);
        {
         if(selected==1)
           {
            if(Symbol()==OrderSymbol()) // only for current chart symbol
              {
               switch(OrderType())
                 {
                  case OP_BUY: // for buy order
                    {
                     // if objects not found - create them
                     if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")<0)
                       {
                        ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJ_HLINE,0,0,OrderOpenPrice()+takeprofit*Point());
                        ObjectSet("#"+IntegerToString(OrderTicket())+"-TP",7,3);
                       }
                     if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-SL")<0)
                       {
                        ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-SL",OBJ_HLINE,0,0,OrderOpenPrice()-stoploss*Point());
                        ObjectSet("#"+IntegerToString(OrderTicket())+"-SL",7,3);
                       }
                     // if objects exist
                     if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")>=0)
                       {
                        if(Bid>ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJPROP_PRICE,0))
                          {
                           PlaySound("alert2.wav"); // OrderClose now removed...
                          }
                       }
                     if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-SL")>=0)
                       {
                        if(Ask<ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-SL",OBJPROP_PRICE,0))
                          {
                           PlaySound("alert2.wav"); // OrderClose now removed...
                          }
                       }
                    }
                  break;

                  case OP_SELL: // for sell order
                    {
                     // if objects not found - create them
                     if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")<0)
                       {
                        ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJ_HLINE,0,0,OrderOpenPrice()-takeprofit*Point());
                        ObjectSet("#"+IntegerToString(OrderTicket())+"-TP",7,3);
                       }
                     if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-SL")<0)
                       {
                        ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-SL",OBJ_HLINE,0,0,OrderOpenPrice()+stoploss*Point());
                        ObjectSet("#"+IntegerToString(OrderTicket())+"-SL",7,3);
                       }
                     // if objects exist
                     if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")>=0)
                       {
                        if(Ask<ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJPROP_PRICE,0))
                          {
                           PlaySound("alert2.wav"); // OrderClose now removed...
                          }
                       }
                     if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-SL")>=0)
                       {
                        if(Bid>ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-SL",OBJPROP_PRICE,0))
                          {
                           PlaySound("alert2.wav"); // OrderClose now removed...
                          }
                       }
                    }
                  break;
                 }
              }
           }
        }
     }
//+------------------------------------------------------------------+
//--- delete objects when order is closed
   for(int order=OrdersHistoryTotal()-1; order>=0; order--)
     {
      bool selected=OrderSelect(order,SELECT_BY_POS,MODE_HISTORY);
        {
         if(selected==1)
           {
            // if objects are still found - Delete them
            if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")>=0)
              {
               ObjectDelete(0,"#"+IntegerToString(OrderTicket())+"-TP");
              }
            if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-SL")>=0)
              {
               ObjectDelete(0,"#"+IntegerToString(OrderTicket())+"-SL");
              }
           }
        }
     }
//+------------------------------------------------------------------+    
  } // end OnTimer() function
//+------------------------------------------------------------------+

Assim, agora você tem a adição totalmente automatizada de linhas de ganho e perda virtual, e também a remoção totalmente automatizada destas linhas.

É claro que este exemplo está continuamente escaneando o pool de histórico.

Além disso, você poderia adicionar um número inteiro que contenha o número de ordens, que é então comparado com OrderTotal(), e sempre que algo muda, você executa o código de remoção de objetos.

Ou, você poderia adicionar um simples contador (60), então o pedaço de código só será verificado uma vez por minuto, se alguma coisa precisar ser removida.

 

Ei, cara! Isso funciona perfeitamente! Muito obrigado!

Eu apenas mudei pouco. Até agora, funciona sem problemas.

//--- delete objects when order is closed
   for(int order=OrdersHistoryTotal()-1; order>=0; order--)
     {
      bool selected=OrderSelect(order,SELECT_BY_POS,MODE_HISTORY);
        {
         if(selected==1)
           {
            // if objects are still found - Delete them
            ObjectsDeleteAll( 0, "#" + IntegerToString( OrderTicket() ) ); // for arrows
            ObjectsDeleteAll( 0, _prefix + " #" + IntegerToString( OrderTicket() ) ); // order, sl, tp, price objects
           }
        }
     }

Se algo estiver errado, por favor, me avise sobre isso.
Mais uma vez, muito obrigado, cara!

 

Talvez ninguém entenda minha pergunta. Mas ainda preciso de um bom comentário para isso. Por isso, agora estou tentando esclarecer minha pergunta com imagem.
Pergunta: Também Stop Loss, Take Profit Lines frente aos Objetos do Painel de Comércio. Eu sei que isso causado da última vez cria objetos. Mas se você me entendeu, por favor, me informe como posso fazer para que um objeto do Painel de Comércio seja colocado na frente de todos os outros objetos sem "Stop Loss and Take Profit" Lines.

Objetos misturados

Sei que posso usar OBJPROP_BACK, mas não quero usá-lo. Só preciso ver linha e preço como os dois. Espero receber bons comentários por isso.


Abrir, Stop Loss, Take Profit, linhas de preço "Create and Delete" que todos eles em uma função. Portanto, agora mesmo estou tentando dividi-lo, porque preciso colocar essa função no OnChartEvent(). Mas antes, preciso perguntar.
P: Se eu colocar essa função no OnChartEvent() - para que essa função não possa afetar minhas ordens manuais?

Estou trabalhando nisso agora.

Por favor, me ajude, obrigado de antemão.

 

Nenhum Onchartevent() só executará o código quando houver um evento gráfico que não seja como a função OnTImer().

Portanto, você tem que saber exatamente o que está fazendo.

Por exemplo, se você estiver usando o código de escaneamento :

if(Bid>ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-SL",OBJPROP_PRICE,0))

Para verificar se o preço cruzou sua linha, isto não funcionará na função OnChartEvent().

Também se você quiser usar o exemplo automatizado

if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")<0)
   {
     ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJ_HLINE,0,0,OrderOpenPrice()-takeprofit*Point());
     ObjectSet("#"+IntegerToString(OrderTicket())+"-TP",7,3);
   }

Isto não vai funcionar ou criar os objetos.

Você terá que reescrever o código.

Além disso, você pode configurar os objetos H_LINE para OBJPROP_BACK isto não é problema você ainda os verá e eles estarão sob seu painel.

 

Comentário muito bom e útil, agora eu sei com certeza que deveria tentar pelo menos uma vez para saber o que eu poderia fazer adicionalmente.

Obrigado por sua resposta rápida e por seu comentário útil.

 
Marco vd Heijden:

Você terá que reescrever o código.

( Já li cuidadosamente seu comentário, mas só quis tentar uma vez - finalmente como você disse, não funciona como o OnTimer(). )

Omg! Devo mudar tudo nesse código de bloco?
Agora eu tenho quatro funções. Eu apenas tento colocá-las no OnChartEvent(). Já tentei, só vejo uma coisa que atualizo: Imprimir() para parar de perder, tomar preços de lucro.
OrderModify() não funciona nele.

Vou começar a tentar algo novamente para esta edição em 8 - 10 horas.
Eu só preciso realmente de bons comentários, espero conseguir.

Muito obrigado de antemão.

void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
  {
   if(id==CHARTEVENT_OBJECT_DRAG) // I already tried with take profit object - there was not any effects
     {
      SL_TPcreateobjects();
      SL_TPdrags();
      SL_TPmodify();
      deleteobjs();
     }
  }
// if objects not found - create them
SL_TPcreateobjects()
  {
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
      if(Symbol()!=OrderSymbol()) continue;

      if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")<0)
        {
         ObjectCreate(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJ_HLINE,0,0,takeprofit);
        }
     }
  }
// if objects exist
SL_TPdrags()
  {
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
      if(Symbol()!=OrderSymbol()) continue;

      if(ObjectFind(0,"#"+IntegerToString(OrderTicket())+"-TP")>=0)
        {
         if(TP_Price!=ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJPROP_PRICE,0))
           {
            TP_drag=1;
            TP_Price=ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJPROP_PRICE,0);
           }
         if(TP_drag==1)
           {
            if(TP_Price==ObjectGetDouble(0,"#"+IntegerToString(OrderTicket())+"-TP",OBJPROP_PRICE,0))
              {
               Print("Take Profit Price:",DoubleToString(TP_Price,Digits));
               TP_drag=0;
              }
           }
        }
     }
  }
// order closed - delete junks
deleteobjs()
{
  for(int i=OrdersHistoryTotal()-1; i>=0; i--)
    {
     bool Selected=OrderSelect(i,SELECT_BY_POS,MODE_HISTORY);
     if(Selected==1)
       {
        ObjectsDeleteAll(0,"#"+IntegerToString(OrderTicket())+"-TP");
       }
    }
}
// ordermodify()
SL_TPmodify()
{
  Order_Modify=OrderModify(OrderTicket(),OrderOpenPrice(),SL_Price,TP_Price,0,CLR_NONE);
}
//+------------------------------------------------------------------+
 

Essas funções só serão executadas quando um evento de caridade acontecer.

Pelo menos é isso que você está mostrando aqui.

Chartevent é apenas um gatilho para uma rotina de interrupção quando alguém pressiona um botão ou outra coisa no gráfico.

Agora você pegou o exemplo totalmente automatizado e o colocou debaixo de um botão, nada acontecerá se ninguém o pressionar.

 
Marco vd Heijden:

Essas funções só serão executadas quando um evento de cartas acontecer.
Pelo menos é isso que você está mostrando aqui.
Chartevent é apenas um gatilho para uma rotina de interrupção quando alguém aperta um botão ou outra coisa no gráfico.
Agora que você pegou o exemplo totalmente automatizado e o colocou sob um botão, nada acontecerá se ninguém pressionar o botão.

É possível que seu último comentário pareça tão simples, mas na verdade esse comentário me mostrou o caminho certo.
Então agora eu resolvo meu problema qual deles eu tento usar de arrastar.

E agora estou começando a pesquisar sobre alguns outros objetos gráficos que se movimentam com aquele objeto HLine.

Muito mais obrigado, cara!
Tudo de bom para você!


honesto_knave:

Além disso, pense com que freqüência você move a linha. É uma vez por segundo? Provavelmente não.
Coloque seu código no OnChartEvent():

void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
  {
   if(id==CHARTEVENT_OBJECT_DRAG && sparam=="line") // the chart event of dragging the line
Muito obrigado, cara! Para que este seu comentário realmente me ajude muito!
Razão: