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

 
Vitaly Muzichenko:

比较下一个小节,如果序列被打破,重置标志并记录有多少个是正确的,然后继续循环。

只要发现这个柱子是看涨的,下一个柱子是看跌的,下一个柱子,如果和上一个柱子一样,你就写下这个值,然后重新设置旗帜。就这样一直到最后。

但第一个可能不是看涨的。

   for(int i=limit-1; i>0; i--)

     {


      if(open[i]<close[i]&&open[i+1]>close[i+1]&&open[i+3]<close[i+3])

        {

         up++;

        }

      else up=0;

    
    
if(max_c<up)max_c=up;

Comment(max_c);
}

//--- return value of prev_calculated for next call

   return(rates_total);

  }

 
PolarSeaman:

但第一个可能不是公牛,没办法。

这里有一个变体,虽然不完全正确,但总是从看跌的蜡烛开始计算

附加的文件:
aCandle.mq4  8 kb
 
Vitaly Muzichenko:

这里有一个变体,虽然不完全正确,但总是从看跌的蜡烛开始计算

谢谢你。如果你将这个数字平方并加一,结果是正确的。

是否检查if(i%2==0)?
 
PolarSeaman:

但第一个可能不是公牛,没办法。


下面是一个找到相同的蜡烛并改变链条方向的例子。

//+------------------------------------------------------------------+
//|                                              CandlesSequence.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                             https://mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link      "https://mql5.com/ru/users/artmedia70"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   1
//--- plot Sequence
#property indicator_label1  "Sequence"
#property indicator_type1   DRAW_COLOR_HISTOGRAM
#property indicator_color1  clrGreen,clrRed,clrGray
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
//--- enums
enum ENUM_CANDLE_TYPE
  {
   CANDLE_TYPE_BULL  =  0,       // Bullish candle
   CANDLE_TYPE_BEAR  =  1,       // Bearish candle
   CANDLE_TYPE_DOJI  = -1        // Doji candle
  };
//--- indicator buffers
double         BufferSeq[];
double         BufferSeqColors[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,BufferSeq,INDICATOR_DATA);
   SetIndexBuffer(1,BufferSeqColors,INDICATOR_COLOR_INDEX);
//--- setting indicator parameters
   IndicatorSetString(INDICATOR_SHORTNAME,"Candles sequence");
   IndicatorSetInteger(INDICATOR_DIGITS,Digits());
//--- setting buffer arrays as timeseries
   ArraySetAsSeries(BufferSeq,true);
   ArraySetAsSeries(BufferSeqColors,true);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//--- Проверка на минимальное колиество баров для расчёта
   if(rates_total<2) return 0;
//--- Установка массивов буферов как таймсерий
   ArraySetAsSeries(open,true);
   ArraySetAsSeries(high,true);
   ArraySetAsSeries(low,true);
   ArraySetAsSeries(close,true);
   ENUM_CANDLE_TYPE type_refs=CANDLE_TYPE_DOJI;
   ENUM_CANDLE_TYPE type_curr=CANDLE_TYPE_DOJI;
//--- Проверка и расчёт количества просчитываемых баров   
   int limit=rates_total-prev_calculated;
   if(limit>1)
     {
      limit=rates_total-2;
      ArrayInitialize(BufferSeq,EMPTY_VALUE);
      BufferSeq[rates_total-1]=open[rates_total-1];
     }
//--- Расчёт индикатора
   for(int i=limit; i>=0 && !IsStopped(); i--)
     {
      type_refs=GetTypeCandle(i+1,open,close);
      type_curr=GetTypeCandle(i,open,close);
   //--- смена направления цепочки свечей
      if(!CheckCandle(type_refs,type_curr))
        {
         BufferSeq[i]=(type_curr==CANDLE_TYPE_BULL ? low[i]: type_curr==CANDLE_TYPE_BEAR ? high[i]: open[i]);
        }
   //--- свечи одного типа
      else
        {
         BufferSeq[i]=BufferSeq[i+1];
        }
      BufferSeqColors[i]=(type_curr==CANDLE_TYPE_BULL ? 0 : type_curr==CANDLE_TYPE_BEAR ? 1 : 2);
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Возвращает тип свечи                                             |
//+------------------------------------------------------------------+
ENUM_CANDLE_TYPE GetTypeCandle(const int shift,const double &open[],const double &close[])
  {
   return(close[shift]>open[shift] ? CANDLE_TYPE_BULL : close[shift]<open[shift] ? CANDLE_TYPE_BEAR : CANDLE_TYPE_DOJI);
  }
//+------------------------------------------------------------------+
//| Сравнивает два типа свечей                                       |
//+------------------------------------------------------------------+
bool CheckCandle(const ENUM_CANDLE_TYPE reference_candle_type,const ENUM_CANDLE_TYPE checked_candle_type)
  {
   return(reference_candle_type==checked_candle_type ? true : false);
  }
//+------------------------------------------------------------------+

现在,在链子继续的地方,你可以计算链子上的蜡烛数量,并保存到一个列表中,在链子变化到新的地方,开始新的计算。

每条链中的蜡烛数量可以存储在一个排序的列表中。然后,通过对列表进行排序,可以找到最大 和最小的序列。

 
PolarSeaman:

谢谢你。如果得到的数字经过平方,再加上1,结果就是正确的。

这就是我们要检查的if(i%2==0)吗?

如果i是2的倍数。

它是i的余数 除以2的结果。

 
Juer:

在这里,局部变量的大小在编译过程中过大(超过512kb)。

去哪里找,做什么?函数中有一个字符串数组CArrayString,我怀疑这可能是一个错误。

我使用Add()方法填充它,然后再次做Clear()Shutdown()。然后我用Add()方法再次填充新的数据。在这种情况下,数组是否又会被填充为零项?

我们必须从编译阶段已经占用内存的类中删除这些成员。这些数据将被分配到堆栈内存中,堆栈内存总是非常小。解决这个问题的方法是为占用大量内存的类成员动态地分配内存。

例如,如果有一个类成员。

class A
{
   double m_arrfArray[9999999];
};

它应该被替换成。

class A
{
   double m_arrfMyArray[];
};

bool A::Init()
{
   if (ArrayResize(m_arrfMyArray, 9999999) != 9999999)
      return false;
   ....
}
 
Ihor Herasko:

我们需要从类中删除那些在编译阶段已经占用内存的成员。这些数据将被放在堆栈内存中,堆栈内存总是非常小。解决这个问题的方法是为占用大量内存的类成员动态地分配内存。

例如,如果有一个类成员。

那么它应该被替换为。

谢谢。不知何故,我通过从每个函数的参数中删除类来摆脱了这个问题。一般来说,可以对所有的方法初始化一次这个对象。

我还有一个关于CArray类的 问题,更确切地说,是CArrayObj。是否有一个Delete()方法,但它不会移动数组中的一个元素?也就是说,我删除了Delete(18),它在这个位置删除了一个项目,以后如果我想通过这个索引查询这个项目,我得到一个无效的指针。是否有这样一种方法,可以删除和移动元素,以便在这种情况下,第18个元素在删除后成为第19个元素?

 
Juer:

谢谢你。不知何故,我从每个函数的参数中删除了类,从而摆脱了这个问题。一般来说,可以对所有的方法初始化一次这个对象。

我还有一个关于CArray类的 问题,更确切地说,是CArrayObj。是否有一个Delete()方法,但它不会移动数组中的一个元素?也就是说,我删除了Delete(18),它在这个位置删除了一个项目,以后如果我想通过这个索引查询这个项目,我得到一个无效的指针。有没有这样一种方法,可以删除和移动项目,使第18个项目在删除后成为第19个项目?

我没有使用过标准库,但是根据帮助,Delete()方法应该是物理地移除元素,改变数组的大小。例外:如果内存管理机制被禁用。默认情况下,这个机制是启用的。FreeMode方法是用来检查内存管理标志的状态。

就我而言,我建议在MQL中使用自己的数组(尽管在C++中我使用向量和列表),并自己进行内存管理,因为我在CArray类中没有看到任何特别的便利或优势。我使用这种方法相当快地删除了我自己数组中的数组项。

template<typename Array>
bool DeleteArrayElement(Array &array[], int nIndex)
{
   int nArraySize = ArraySize(array);
   if (nIndex < 0 || nIndex >= nArraySize)
      return true;
   
   array[nIndex] = array[nArraySize - 1];
   return (ArrayResize(array, nArraySize - 1, ARRAY_RESERVE_SIZE) == nArraySize - 1);
}

它唯一的缺点是不能保持数组项目的顺序。也就是说,它可以应用于所有数组,除了有序(排序)的数组。

 

你好,请你告诉我在哪里可以找到一个脚本,可以让我在MT4中一次性下达距离当前价格一定点数的买入 和卖出挂单,也就是说不需要手动计算,也许甚至不需要进入订单窗口?我不想进入订单窗口。 谢谢。

PS: 也许我问错了,我以前从来没有使用过脚本。

 

请给我解释一下这一点--"如果市场订单的StopLoss或TakeProfit值违反FreezeLevel参数,则不能关闭。"

这是否意味着,如果一个市场订单的获利或止损不符合FreezeLevel,就不能关闭?我只是不太明白,一个公开市场订单怎么会有违反StopLevel或FreezeLevel规则的止损?毕竟,如果设置了错误的止损点,服务器将只是给出一个错误,而不会设置任何止损点。

另外,请告诉我们,当经纪人使用FreezeLevel时,在关闭市场订单时,我们还需要知道什么?

Требования и ограничения при проведении торговых операций - Приложения - Учебник по MQL4
Требования и ограничения при проведении торговых операций - Приложения - Учебник по MQL4
  • book.mql4.com
В таблицах указаны расчётные значения, ограничивающие проведение торговых операций при открытии, закрытии, установке, удалении и модификации ордеров. Для получения значения минимальной дистанции StopLevel и дистанции заморозки FreezeLevel необходимо вызвать функцию MarketInfo(). Требования. Правильные цены, используемые при осуществлении...
原因: