Problema de pedidos múltiplos - página 2

 

Olá Raptor;

Enquanto no Tester todos os pedidos são fechados quando o TrailingStop fecha, mas na Demo apenas o pedido fechado por meio do TrailingStop fecha, qualquer pedido que esteja aberto ainda está aberto.

Usando o seguinte código em cima do código de seu aviso, a lógica é;

"Encontre qual é a condição da última ordem, se foi um fechamento, então execute o código para começar a fechar todas as ordens abertas restantes".

Alguma pista sobre o porquê disso acontecer?

Melhores Cumprimentos

Luis

int OrdType, GLError;
   double OrderClosed;
   RefreshRates();
   
    for(int Closed = OrdersTotal()-1;Closed >= 0; Closed--) 
      if(OrderSelect(Closed,SELECT_BY_POS,MODE_HISTORY)
        && OrderMagicNumber()== MagicNumber
        && OrderSymbol()== Symbol())
        {//29
        OrderClosed = OrderCloseTime();
        if(OrderClosed!=0)
           {//30                                  
   for(int OrderPos = OrdersTotal()-1; OrderPos >= 0; OrderPos--)       
      if(OrderSelect(OrderPos, SELECT_BY_POS, MODE_TRADES)
         && OrderMagicNumber()== MagicNumber 
         && OrderSymbol()== Symbol())                                       
         {//31
         OrdType = OrderType();
         if(OrdType == OP_BUY || OrdType==OP_SELL)
           {//32
           if(!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(),RealSlippage, Yellow))
               GLError = GetLastError();
           }//32                                         
          }//31
       }//30
     }//29 
    
  if(GLError > 0) Print("Error Closing/Deleting Order, error # ", GLError, " for ticket: ", OrderTicket());           
  return(0);
  }//0 
 
luisneves:

Olá Raptor;

Enquanto no Tester todos os pedidos são fechados quando o TrailingStop fecha, mas na Demo apenas o pedido fechado por meio do TrailingStop fecha, qualquer pedido que esteja aberto ainda está aberto.

Usando o seguinte código em cima do código de seu aviso, a lógica é;

"Encontre qual é a condição da última ordem, se foi um fechamento, então execute o código para começar a fechar todas as ordens abertas restantes".

Alguma pista sobre o porquê disso acontecer?

Você não pode fazer isso . . .

    for(int Closed = OrdersTotal()-1;Closed >= 0; Closed--)    // OrdersTotal is the total of open orders
      if(OrderSelect(Closed,SELECT_BY_POS,MODE_HISTORY)        //  this is looping through the closed orders

. não faz sentido usar o número de Ordens Abertas como condição de início de loop para fazer loop através das Ordens Fechadas. Talvez você quisesse usarOrderssHistoryTotal()? mas o OrderCloseTime() de uma Ordem Fechada nunca == 0

 
luisneves:

.....

Estou usando BuyTicket e SellTicket no código para evitar a abertura de vários pedidos, mas parece que esse não é o método certo para ir...

.....

Um problema vem quando uma condição para abrir uma terceira ordem vem e assim por diante. Aqui, porém, as condições para abrir estão lá e o código tem lidado bem com a segunda aberta. Por que o código não funciona aqui?

Entendo que você mudou ligeiramente o tópico inicial e talvez a primeira questão seja discutida até o fim (para mim está tudo bem)
Se você ainda quiser acompanhar a questão inital, você tem que explicar um pouco mais, porque eu não entendo realmente o que você está procurando.

O primeiro trecho que ajustei impede que o código abra vários pedidos. Você parecia não estar satisfeito com ele, portanto o removeu (ou simplesmente não o adicionou), mas fazendo o mesmo usando o BuyTicket e o SellTicket.
Então você está falando de um terceiro pedido... Você procura algo parecido com isto?

Buy->Sell->Buy->Sell->Buy
mas prevenir
Comprar->Comprar->Vender->Comprar->Comprar

Em outras palavras, se a última ordem aberta é uma ordem de compra, a próxima deve ser uma ordem de venda e vice-versa?

Ou qual é a quantidade máxima de pedidos que sua EA deve abrir? É 2, uma venda e se a condição para uma ordem oposta for atendida, uma compra, mas não mais uma venda se ela ressaltar do gatilho de compra novamente?
Se isto for verdade, qual foi o problema com o contador OpenOpposite que adicionei ao seu código inital?

editar:

A terceira opção que posso imaginar é você querer abrir outra ordem oposta se a primeira ordem oposta tiver sido interrompida?
Então, assim:

Comprar->Vender->Se a venda foi interrompida->Vender->Se a venda foi interrompida->Vender

 
kronin:

Entendo que você mudou ligeiramente o tópico inicial e talvez a primeira questão seja discutida até o fim (para mim está tudo bem)
Se você ainda quiser acompanhar a questão inital, você tem que explicar um pouco mais, porque eu não entendo realmente o que você está procurando.

O primeiro trecho que ajustei impede que o código abra vários pedidos. Você parecia não estar satisfeito com ele, portanto o removeu (ou simplesmente não o adicionou), mas fazendo o mesmo usando o BuyTicket e o SellTicket.
Então você está falando de um terceiro pedido... Você procura algo parecido com isto?

Buy->Sell->Buy->Sell->Buy
mas prevenir
Comprar->Comprar->Vender->Comprar->Comprar

Em outras palavras, se a última ordem aberta é uma ordem de compra, a próxima deve ser uma ordem de venda e vice versa?

Ou qual é a quantidade máxima de pedidos que sua EA deve abrir? É 2, uma venda e se a condição para uma ordem oposta for atendida, uma compra, mas não mais uma venda se ela ressaltar do gatilho de compra novamente?
Se isto for verdade, qual foi o problema com o contador OpenOpposite que adicionei ao seu código inital?

editar:

A terceira opção que eu posso imaginar é você querer abrir outra ordem oposta se a primeira ordem oposta tiver sido interrompida?
Então, assim:

Comprar->Vender->Se a venda foi interrompida->Vender->Se a venda foi interrompida->Vender


Olá Kronin,

Reserve com antecedência o seu tempo para me apoiar nesta questão.

A estratégia observa esta lógica;

Digamos que o primeiro pedido a abrir é uma compra e depois parece fechar por meio do TrailingStop, mas se o Bid saltar alguns pips abaixo doOrderOpenPrice(ReturnDistance), um Sell abrirá e parece fechar por meio do TrailingStop e novamente se o Ask saltar alguns pips acima do OrderOpenPrice então uma compra abrirá. Este processo de ping pong terminará quando a última ordem de abertura fechar por meio do TrailingStop ou atingir a configuração máxima de pedidos, que é 7 (pode-se ajustar isto por meio de ajuste externo).

O problema com as múltiplas aberturas acontece quando o preço sobe e desce atravessando o OrderOpenPrice. portanto, se tivermos uma compra, a próxima ordem pode ser apenas uma venda e assim por diante.

Com relação à sua ajuda anterior, talvez eu não tenha explicado bem qual era o meu problema. Qualquer ajuda fornecida tem para mim o maior valor para cima.

Melhores cumprimentos

Luis

 

Luis, gastei muito tempo com seu código, mas honestamente não tenho certeza se faço o que você quer.

Veja em anexo. Finalize/Modifique, teste, entenda.... e me diga pelo menos que está trabalhando perto, similar ou completo, do que você está procurando. Ainda não estou bem certo sobre a estratégia.
Por favor, não acrescente ainda novas funções (não readicione o martingale). O código é grande o suficiente e você ainda tem muito trabalho à sua frente, para que ele funcione de forma confiável.
Devo dizer que o código não está muito mais claramente arranjado. Eu não queria mudar suas peças em funcionamento (até mesmo você precisa de um melhor tratamento de erros). Comentei peças e movi peças, mas tudo ainda está lá...


Divirta-se...

Arquivos anexados:
 
kronin:

Luis, gastei muito tempo com seu código, mas honestamente não tenho certeza se faço o que você quer.

Veja em anexo. Finalizar/Modificar, testar, compreender.... e me dizer pelo menos que está trabalhando próximo, similar ou completo, do que você está procurando. Ainda não estou bem certo sobre a estratégia.
Por favor, não acrescente ainda novas funções (não readicione o martingale). O código é grande o suficiente e você ainda tem muito trabalho à sua frente, para que ele funcione de forma confiável.
Devo dizer que o código não está muito mais claramente arranjado. Eu não queria mudar suas peças em funcionamento (até mesmo você precisa de um melhor tratamento de erros). Comentei peças e movi peças, mas tudo ainda está lá...


Divirta-se...


Olá Kronin,

Antes de tudo, muito obrigado pelo tempo gasto em apoio aos meus problemas.

Embora eu acredite que você tenha feito o seu melhor para entender a estratégia, algumas coisas não respondem bem (devido, é claro, à minha falta de compreensão neste assunto).

Fiz algumas modificações para comprar seus conselhos, mas não tenho certeza se foram feitas corretamente.

Duas questões;

1 - A idéia é que uma vez que o comércio tenha sido fechado por meio do TrailingStop, todas as ordens abertas restantes devem ser fechadas. As ordens não devem ser fechadas no TakeProfit (que o TakeProfit só está lá porque eu quero ter certeza de que é colocado de Zona de Congelamento). Então, pensei em fazer isso usando o fechamento da última ordem para executar a função CloseAll (algumas coisas estúpidas surgem para tentar fazer isso...). Você está usando o último Bilhete Fechado para executar o fechamento da última ordem aberta, mas eu não entendo se isso acontece quando o comércio fecha por meio do TrailingStop...

2 - O "ping pong" não está funcionando, pelo menos no Testador.

Em anexo está o arquivo onde as modificações tinham sido feitas até onde eu as entendi.

Obrigado antecipadamente pela paciência e pelo tempo gasto. (mais em mensagem particular)

Melhores cumprimentos

Luis

Arquivos anexados:
 

Ok, eu mudei o algoritmo para fechar todos os pedidos no SL instigados pelo TP. (A mudança foi '<' substituída por '>' - você deve descobrir onde)

O ping pong funciona para mim e eu só o deixei correr no modo visual no testador. Mas eu ajustei seus parâmetros de entrada para não ter todas as ordens abertas praticamente ao mesmo tempo. Talvez você tenha que verificar os params padrão.

Ele começa com a ordem inital (eu alterei a declaração de impressão()) e depois faz ordens opostas.

EURUSD,M1: abrir #1 comprar 0,01 EURUSD a 1,43310 ok
EURUSD,M1: Pedido de Compra Inital # 1
EURUSD,M1: modificar #1 comprar 0,01 EURUSD a 1,43310 sl: 1,42810 tp: 1,43510 ok
EURUSD,M1: abrir #2 vender 0,01 EURUSD a 1,43200 ok
EURUSD,M1: Encomenda de venda em oposição # 2
EURUSD,M1: modificar #2 vender 0,01 EURUSD a 1,43200 sl: 1,43700 tp: 1,43000 ok
EURUSD,M1: abrir #3 comprar 0,01 EURUSD a 1,43300 ok
EURUSD,M1: Ordem de compra contrária # 3
EURUSD,M1: modificar #3 comprar 0,01 EURUSD a 1,43300 sl: 1,42800 tp: 1,43500 ok

Acrescentei um retorno ao OpenOppositeOrder() quando abri um pedido. Junto com as configurações, foi possível abrir uma ordem de compra e no mesmo tick uma ordem de venda. Este chumbo no MaxOrder não é confiável.
Talvez uma abordagem melhor seja dividi-lo em 2 funções ou dar à função um parâmetro para executar apenas para ordens de venda ou ordens de compra.

btw. o código que você carregou não foi negociado! Todas as negociações falharam por causa do "LotSize inválido"....

Arquivos anexados:
 

Olá Kronin,

Obrigado pelo tempo gasto em meu apoio.

Em relação à questão "o código que você carregou não foi negociado! Todas as negociações falharam por causa do "LotSize inválido".... ", isso aconteceu depois de mover o código MM para o final do arquivo. Eu fiz a chamada da função usando MM(); no início do código, parece que este tipo de ação não funciona, mas o último código que você enviou está funcionando e a função MM() ainda está no mesmo lugar e está funcionando, então aqui estou perdido....

Sobre a abertura do pedido no mesmo tick;

Quando a EA entra no gráfico, o caminho para o preço é mais (ou menos) do que o preço naquele momento, ou seja, quando o preço sobe (ou desce) a OpenDistance uma ordem de compra (ou venda) ocorre. A partir daqui, a próxima abertura só pode acontecer quando o preço saltar para baixo (se a última ordem for uma compra) da OrderOpenPrice menos ReturnDistance.A mesma lógica no caso de a venda ser a última ordem. Talvez um limite tenha que ser estabelecido para evitar qualquer abertura de ordem fora desta lógica.

A melhor consideração é a

Luis

 
//mine
LotSize = (RiskAmount / StopLoss) / TickValue;              //Phil: LotSize is defined in global scope

//yours
double LotSize = (RiskAmount / StopLoss) / TickValue;


Você definiu LotSize no escopo global e o initalizou com 0. Na função MM() nula você calcula um LotSize válido somente nessa função. Eu só removi a inicialização, portanto a variável no escopo global é atualizada.

Você poderia comentar para cada um destes valores, o valor em Pips, por favor?

extern double StopLoss       =  50;
extern double TakeProfit     =  20;
extern double TrailingStop   =   2;
extern int    MinimumProfit  =   3;
extern int    Slippage       =   3;
extern double OpenDistance   =   2;
extern double ReturnDist     =   1;
extern double MinStop        =   1;

Qual é o spread para o Símbolo que você deseja executar a EA?

Mas eu ajustei seus parâmetros de entrada para que nem todas as ordens sejam abertas praticamente ao mesmo tempo.Talvez você tenha que verificar os parâmetros padrão.

Tente fazer o mesmo e deixe-o rodar no modo de teste visual.

 
kronin:


Você definiu LotSize no escopo global e o initalizou com 0. Na função MM() nula você calcula um LotSize válido somente nessa função. Eu só removi a inicialização, portanto a variável no escopo global é atualizada.

Você poderia comentar para cada um destes valores, o valor em Pips, por favor?

Qual é o spread para o Símbolo que você deseja executar a EA?

Mas eu ajustei seus parâmetros de entrada para que nem todas as ordens sejam abertas praticamente ao mesmo tempo.Talvez você tenha que verificar os parâmetros padrão.

Tente fazer o mesmo e deixe-o rodar no modo de teste visual.


Olá, Kronin,

Sim, tenho muito a aprender....Agora entendo que quando há a necessidade de um valor para ser acessado de fora de uma função que deve estar na Global.

Os valores que estão no externo são multiplicados por 10 porque a EA também deve funcionar em corretores de 5 dígitos. Estou usando este bloco de código para obtê-lo automaticamente, mas recebo um aviso da WHRoeder que não é compatível com metais.

int init ()// Adjust for 4 or 5 digits.
   {
   if (Digits == 2 || Digits == 4) <------- not compatible with metals
      {
      pt = Point;
      RealSlippage = Slippage;
      }    
   if (Digits == 3 || Digits == 5) 
      {
      pt = Point * 10;
      RealSlippage = Slippage * 10;
      }

A propagação do par pode ser variável. É por isso que estou usando o código para sair do nível de parada.

Com relação a esta questão "Mas eu ajustei seus parâmetros de entrada para não ter todas as ordens abertas praticamente ao mesmo tempo.Talvez você tenha que verificar os parâmetros de entrada padrão".

Até onde eu posso ver (desculpe se não estou...), OpenDistance mantém como 2 pips e ReturnDistance agora também está com 2. O que estou vendo agora é que a ordem abre mas não com 2 pips de diferença. Isto está funcionando com um testador de uma plataforma de um corretor ECN (IC Markets). Isto poderia ter alguma importância?

Na verdade, as ordens não abrem ao mesmo tempo, mas parece que a Distância Aberta e o ReturnDist não são levados em conta para obter a distância certa para abrir ordens.

Você tem isso em código;

OTLastTick=OTCurrentTick;                      //shift OrderTotal
  OTCurrentTick=OrdersTotal();                   //reinit OrderTotal
  if(OTCurrentTick>0)Trail();                    //Trail
  if(OTLastTick>=2                               //if OrderTotal has changed
     &&OTCurrentTick<OTLastTick
     &&OTCurrentTick>0){CloseAllOnSL();return;}  //Check order closed on SL level
  if(OTCurrentTick>=MaxOrders)return;            //Dont open more orders. Trail and return.
                                                 //Actually we have nothing more to do.
                                                 //Only call opposite if the initial order of the serie is open
  if(OTCurrentTick>0)OpenOppositeOrder(); //<--------------------- include this line to call function (not sure if this the right method to do it...)
  MM();                //<--------------------- include this line to call function (not sure if this the right method to do it...)
                        
  if(OTCurrentTick==0){//init serie
     BuyAllowed=true;
     SellAllowed=true; 

Incluí a linha em negrito para chamar a função OpenOppositeOrder e aqui não tenho certeza se isto está certo. Para o outro lado não posso ver onde está a comparação do tick presente com o último tick que aconteceu 2 pips antes (OpenDistance).

Desculpe se começo a aborrecê-lo com meus problemas.

Com a maior consideração

Luis

Razão: