Quaisquer perguntas de recém-chegados sobre MQL4 e MQL5, ajuda e discussão sobre algoritmos e códigos - página 1046

 

O código padrão do Mashka

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//--- indicator parameters
input int            InpMAPeriod=13;        // Period
input int            InpMAShift=0;          // Shift
input ENUM_MA_METHOD InpMAMethod=MODE_SMA;  // Method
//--- indicator buffer
double ExtLineBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(void)
  {
   string short_name;
   int    draw_begin=InpMAPeriod-1;
//--- indicator short name
   switch(InpMAMethod)
     {
      case MODE_SMA  : short_name="SMA(";                break;
      case MODE_EMA  : short_name="EMA(";  draw_begin=0; break;
      case MODE_SMMA : short_name="SMMA(";               break;
      case MODE_LWMA : short_name="LWMA(";               break;
      default :        return(INIT_FAILED);
     }
   IndicatorShortName(short_name+string(InpMAPeriod)+")");
   IndicatorDigits(Digits);
//--- check for input
   if(InpMAPeriod<2)
      return(INIT_FAILED);
//--- drawing settings
   SetIndexStyle(0,DRAW_LINE);
   SetIndexShift(0,InpMAShift);
   SetIndexDrawBegin(0,draw_begin);
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtLineBuffer);
//--- initialization done
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|  Moving Average                                                  |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//--- check for bars count
   if(rates_total<InpMAPeriod-1 || InpMAPeriod<2)
      return(0);
//--- counting from 0 to rates_total
   ArraySetAsSeries(ExtLineBuffer,false);
   ArraySetAsSeries(close,false);
//--- first calculation or number of bars was changed
   if(prev_calculated==0)
      ArrayInitialize(ExtLineBuffer,0);
//--- calculation
   switch(InpMAMethod)
     {
      case MODE_EMA:  CalculateEMA(rates_total,prev_calculated,close);        break;
      case MODE_LWMA: CalculateLWMA(rates_total,prev_calculated,close);       break;
      case MODE_SMMA: CalculateSmoothedMA(rates_total,prev_calculated,close); break;
      case MODE_SMA:  CalculateSimpleMA(rates_total,prev_calculated,close);   break;
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }

Não estou colando todo o código, já que o próximo passo são os cálculos, a questão está relacionada à inicialização

Como fazer com que o valor"InpMAPeriod" mude quando o prazo mudar.

Por exemplo: no M15 -"Período InpMAP".

Na M30 -"InpMAPeriod2".

Eu não sou um programador, por favor, ajude-me.

 

Estou intrigado - ou meus olhos estão mentindo, ou estou perdendo algo


Aqui está a fórmula de cálculo (você não precisa entrar em tudo, preste atenção às condições de impressão e cálculo dentro do retorno() - código em fundo amarelo)

double Phase_Value_2(int index, double point, int period)
  {
   
   double muving = 0, flat = 0, up = EMPTY_VALUE, down = EMPTY_VALUE;
   int limit = index + (period > 1 ? period : 1);
   for(int i = index; i < limit; i++)
     {
      if(High[i] <= High[i+1] && Low[i] >= Low[i+1])
        {
         flat += High[i] - Low[i];
        }
      else if(MathMax(High[i],High[i+1]) - MathMin(Low[i],Low[i+1]) < High[i] - Low[i] + High[i+1] - Low[i+1])
        {
         muving += High[i] - Low[i];
        }
      else
        {
         up     = (High[i] > High[i+1] ? High[i] - High[i+1] : 0);
         down   = (Low[i] < Low[i+1] ? Low[i+1] - Low[i] : 0);
         muving += up + down;
         up     = MathMin(High[i],High[i+1]);
         down   = MathMax(Low[i],Low[i+1]);
         flat   += up - down;
        };
     };
   
   muving = (muving == 0 ? 1 * point : muving);
   flat   = (flat == 0 ? 1 * point : flat);
   if(flat <= muving && flat / muving > 1) Print("index ",(string)index," ",(string)flat," / ",(string)muving," = ",(string)(flat/muving));
  //-----------------------------------------------------------------
   return(muving < flat ? (1 - (muving / flat)) * (-1) : 1 - (flat / muving));
  }

... Nesta etapa, todos os valores são corretamente devolvidos na faixa de 1 a -1


Mas quando esses valores são impressos a partir do buffer - o intervalo é quebrado (no buffer, o intervalo já é de 100 a -100)

Aqui está o ciclo em si

for(int i = limit_slowing; i >= 0; i--)
     {
      if(p_slowing > 1) {Slowing(i,(int)p_slowing,p_method,P);}
      else              {P[i] = Phase_Value_2(i,_Point,(int)p_period) * 100;}; if(P[i] > 100 || P[i] < -100) Print("index ",(string)i,", value ",(string)P[i]);
     };


Dentro do retardador, não há adição, apenas multiplicação por 100

void Slowing(int index, int slowing, ENUM_MA_METHOD method, double &Bufer[])
  {
   
   double value = 0, c = 2 / (double)(slowing+1); int limit, period = slowing, sum_period = 0;
   
   if(method == MODE_SMA)
     {
      limit = index + slowing;
      for(int i = index; i < limit; i++) value += Inhibitor[i];
      Bufer[index] = (value / (double)slowing) * 100;
     }
   
   else if(method == MODE_EMA)
     {
      if(Bufer[index+1] == EMPTY_VALUE)
        {
         limit = index + slowing;
         for(int i = index; i < limit; i++) value += Inhibitor[i];
         Bufer[index] = (value / (double)slowing) * 100; return;
        };
      Bufer[index] = (c * Inhibitor[index] + (1-c) * (Bufer[index+1]/100)) * 100;
     }
   
   else if(method == MODE_SMMA)
     {
      if(Bufer[index+1] == EMPTY_VALUE)
        {
         limit = index + slowing;
         for(int i = index; i < limit; i++) value += Inhibitor[i];
         Bufer[index] = (value / (double)slowing) * 100; return;
        };
      if(Bufer[index+1] != EMPTY_VALUE && Bufer[index+2] == EMPTY_VALUE)
        {
         limit = index + slowing;
         for(int i = index; i < limit; i++) value += Inhibitor[i];
         Bufer[index] = ((value - (Bufer[index+1]/100) + Inhibitor[index]) / (double)slowing) * 100; return;
        };
      value = (Bufer[index+1]/100) * (double)slowing;
      Bufer[index] = ((value - (Bufer[index+1]/100) + Inhibitor[index]) / (double)slowing) * 100;
     }
   
   else
     {
      limit = index + slowing;
      for(int i = index; i < limit; i++)
        {
         value += Inhibitor[i] * (double)period;
         sum_period += period; period--;
        };
      Bufer[index] = value / (double)sum_period * 100;
     };
   
  }


Qual é o problema?

 
Alexandr Sokolov:

Estou intrigado - ou meus olhos estão mentindo ou estou perdendo algo

Qual é o problema?

Eu não entendia nada do código.

*100
tente mudar para 100,0
 
Vitaly Muzichenko:

Não estou de modo algum familiarizado com o código.

tente substituir por 100,0

Experimentei, não funcionou.

 
ukrop1203:
Olá, recebo um erro sobre objetos mal sucedidos após completar um teste ekspert, e crio absolutamente todos os objetos, até onde entendo, na pilha, ou seja, sem novos. Por favor, explique esta pergunta.

Tentativa número 2, por favor, responda à pergunta.

 
ukrop1203:

Tentativa número 2, por favor, responda à pergunta.

Milagres não acontecem, se diz que vazou, significa que você o deixou em algum lugar na pilha e o esqueceu. Procure por ela. Alternativamente, no inserto do construtor

if (CheckPointer(&this)==POINTER_DYNAMIC) DebugBreak();

e embaixo do depurador, pegue um lugar.

 
bool CloseByBu(OpenModel& open_model) { 
   bool closed_by_bu = False;
   if (OrderSelect(open_model.bu_ticket, SELECT_BY_TICKET, MODE_TRADES) && OrderType() <= 1) {
      closed_by_bu = OrderCloseBy(open_model.bu_ticket, open_model.ticket);   
      if (!closed_by_bu) {         
         PrintMessageInLog(StringFormat("DIDN'T CLOSE order by opposite order first ticket=%i, second ticket=%i, error=%i", 
			   		 open_model.ticket, open_model.bu_ticket, GetLastError()));         
         PrintMessageInLog(StringFormat("First order selected=%s, order type=%i, order price=%f", 
                           		string(OrderSelect(open_model.ticket, SELECT_BY_TICKET, MODE_TRADES)), OrderType(), OrderOpenPrice()));
         PrintMessageInLog(StringFormat("Second order selected=%s, order type=%i, order price=%f", 
                           		string(OrderSelect(open_model.bu_ticket, SELECT_BY_TICKET, MODE_TRADES)), OrderType(), OrderOpenPrice()));                                       
      }
   }   
   return closed_by_bu;
}

2018.01.02 08:01:30 DIDN'T CLOSE encomenda por encomenda oposta primeiro bilhete=2, segundo bilhete=3, erro=3

2018.01.02 08:01:30 Primeiro pedido selecionado=verdadeiro, tipo de pedido=1, preço do pedido=1.351920

2018.01.02 08:01:30 Segundo pedido selecionado=verdadeiro, tipo de pedido=0, preço do pedido=1.351590


Não fechar duas contra-ordens, por favor explique.

 

Por que 2 funções sobrecarregadas de desenho vertical são aprovadas pelo compilador (primeira função - seleção de cor, segunda - cor e janela) e você pode usar ambas, mas quando eu adiciono a terceira, com seleção de cor, janela e estilo - jura e força todas as funções a serem do terceiro tipo?


void VLine(int window=0) {
 
  
 string nm="VLINE"+(string)(Time[0]);
 
   if (ObjectFind(nm)<0) ObjectCreate(nm, OBJ_VLINE, window, 0,0);
  ObjectSet(nm, OBJPROP_TIME1, Time[0]);
  ObjectSet(nm, OBJPROP_COLOR, Red);
  ObjectSet(nm, OBJPROP_STYLE, 0);
  ObjectSet(nm, OBJPROP_WIDTH, 1);
  ObjectSetString(0,nm, OBJPROP_TOOLTIP,"\n");
}


void VLine(color cl, int window=0) {
 
  
 string nm="VLINE"+(string)(Time[0]);
 
   if (ObjectFind(nm)<0) ObjectCreate(nm, OBJ_VLINE, window, 0,0);
  ObjectSet(nm, OBJPROP_TIME1, Time[0]);
  ObjectSet(nm, OBJPROP_COLOR, cl);
  ObjectSet(nm, OBJPROP_STYLE, 0);
  ObjectSet(nm, OBJPROP_WIDTH, 1);
  ObjectSetString(0,nm, OBJPROP_TOOLTIP,"\n");
}




void VLine(color cl, int window=0, int style=0) {
 
 
 string nm="STOPLINE"+(string)(Time[0]);
 
   if (ObjectFind(nm)<0) ObjectCreate(nm, OBJ_VLINE, window, 0,0);
  ObjectSet(nm, OBJPROP_TIME1, Time[0]);
  ObjectSet(nm, OBJPROP_COLOR, cl);
  ObjectSet(nm, OBJPROP_STYLE, style);
  ObjectSet(nm, OBJPROP_WIDTH, 1);
  ObjectSetString(0,nm, OBJPROP_TOOLTIP,"\n");
}
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Типы объектов
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Типы объектов
  • www.mql5.com
При создании графического объекта функцией ObjectCreate() необходимо указать тип создаваемого объекта, который может принимать одно из значений перечисления ENUM_OBJECT. Дальнейшие уточнения свойств созданного объекта возможно с помощью функций по работе с графическими объектами.
 
Viatcheslav Pashkov:

Por que 2 funções sobrecarregadas de desenho vertical são aprovadas pelo compilador (primeira função - seleção de cor, segunda - cor e janela) e você pode usar ambas, mas quando eu adiciono a terceira, com seleção de cor, janela e estilo - jura e força todas as funções a serem do terceiro tipo?


Os valores padrão negam a presença do parâmetro de entrada. Considere que ela não existe. E veja se o compilador pode selecionar a função correta.

 
ukrop1203:

Ele não fecha duas contra-ordens, por favor explique.

Em teoria seu código deveria funcionar, eu poderia estar errado, mas nem todos os corretores permitem fazer isso, tente Metakvotes-demo para verificar, ele definitivamente funcionou lá