新人对MQL4和MQL5的任何问题,对算法和代码的帮助和讨论 - 页 1046

 

马什卡的标准代码

#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);
  }

我没有粘贴所有的代码,因为下一步是计算,问题是与初始化有关的

如何使"InpMAPeriod"值在时间框架变化时发生变化。

例如:在M15 -"InpMAPeriod"

在M30 -"InpMAPeriod2"。

我不是一个程序员,请帮助。

 

我很疑惑--要么是我的眼睛在撒谎,要么是我错过了什么


下面是计算公式(你不必深入了解,注意打印输出条件和return()里面的计算--黄色背景的代码)。

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));
  }

...在这一步,所有的值都正确地返回在1到-1的范围内。


但当这些值从缓冲区打印出来时,范围就被打破了(在缓冲区内,范围已经是100到-100)。

以下是这个周期本身

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]);
     };


在延缓器内,没有加法,只有乘以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;
     };
   
  }


有什么问题呢?

 
Alexandr Sokolov:

我很疑惑--要么是我的眼睛在撒谎,要么是我错过了什么

有什么问题呢?

我完全不理解这些代码。

*100
尝试改变为100.0
 
Vitaly Muzichenko:

对代码一点也不熟悉。

尝试用100.0代替

试过了,没有用。

 
ukrop1203:
你好,我在完成一個 ekspert 測試後得到一個關於不成功的物件的錯誤,而我絕對是在堆疊中創建了所有的物件,據我所知,也就是沒有新的。请解释这个问题。

第2项尝试,请回答问题。

 
ukrop1203:

第2项尝试,请回答问题。

奇迹不会发生,如果它说它被泄露了,那就意味着你把它丢在某个地方,忘记了它。搜索一下吧。或者,在构造函数中插入

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

并在调试器下面,抓一个点。

 
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 order by opposite order first ticket=2, second ticket=3, error=3

2018.01.02 08:01:30 第一笔订单选择=true, 订单类型=1, 订单价格=1.351920

2018.01.02 08:01:30 第二笔订单选择=true, 订单类型=0, 订单价格=1.351590


不关闭两个柜台的订单,请解释。

 

为什么有两个垂直画线 的重载函数被编译器认可(第一个函数--颜色选择,第二个--颜色和窗口),而且你可以使用这两个函数,但当我添加第三个函数,包括颜色、窗口和样式选择时,它发誓并强迫所有函数为第三种类型?


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:

为什么有两个垂直画线 的重载函数被编译器认可(第一个函数--颜色选择,第二个--颜色和窗口),而且你可以使用这两个函数,但当我添加第三个函数,包括颜色、窗口和样式选择时,它发誓并强迫所有函数都是第三种类型?


默认值否定了输入参数的存在。考虑到它并不存在。并看看编译器是否能选择正确的函数。

 
ukrop1203:

它没有关闭两个反订单,请解释。

理论上,你的代码应该是有效的,我可能是错的,但不是所有的经纪商都允许这样做,尝试Metakvotes-demo来检查,它肯定在那里工作。

原因: