Calculo de posicoes em martingale ?

 

Salve galera. Estou criando uma estratégia em Martingale para usar no Forex. Minha estrategia se baseia em um robo que tenho que usa essa estrategia e vai incrementando a qtd de lotes.

Basicamente, o robo vai abrindo ordens conforme o mercado anda, por exemplo se estiver subindo ele vende, se estiver caindo ele compra. 

Minha duvida é quanto a quantidade de ordens, como exemplo esse robo que tenho vai abrindo ordens e movendo o takeprofit dependendo da quantidade de ordens.

Por exemplo: Se ele abre 15 ordens, ele move o takeprofit dxando sempre as ultimas 5 ou 4 para recuperar o lucro na volta, é isso que não estou conseguindo fazer.

Atualmente eu estou somando os valores de abertura da primeira e da segunda ordem e divido por 2, porem, quero acertar isso, para que me deixe sempre as ultimas 5 ordens para recuperação como falei. Então caso abra 15 ordens, ele move o takeprofit dxando as 5 ultimas e perdendo as outras 10 na volta.

Como fazer isso, como fazer para dxar sempre as ultimas 4 ou  5 ordens para recuperação ?

Atualmente estou fazendo.

//aqui divide por 2 e reposiciona o takeprofit para a metade
double _vAberturaPrimeiraOrdem = x;
double _vAberturaUltimaOrdem = y;
double _total = x + y / 2;


 

 
Fernando Paiva:

Salve galera. Estou criando uma estratégia em Martingale para usar no Forex. Minha estrategia se baseia em um robo que tenho que usa essa estrategia e vai incrementando a qtd de lotes.

Basicamente, o robo vai abrindo ordens conforme o mercado anda, por exemplo se estiver subindo ele vende, se estiver caindo ele compra. 

Minha duvida é quanto a quantidade de ordens, como exemplo esse robo que tenho vai abrindo ordens e movendo o takeprofit dependendo da quantidade de ordens.

Por exemplo: Se ele abre 15 ordens, ele move o takeprofit dxando sempre as ultimas 5 ou 4 para recuperar o lucro na volta, é isso que não estou conseguindo fazer.

Atualmente eu estou somando os valores de abertura da primeira e da segunda ordem e divido por 2, porem, quero acertar isso, para que me deixe sempre as ultimas 5 ordens para recuperação como falei. Então caso abra 15 ordens, ele move o takeprofit dxando as 5 ultimas e perdendo as outras 10 na volta.

Como fazer isso, como fazer para dxar sempre as ultimas 4 ou  5 ordens para recuperação ?

Atualmente estou fazendo.


 

Olá Fernando, bom dia,

Primeiro veja a ordem de cálculo da matemática, pois divisão vem antes de adição. Então seu código precisa:

double _total = (x + y) / 2;

Depois disso para você manter as últimas 5 posições vai precisar guardá-las em uma array ou se não souber usar array use variáveis separadas. Dai da mesma forma que você fez esse seu cálculo da última posição com a primeira, você vai poder fazer da segunda, da terceira... da quinta... também fazendo eles separadamente ou usando um for(...)... ou ainda usando um while.

Parece simples, tente fazer dessa forma.

https://www.mql5.com/pt/docs/basis/operators/dowhile

https://www.mql5.com/pt/docs/basis/operators/for

https://www.mql5.com/pt/docs/function_indices

Documentação sobre MQL5: Elementos Básicos da Linguagem / Operadores / Operador de loop do while
Documentação sobre MQL5: Elementos Básicos da Linguagem / Operadores / Operador de loop do while
  • www.mql5.com
verifica a condição de término no fim, após cada interação do loop. O corpo do loop é sempre executado pelo menos uma vez. Primeiro o operador é executado, então a expressão é calculada. Se a expressão for verdadeira, então o operador é executado novamente, e assim por diante. Se a expressão se tornar falsa, o loop termina. Se é esperado que um...
 
Ruy Christian Hoffmann:

Olá Fernando, bom dia,

Primeiro veja a ordem de cálculo da matemática, pois divisão vem antes de adição. Então seu código precisa:

Depois disso para você manter as últimas 5 posições vai precisar guardá-las em uma array ou se não souber usar array use variáveis separadas. Dai da mesma forma que você fez esse seu cálculo da última posição com a primeira, você vai poder fazer da segunda, da terceira... da quinta... também fazendo eles separadamente ou usando um for(...)... ou ainda usando um while.

Parece simples, tente fazer dessa forma.

https://www.mql5.com/pt/docs/basis/operators/dowhile

https://www.mql5.com/pt/docs/basis/operators/for

https://www.mql5.com/pt/docs/function_indices

Ruy, acho que vc não entendeu minha duvida, não eh quanto a linguagem e nem quanto a a ordem matematica, mas sim, como diminuir o takeprofit para que fique sempre abaixo de 5 ou 4 ordens abertas. A divisão por 2 eu ja faco, porem, sempre fica na metade das ordens. Ja fiz o teste no robo que tenho, e as vezes ele divide por 0.199950 e por ai vai. O que preciso, eh bolar uma formula para que sempre fique abaixo de 5 ordens caso abra 10, ok, divido por 2, mas se abrir 15 como ignoro 10 e fico só com 5 ordens. Não sei se estou explicando bem, mas basicamente é isso.

 
Fernando Paiva:

Salve galera. Estou criando uma estratégia em Martingale para usar no Forex. Minha estrategia se baseia em um robo que tenho que usa essa estrategia e vai incrementando a qtd de lotes.

Basicamente, o robo vai abrindo ordens conforme o mercado anda, por exemplo se estiver subindo ele vende, se estiver caindo ele compra. 

Minha duvida é quanto a quantidade de ordens, como exemplo esse robo que tenho vai abrindo ordens e movendo o takeprofit dependendo da quantidade de ordens.

Por exemplo: Se ele abre 15 ordens, ele move o takeprofit dxando sempre as ultimas 5 ou 4 para recuperar o lucro na volta, é isso que não estou conseguindo fazer.

Atualmente eu estou somando os valores de abertura da primeira e da segunda ordem e divido por 2, porem, quero acertar isso, para que me deixe sempre as ultimas 5 ordens para recuperação como falei. Então caso abra 15 ordens, ele move o takeprofit dxando as 5 ultimas e perdendo as outras 10 na volta.

Como fazer isso, como fazer para dxar sempre as ultimas 4 ou  5 ordens para recuperação ?

Atualmente estou fazendo.


 

Como @Ruy Christian Hoffman bem apontou, seu código está errado.

Para ser um programador minimamente decente você precisa conhecer não só o básico de programação, como também o básico de Matemática. Se você lembrar dos seus tempos de escola, a menos que você tenha faltado nessa aula, existe a Precedência de Operadores. Reveja esse assunto e você entenderá a razão do erro.

;)

 

E depois... Tente isto:

double _total = ((x+y)/2 <= 5 ? 5 : (x+y)/2);
 
Fernando Paiva:

Ruy, acho que vc não entendeu minha duvida, não eh quanto a linguagem e nem quanto a a ordem matematica, mas sim, como diminuir o takeprofit para que fique sempre abaixo de 5 ou 4 ordens abertas. A divisão por 2 eu ja faco, porem, sempre fica na metade das ordens. Ja fiz o teste no robo que tenho, e as vezes ele divide por 0.199950 e por ai vai. O que preciso, eh bolar uma formula para que sempre fique abaixo de 5 ordens caso abra 10, ok, divido por 2, mas se abrir 15 como ignoro 10 e fico só com 5 ordens. Não sei se estou explicando bem, mas basicamente é isso.

Eita Fernando, desculpe mas entendi não :(  ... você teria um exemplo prático em Excel para dar um print?

 
Fernando Paiva:

Ruy, acho que vc não entendeu minha duvida, não eh quanto a linguagem e nem quanto a a ordem matematica, mas sim, como diminuir o takeprofit para que fique sempre abaixo de 5 ou 4 ordens abertas. A divisão por 2 eu ja faco, porem, sempre fica na metade das ordens. Ja fiz o teste no robo que tenho, e as vezes ele divide por 0.199950 e por ai vai. O que preciso, eh bolar uma formula para que sempre fique abaixo de 5 ordens caso abra 10, ok, divido por 2, mas se abrir 15 como ignoro 10 e fico só com 5 ordens. Não sei se estou explicando bem, mas basicamente é isso.

Para atingir este objetivo, você deve utilizar a função matemática MathMod.

 

Acompanhando o EA que eu falei que tenho para ver como ele faz como base de calculo para mudar o TP. Fiz os calculos, somando o valor da primeira ordem aberta com o da ultima e dividi pelo TP que o EA estava usando, então encontrei o numero 0.199950 como base, e percebi que ele adiciona 100 a cada qtd de ordens abertas, então criei um método para retornar isso e fazer o calculo pra mim. 

Não sei se é dessa maneira que o EA faz, nem sei como chegou a essa formula, mas é um padrão que reconheci. 

Então comecei a testar e meu TP estava se posicionando igual ao do EA, ou seja, funcionou. 

Aqui como fiz e está funcionando como preciso

/* Altera posicao take profit de todas as ordens abertas

mn = magic number
moveTPAsOfOrder = mover tp a partir de X ordens
*/
void changeTP(int mn, int moveTPAsOfOrder){
   double _diffPrice = 0;     
   double _firstOrderOpenPrice = 0;
   double _lastOrderOpenPrice = 0;
   double _normalizePrice = 0;  
   int _digits = getDigits(); 
   int _qtdOrdens = OrdersTotal();
   double _index = getIndexToChangeTP();

   
   if(OrdersTotal() >= moveTPAsOfOrder){
         
         //seleciona primeira ordem aberta 
         if(OrderSelect(getTicketFirstOrder(mn), SELECT_BY_TICKET)){
            _firstOrderOpenPrice = OrderOpenPrice();
         }
         //seleciona ultima ordem aberta
         if(OrderSelect(getTicketLastOrder(mn), SELECT_BY_TICKET)){
            _lastOrderOpenPrice = OrderOpenPrice();
         }
         
         //soma o preço da primeira e ultima ordem aberta e divide por _index        
         _diffPrice = (_firstOrderOpenPrice + _lastOrderOpenPrice) / _index; 
                  
         
         //normaliza o resultado  
         _normalizePrice = NormalizeDouble(_diffPrice, _digits);             
                  
         //reposiciona TP de todas as ordens
         for(int x = 0; x < OrdersTotal(); x++){
            if(OrderSelect(x, SELECT_BY_POS)){
               if(OrderMagicNumber() == mn && OrderSymbol() == Symbol()){
                  if(!OrderModify(OrderTicket(), OrderClosePrice(), 0, _normalizePrice, 0, clrRed)){
                     //Comment("Erro Tentando Mudar TP: ", GetLastError());
                  }//modify take profit
               }//if ordermagicnumber
            }//if select
         }//for
         

    }//OrdersTotal
   
   
}//changeTP


//retorna o indice para calculo da mudança do TP
double getIndexToChangeTP(){
   double _index = 1.99950;

   if((OrdersTotal() >= 4) && (OrdersTotal() < 8)){      
      return _index;
   }
   if((OrdersTotal() >= 8) && (OrdersTotal() < 12)){
      return _index + 0.00100;
   }
   if((OrdersTotal() >= 12) && (OrdersTotal() < 16)){
      return _index + 0.00200;
   }
   if((OrdersTotal() >= 16) && (OrdersTotal() < 20)){
      return _index + 0.00300;
   }
   if(OrdersTotal() >= 20){
      return _index + 0.00400;
   }
   return 0;
}


PS: Em 1995, quando comecei a programar em Cobol e Clipper, havia alguns programadores com o EGO enorme, e até hoje percebo que existe esse tipo de programador.

@Flavio Jarabeck cuidado com o EGO, muitas vezes ele cega e leva vc a julgar as pessoas sem nem mesmo conhece-las. Humildade sempre !


abraços e obrigado a todos.!

 
Fernando Paiva:

Acompanhando o EA que eu falei que tenho para ver como ele faz como base de calculo para mudar o TP. Fiz os calculos, somando o valor da primeira ordem aberta com o da ultima e dividi pelo TP que o EA estava usando, então encontrei o numero 0.199950 como base, e percebi que ele adiciona 100 a cada qtd de ordens abertas, então criei um método para retornar isso e fazer o calculo pra mim. 

Não sei se é dessa maneira que o EA faz, nem sei como chegou a essa formula, mas é um padrão que reconheci. 

Então comecei a testar e meu TP estava se posicionando igual ao do EA, ou seja, funcionou. 

Aqui como fiz e está funcionando como preciso


PS: Em 1995, quando comecei a programar em Cobol e Clipper, havia alguns programadores com o EGO enorme, e até hoje percebo que existe esse tipo de programador.

@Flavio Jarabeck cuidado com o EGO, muitas vezes ele cega e leva vc a julgar as pessoas sem nem mesmo conhece-las. Humildade sempre !


abraços e obrigado a todos.!

Não é questão de Ego.

Você tinha uma linha de código que estava errada, outra pessoa apontou o erro, e você insistiu que estava fazendo certo.

Eu não julgo pessoas, eu julgo o código-fonte.

Mas ok.

Boa sorte com seu Martingale.

Razão: