Correção definitiva de preços

 
Bom dia pessoal,
queria uma ajuda para a normalização de preço... 
minha estratégia sempre depende do valor de (máxima ou minima) da ultima vela somada a um valor determinado de pontos, por exemplo:
Valor máximo da ultima vela + 10 pontos

o que acontece é que dependendo do ativo essa soma não funciona, e quando funciona ele diz as vezes que o preço não é valido (acho que depende do lotstep).

vocês já passaram por isso e o que fizeram para corrigir ? Eu tentei criar um script para me ajudar a analisar as mais diversas possibilidades, mas não adianta, não consigo deixar algo universal (forex, B3, etc)


#include <Trade\SymbolInfo.mqh>
CSymbolInfo _symb;

input double pts = 10;

MqlRates rates[];

int OnInit()
  {
   
   _symb.Name(_Symbol);
   _symb.RefreshRates();
   ArraySetAsSeries(rates,true);
   CopyRates(Symbol(), _Period, 0, 3, rates);
   
   double size = 0;
   double pricehigh = rates[1].high;
   double pricelow  = rates[1].low;
   double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
   double _tick = size ? size : SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
   
   double takeA = rates[1].high + pts;
   double takeB = rates[1].high + pts*_Point;
   double takeA1 = NormalizeDouble(takeA,_Digits);
   double takeA2 = takeA*_Point;
   double takeA3 = takeA/_Point;
   double takeA4 = NormalizeDouble((takeA*_Point),_Digits);
   double takeA5 = NormalizeDouble(takeA * tickSize, _Digits);
   double takeA6 = _symb.NormalizePrice(takeA);
   double takeA7 = round(takeA / _tick) * _tick;
   double takeB1 = NormalizeDouble(takeB,_Digits);
   double takeB2 = takeB*_Point;
   double takeB3 = takeB/_Point;
   double takeB4 = NormalizeDouble((takeB*_Point),_Digits);
   double takeB5 = NormalizeDouble(takeB * tickSize, _Digits);
   double takeB6 = _symb.NormalizePrice(takeB);
   double takeB7 = round(takeB / _tick) * _tick;
   double teste1  = NormalizeDouble((rates[1].high + pts * _Point), _Digits);
   double teste2  = NormalizeDouble((rates[1].low - pts * _Point), _Digits);
   
   Print("\nTarget: Price + pts",
         "\nPriceHigh: ",pricehigh,
         "\nPriceLow: ",pricelow,
         "\nTakeA: ", takeA,
         "\nTakeA1: ", takeA1,
         "\nTakeA2: ", takeA2,
         "\nTakeA3: ", takeA3,
         "\nTakeA4: ", takeA4,
         "\nTakeA5: ", takeA5,
         "\nTakeA6: ", takeA6,
         "\nTakeA7: ", takeA7,
         "\n---------------",
         "\nTarget: Price + 10pts",
         "\nPriceHigh: ",pricehigh,
         "\nPriceLow: ",pricelow,
         "\nTakeB: ", takeB,
         "\nTakeB1: ", takeB1,
         "\nTakeB2: ", takeB2,
         "\nTakeB3: ", takeB3,
         "\nTakeB4: ", takeB4,
         "\nTakeB5: ", takeB5,
         "\nTakeB6: ", takeB6,
         "\nTakeB7: ", takeB7,
         "\n---------------",
         "\nTest01: ", teste1,
         "\nTest02: ", teste2
         );
     
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
      
      
   
  }
//+------------------------------------------------------------------+
 
diegotfcastro:
....

tenta algo assim...

#define ASK SymbolInfoDouble(Symbol(), SYMBOL_ASK)
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   Custom *custom=new Custom(Symbol());
   Print("Sem normalização: ", ASK);
   Print("Com normalização: ",custom.NormalizePrice(ASK+custom.StepToPrice(2)));
   
   
   
   delete custom;
  }
//+------------------------------------------------------------------+
class Custom
  {
private:
   int               m_digits;
   string            m_symbol;
public:
                     Custom(string symbol) : m_symbol(symbol) {  }

   double            NormalizePrice(const double price) const
     {
      return(NormalizeDouble(price,m_digits));
     }
   double            StepToPrice(int price_step)
     {
      double price = SymbolInfoDouble(m_symbol, SYMBOL_POINT)*(double)price_step;
      return price;
     }
  };
 
Jonathan Pereira:

tenta algo assim...

Mesmo assim, 

olha o codigo que estou recebendo de erro:



tudo o que eu queria era poder utilizar essas valores:


               double pr2  = rates[1].low;
               double sl2 = _symb.NormalizePrice(rates[1].high + stoploss);
               double tp2 = _symb.NormalizePrice(pr2 - takeprofit);
 
diegotfcastro:

...

Vc esta mandando volume 0, vai tomar erro mesmo.

E mais uma obs. da forma que eu lhe mostrei funciona em qualquer ativo, basta usar a pontuação de cada ativo.

exemplo

indice : 1,2,3..

Dolar:0.500,1000,1500,.....

ações 0.01,0.02,....

 
Jonathan Pereira:

Vc esta mandando volume 0, vai tomar erro mesmo.

Meu lote é dinamico, eu uso isso aqui como função auxiliar:


double Lote()
{

     current_vol = LastVolume();
     double vol_initial = lot;
     double ticksize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);

     if(LastResult() < 0 && Recover == 1) { //Martingale
          current_vol *= VolumeMult;
          if(current_vol > VolumeMax) {
               current_vol = VolumeMax;
          }

     } else if(LastResult() > 0 && Recover == 2) { //AntiMartingale
          current_vol *= VolumeMult;
          if(current_vol > VolumeMax) {
               current_vol = VolumeMax;
          }

     } else if(LastResult() > 0 && Recover == 3) { //SorosWin
          current_vol += lot;
          if(current_vol > VolumeMax) {
               current_vol = VolumeMax;
          }

     } else if(LastResult() < 0 && Recover == 4) { //SorosLoss
          current_vol += lot;
          if(current_vol > VolumeMax) {
               current_vol = VolumeMax;
          }

     } else if(LastResult() <= 0 && Recover == 5) { //Kamikaze
           current_vol = MathRound(MathAbs(LastResult())/((takeprofit)/ticksize));

     } else {

          current_vol = vol_initial;

     }

     return current_vol;

}
 
diegotfcastro:

Meu lote é dinamico, eu uso isso aqui como função auxiliar:


Tentei mudar para isso, vou testar:


current_vol = (LastVolume()<=0) ? 1 : LastVolume();
 
diegotfcastro:

...

não faça assim...pois em mercados com lotes maiores ou menores dara erro.


faz assim, no OnInit()


   static double lotTemp = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MIN);

   if(m_lot < lotTemp)
      m_lot = lotTemp;
 
Jonathan Pereira:

não faça assim...pois em mercados com lotes maiores ou menores dara erro.


faz assim, no OnInit()


Eu tentei mas não deu.

acho que essa função de calculo de lot que eu fiz que está muito "porca", vou refazer.. mtos ifs.. elses.. nuncam dão certo.

 
diegotfcastro:

Eu tentei mas não deu.

acho que essa função de calculo de lot que eu fiz que está muito "porca", vou refazer.. mtos ifs.. elses.. nuncam dão certo.

double Lote()
  {

   if(current_vol <= lot)
      current_vol = lot;
   else(current_vol = LastVolume());

   if(LastResult() < 0 && Recover == 1)       //Martingale
      current_vol *= VolumeMult;
   if(current_vol > VolumeMax)
      current_vol = VolumeMax;
   else
      if(LastResult() > 0 && Recover == 2)   //AntiMartingale
         current_vol *= VolumeMult;
   if(current_vol > VolumeMax)
      current_vol = VolumeMax;
   else
      if(LastResult() > 0 && Recover == 3)   //SorosWin
         current_vol += current_vol;
   if(current_vol > VolumeMax)
      current_vol = VolumeMax;
   else
      if(LastResult() < 0 && Recover == 4)   //SorosLoss
         current_vol += current_vol;
   if(current_vol > VolumeMax)
      current_vol = VolumeMax;
   else
      if(LastResult() < 0 && Recover == 5)   //Kamikaze
         current_vol = MathRound(MathAbs(LastResult())/((takeprofit)/ticksize));
      else
         current_vol = lot;

   return current_vol;

  }