Небольшая помощь в простом советнике

 

Здравствуйте. Некоторое время назад реашил изучать MQL4, чтобы впоследствии воплотить в советнике свою торговую стратегию.

Изучение языка идет своим чередом, все отлично.

Для закрепления базовых знаний решил написать простой советник, торгующий по 3ём индикаторам:

  • Heiken Ashi
  • Slope Direction Line
  • MA Rsi

Возникла небольшая проблема: Советник открывает только длинные позиции (Buy).

Мне кажется что я, что-то напортачил в параметрах MA Rsi.

Ниже помещаю код советника:

#property copyright "WAK"
#property link "----"

//--------------------------------------------------------------------
extern string s0 = "Setup: Main";
extern int Magic = 1121;
extern double lots = 0.1;
extern int StopLoss = 10;
extern int TakeProfit = 40;

extern string s1 = "Setup: MA_rsi";
extern int maPeriod = 50;
extern int maMethod = MODE_EMA;
extern int maPrice = PRICE_CLOSE;
extern int rsiPeriod = 40;
extern int rsiLevel = 50;

extern string s2 = "Setup: Slope_Direction_Line";
extern int period = 20; 
extern int method = 3; // MODE_SMA 
extern int price = 0; // PRICE_CLOSE
int slip = 3;



//--------------------------------------------------------------------
//The main condition--------------------------------------------------
int start ()
{
  static datetime TimeFlag = 0;
  datetime TimeLast = Time[0];
  if (TimeFlag < TimeLast)
  {
  TimeFlag = TimeLast;
   
  int HA = GetSignal_HA();
  int MA = GetSignal_MA();
  int SD = GetSignal_SD();

  AnalyzeSignals(HA, MA, SD);
   
  }
  return (0);

}

void AnalyzeSignals(int HA, int MA, int SD)
{
  int res;
   
  if(HA == OP_BUY && MA == OP_BUY && SD == OP_BUY) //Buy
  {
  res = OrderSend(Symbol(), OP_BUY, lots, Ask, slip, Bid - StopLoss*Point, Bid + TakeProfit*Point, NULL, Magic);
  if(res < 0) {Alert("Oreder Sent Error", GetLastError());}
  }
   
  else if(HA == OP_SELL && MA == OP_SELL && SD == OP_SELL) //Sell
  {
  res = OrderSend(Symbol(), OP_SELL, lots, Bid, slip, Ask + StopLoss*Point, Ask - TakeProfit*Point, NULL, Magic);
  if(res < 0) {Alert("Oreder Sent Error", GetLastError());}
  }
}

//--------------------------------------------------------------------
//Indicators funktion-------------------------------------------------
// Heiken Ashi

int GetSignal_HA()
{
  double ha0 = iCustom(NULL, 0, "HeikenAshi_DM", 0, 1); 
  double ha1 = iCustom(NULL, 0, "HeikenAshi_DM", 1, 1); 
   
  if(ha0 > ha1)
  return(OP_SELL);
  else if(ha0 < ha1)
  return(OP_BUY);
  else
  return(-1);
}

//--------------
// MA RSI

int GetSignal_MA()
{
  double ma0 = iCustom(NULL, 0, "MA_rsi", maPeriod, maMethod, maPrice, rsiPeriod, rsiLevel, 0, 1);
  double ma1 = iCustom(NULL, 0, "MA_rsi", maPeriod, maMethod, maPrice, rsiPeriod, rsiLevel, 1, 1);
   
  if(ma0 < ma1)
  return(OP_BUY);
  else if(ma0 > ma1)
  return(OP_SELL);
  else
  return(-1); 
}

//--------------
// Slope Direction Line

int GetSignal_SD()
{
  double sd0 = iCustom(NULL, 0, "Slope_Direction_Line", period, method, price, 0, 1); 
  double sd1 = iCustom(NULL, 0, "Slope_Direction_Line", period, method, price, 1, 1); 
   
  if(sd0 > 0.0)
  return(OP_BUY);
  else if(sd1 > 0.0)
  return(OP_SELL);
  else
  return(-1);  
}
//-------------------------------------------------------------------




Индикаторы и советник

Надеюсь на помощь.

Спасибо за внимание.

 

А почему в индикаторе "Slope_Direction_Line" не определены размерности массивов trend[] и vect[]?

 
WAK >>:


Вы то хоть код индюков смотрели ?

1.

У Хейкин нужно сравнивать не 0 и 1 а 2 и 3 буферы - то есть хейкинопен с хейкинклозе - именно от этого зависит цвет свечи.

2.

В Slope_Direction_Line сравнивать нужно не с нулем, а с EMPTY_VALUE - это по умолчанию макс инт - 2Гига, то есть всегда больше нуля. Либо приравняйте нулю в коде индюка, либо в инит индикатора установите EMPTY_VALUE в ноль - есть такая функция, думаю найдете.

Удачи.

 
Roger >>:

А почему в индикаторе "Slope_Direction_Line" не определены размерности массивов trend[] и vect[]?

Там динамически переразмещаются массивы

ArrayResize(vect, e); 
  ArraySetAsSeries(vect, true);
  ArrayResize(trend, e); 
  ArraySetAsSeries(trend, true); 

- не самое мудрое решение...

Удачи.

 
VladislavVG >>:

Вы то хоть код индюков смотрели ?

1.

У Хейкин нужно сравнивать не 0 и 1 а 2 и 3 буферы - то есть хейкинопен с хейкинклозе - именно от этого зависит цвет свечи.

так?

  double ha2 = iCustom(NULL,0, "HeikenAshi",2,0);
  double ha3 = iCustom(NULL,0, "HeikenAshi",3,0);
   

  if(ha2 > ha3)
  return(OP_BUY);
  else if(ha2 < ha3)
  return(OP_SELL);
  else
  return(-1);




 
WAK >>:

так?




Примерно - сейчас повторно смотреть код не буду - лень. Посмотрите в коде индикатора есть хейкин опен (хо) и хейкин клозе (хк) - там по названию переменных понятно. Если хк>хо бай, если меньше, селл.

Вы второй индюк поправьте - а то только на бай будут сигналы.

Успехов.

 

Ещё раз хочу выразить огромную благодарность за помощь. Спасибо большое.


так, вот последние 2 индикатора с учетом исправлений ошибок:

//--------------
// MA RSI

int GetSignal_MA()
{
      double ma0 = iCustom(NULL, 0, "MA_rsi", maPeriod, maMethod, maPrice, rsiPeriod, rsiLevel, 0, 1);
      double ma1 = iCustom(NULL, 0, "MA_rsi", maPeriod, maMethod, maPrice, rsiPeriod, rsiLevel, 1, 1);
      
   if(ma0 < ma1)
      return(OP_BUY);
   else if(ma0 > ma1)
      return(OP_SELL);
   else
      return(-1); 
}

//--------------
// Slope Direction Line

int GetSignal_SD()
{
      double sd0 = iCustom(NULL, 0, "Slope_Direction_Line", period, method, price, 0, 1); 
      double sd1 = iCustom(NULL, 0, "Slope_Direction_Line", period, method, price, 1, 1); 
   
   if(sd0 == EMPTY_VALUE)
      return(OP_BUY);
   else if(sd1 == EMPTY_VALUE)
      return(OP_SELL);
   else
      return(-1);    
}
//--------------------------------------------------------------------


но что-то всеравно не так, сигналы пропускаются, сделки открываются когда сигналы не совпадают

вообщем где-то косяк и не один :)

 

Решил я кратенько описать возможности будущего советника, может ещё появятся желающие помочь?

Итак:

Рассмотрим тяжелейший уровень минутного флета.
Примем величину СтопЛосса равной 7 пунктов (для минутного графика вполне хватит)
Также я планирую для минутного графика закрывать позиции по трейл-стопу, стоп лосс должен висеть около цены на расстоянии примерно 7-5 пунктов (для М1). Также есть идея на счет перемещения уровня СтопЛосса на цену открытия ордера (убыток/прибыль +-0), после прохождения цены в плюс на 4-5 пунктов (требует оптимизации)


1. Возникает правдивый сигнал на покупку. Тренд с небольшим откатом проходит 45 пунктов. (+45)
2. Возникает правдивый сигнал на продажу. +35
3. После сигнала на покупку цена проходит около 20 пунктов, хватит чтоб выставить СтопЛосс на безубыток и даже немного быть в плсюсе
4. Продажа. Чуть более 20 пунктов
5. Обманчивый сигнал на продажу. (минус 7-5 пунктов, стоплосс)
6. Обман на покупку (стоплосс, минус 7-5 пунктов)
7. Около 10 пунктов, хватит чтоб поставит СтопЛосс на безубыток
8. Обман на продажу (СтопЛосс, минус 7-5 пунктов)
9. Тренд. +40 пунктов (минимум, рисунок кончился)

Итого на минутом графике:

45+35+40 = 120 пунктов
-7-7-7 = -21 пунктов

Это минутный график, также можно использовать любой другой, там будет гораздо проще.


1


и это всеголишь 4 часа

так что смотрите, оценивайте



 
WAK >>:

Ещё раз хочу выразить огромную благодарность за помощь. Спасибо большое.


так, вот последние 2 индикатора с учетом исправлений ошибок:


но что-то всеравно не так, сигналы пропускаются, сделки открываются когда сигналы не совпадают

вообщем где-то косяк и не один :)


На сколько я вижу код должно быть примерно так :

int GetSignal_SD()
{
      double sd0 = iCustom(NULL, 0, "Slope_Direction_Line", period, method, price, 0, 1); 
      double sd1 = iCustom(NULL, 0, "Slope_Direction_Line", period, method, price, 1, 1); 
   
   if(sd0 != EMPTY_VALUE)
      return(OP_BUY);
   else if(sd1 != EMPTY_VALUE)
      return(OP_SELL);
   else
      return(-1);    
}

Кстати, обратите внимание на код слоп дирекшн лайн - этот индикатор задним числом корректирует свои показания на предыдущем, уже закрытом баре.

Успехов.

 
VladislavVG >>:

Кстати, обратите внимание на код слоп дирекшн лайн - этот индикатор задним числом корректирует свои показания на предыдущем, уже закрытом баре.

Успехов.

учтем

спасибо за помощь

осталось разобраться с MA_rsi

вот её код, чтоб не лазить Вам далеко:

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Blue
#property indicator_color2 Red
//---- input parameters
extern int       maPeriod=50;
extern int       maMethod=MODE_EMA;
extern int       maPrice=PRICE_CLOSE;
extern int       rsiPeriod=40;
extern int       rsiLevel=50;
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,ExtMapBuffer1);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,ExtMapBuffer2);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {

   int limit;
   int counted_bars=IndicatorCounted();
//---- check for possible errors
   if(counted_bars<0) return(-1);
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
//---- main loop
   for(int i=0; i<limit; i++)
     {
         double ma = iMA(NULL,0,maPeriod, 0, maMethod, maPrice, i);
         double rsi= iRSI(NULL, 0, rsiPeriod, maPrice, i);
         if (rsi >= rsiLevel)
            ExtMapBuffer1[i] = ma;
         else
            ExtMapBuffer2[i] = ma;
     }
   return(0);
  }
//+------------------------------------------------------------------+

у меня такое впечатление, что я много сделал неправильно в выдергивании сигналов в данном советнике

 

Я не эксперт, но выше приведенный код, который вы называете кодом МА_rsi, просто окрашивает Машку в зависимости от того выше или ниже RSI уровня 50.

То есть для проверки условий аналогичных этому коду достачно вызвать RSI  и проверить выше или ниже он уровня - rsiLevel.

Причина обращения: