[АРХИВ] Любой вопрос новичка, чтоб не захламлять форум. Профи, не проходите мимо. Без вас никуда - 3. - страница 280

 
sergeev:

Как вычисляется iMA?


90
Eugene1 20.10.2011 16:34

Где-нибудь можно найти как вычисляется функция iMA (или она засекреченная)

Особеннно меня интересует MODE_LWMA.

Хочу посмотреть и подправить на свой вкус, но что-то нагуглить исходники не получилось

https://docs.mql4.com/ru/indicators/iMA

double iMA(string symbol, int timeframe, int period, int ma_shift, int ma_method, int applied_price, int shift)
Расчет скользящего среднего.
Вам нужна формула, так Гугл её тоже легко находит.
 
snail09:

https://docs.mql4.com/ru/indicators/iMA

double iMA(string symbol, int timeframe, int period, int ma_shift, int ma_method, int applied_price, int shift)
Расчет скользящего среднего.
Вам нужна формула, так Гугл её тоже легко находит.
Или Вам непонятен термин "линейно-взвешенная"?

 

Где-нибудь можно найти как вычисляется функция iMA (или она засекреченная)

Особеннно меня интересует MODE_LWMA.

Хочу посмотреть и подправить на свой вкус, но что-то нагуглить исходники не получилось


//+------------------------------------------------------------------+
//|                                        Custom Moving Average.mq4 |
//|                      Copyright © 2004, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- indicator parameters
extern int MA_Period=13;
extern int MA_Shift=0;
extern int MA_Method=0;
//---- indicator buffers
double ExtMapBuffer[];
//----
int ExtCountedBars=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   int    draw_begin;
   string short_name;
//---- drawing settings
   SetIndexStyle(0,DRAW_LINE);
   SetIndexShift(0,MA_Shift);
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
   if(MA_Period<2) MA_Period=13;
   draw_begin=MA_Period-1;
//---- indicator short name
   switch(MA_Method)
     {
      case 1 : short_name="EMA(";  draw_begin=0; break;
      case 2 : short_name="SMMA("; break;
      case 3 : short_name="LWMA("; break;
      default :
         MA_Method=0;
         short_name="SMA(";
     }
   IndicatorShortName(short_name+MA_Period+")");
   SetIndexDrawBegin(0,draw_begin);
//---- indicator buffers mapping
   SetIndexBuffer(0,ExtMapBuffer);
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   if(Bars<=MA_Period) return(0);
   ExtCountedBars=IndicatorCounted();
//---- check for possible errors
   if (ExtCountedBars<0) return(-1);
//---- last counted bar will be recounted
   if (ExtCountedBars>0) ExtCountedBars--;
//----
   switch(MA_Method)
     {
      case 0 : sma();  break;
      case 1 : ema();  break;
      case 2 : smma(); break;
      case 3 : lwma();
     }
//---- done
   return(0);
  }
//+------------------------------------------------------------------+
//| Simple Moving Average                                            |
//+------------------------------------------------------------------+
void sma()
  {
   double sum=0;
   int    i,pos=Bars-ExtCountedBars-1;
//---- initial accumulation
   if(pos<MA_Period) pos=MA_Period;
   for(i=1;i<MA_Period;i++,pos--)
      sum+=Close[pos];
//---- main calculation loop
   while(pos>=0)
     {
      sum+=Close[pos];
      ExtMapBuffer[pos]=sum/MA_Period;
           sum-=Close[pos+MA_Period-1];
           pos--;
     }
//---- zero initial bars
   if(ExtCountedBars<1)
      for(i=1;i<MA_Period;i++) ExtMapBuffer[Bars-i]=0;
  }
//+------------------------------------------------------------------+
//| Exponential Moving Average                                       |
//+------------------------------------------------------------------+
void ema()
  {
   double pr=2.0/(MA_Period+1);
   int    pos=Bars-2;
   if(ExtCountedBars>2) pos=Bars-ExtCountedBars-1;
//---- main calculation loop
   while(pos>=0)
     {
      if(pos==Bars-2) ExtMapBuffer[pos+1]=Close[pos+1];
      ExtMapBuffer[pos]=Close[pos]*pr+ExtMapBuffer[pos+1]*(1-pr);
           pos--;
     }
  }
//+------------------------------------------------------------------+
//| Smoothed Moving Average                                          |
//+------------------------------------------------------------------+
void smma()
  {
   double sum=0;
   int    i,k,pos=Bars-ExtCountedBars+1;
//---- main calculation loop
   pos=Bars-MA_Period;
   if(pos>Bars-ExtCountedBars) pos=Bars-ExtCountedBars;
   while(pos>=0)
     {
      if(pos==Bars-MA_Period)
        {
         //---- initial accumulation
         for(i=0,k=pos;i<MA_Period;i++,k++)
           {
            sum+=Close[k];
            //---- zero initial bars
            ExtMapBuffer[k]=0;
           }
        }
      else sum=ExtMapBuffer[pos+1]*(MA_Period-1)+Close[pos];
      ExtMapBuffer[pos]=sum/MA_Period;
           pos--;
     }
  }
//+------------------------------------------------------------------+
//| Linear Weighted Moving Average                                   |
//+------------------------------------------------------------------+
void lwma()
  {
   double sum=0.0,lsum=0.0;
   double price;
   int    i,weight=0,pos=Bars-ExtCountedBars-1;
//---- initial accumulation
   if(pos<MA_Period) pos=MA_Period;
   for(i=1;i<=MA_Period;i++,pos--)
     {
      price=Close[pos];
      sum+=price*i;
      lsum+=price;
      weight+=i;
     }
//---- main calculation loop
   pos++;
   i=pos+MA_Period;
   while(pos>=0)
     {
      ExtMapBuffer[pos]=sum/weight;
      if(pos==0) break;
      pos--;
      i--;
      price=Close[pos];
      sum=sum-lsum+price*MA_Period;
      lsum-=Close[i];
      lsum+=price;
     }
//---- zero initial bars
   if(ExtCountedBars<1)
      for(i=1;i<MA_Period;i++) ExtMapBuffer[Bars-i]=0;
  }
//+------------------------------------------------------------------+
 

Добрый день!

В качестве первого опыта решил реализовать следующий алгоритм: можно ожидать, что после сближения линий Боллинджера в узкий коридор через какое-то время будет резкое движение рынка вверх или вниз. В советнике анализирую состояние линий Боллинджера и при их близком сближении (Delta пунктов) ставим отложенный ордер на продажу в нижнем направлении (на StepOpen пунктов ниже нижней линии) в надежде что рынок резко пойдет именно в эту сторону. Если рынок пошел в другую сторону, то просто удаляем этот ордер.

extern double Delta=800.0;              // Ширина канала, которую мы считаем достаточно узкой чтобы ожидать скоро серьезного движения в одну из сторон
extern double StepOpen=150.0;           // Отступ от линии Боллинджера  для открытия отложенного ордера
extern double TP=350.0;                 // Take Profit
extern double SL=400.0;                 // Stop Loss

int start()
  {
   double T1=iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_UPPER,0);  // верхняя линия Боллинджера
   double T2=iBands(NULL,0,20,2,0,PRICE_CLOSE,MODE_LOWER,0); // нижняя линия Боллинджера
   if ((Ask>T1+StepOpen*Point)&&OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true) OrderDelete(0); // если рынок пошел вверх – то удаляем отложенный ордер
   if (OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true) return(0); // если есть ранее открытый ордер – прекращаем выполнение текущей итерации советника
   if (T1-T2<Delta*Point) {               // если линии Боллинджера сблизились ближе чем на Delta пунктов начинаем операцию открытия ордера
      double PriceOpen=NormalizeDouble(T2-StepOpen*Point,5);  // вычисляем цену открытия
      double StopLoss=NormalizeDouble(T2-StepOpen*Point+SL*Point,5); // вычисляем StopLoss
      double TakeProfit=NormalizeDouble(T2-StepOpen*Point-TP*Point,5); // вычисляем TakeProfit
      OrderSend(Symbol(),OP_SELL,0.1,PriceOpen,5,StopLoss,TakeProfit,0,0,0,Green); //  открываем ордер на продажу
            }
   return(0);
  }
Алгоритм работает нестабильно, иногда открывает по два ордера через короткий промежуток времени, постоянно выдает ошибки OrderSend Error 130 и OrderSend Error 138, а удаление открытых ордеров в случае движения рынка в другую сторону вообще не срабатывает.

Большая просьба помочь советом! Спасибо!

 
Vinin:


Виктор Иванович!

Так много листать, че Вы не дали ссылку? Вложили код... Зачем?

 
snail09:
int start()
{
static datetime PrevTime=0; // Время открытия предпоследнего бара

//Дополнительные проверки

if (PrevTime==0) PrevTime=Time[0]; // При первом запуске текущий бар пропускаем
if (Time[0]<=PrevTime) return(0); // Контроль времени открытия нового бара

//--Ваш основной код

PrevTime=Time[0]; // Запоминаем время открытия нулевого бара

return(0);
}

Если у Вас сетап по открытию бара, вот шаблон, он работает.

Большая просьба Вы не могли бы вписать сами эту функцию в советник? На картинке видно открыл 3 ордера на одном баре. А надо только один У меня не получается исправить код.СПАСИБО.

//+------------------------------------------------------------------+
int start()
//+------------------------------------------------------------------+
{
//--- Разрешение на открытие позиций - каждую свечу
if(candle_time != Time[0])
{
candle_time = Time[0];
new_bar_buy = true;
new_bar_sell = true;
}
if (Bars < bars_count){Print("Мало данных для работы"); return(0);}

//--- Получение значений индикатора iMA
ma10 = iMA ( Symbol(), Period(), MA1_period, MA1_shift, MA1_method, MA1_price, bars_shift);
ma20 = iMA ( Symbol(), Period(), MA2_period, MA2_shift, MA2_method, MA2_price, bars_shift);
ma11 = iMA ( Symbol(), Period(), MA1_period, MA1_shift, MA1_method, MA1_price, bars_shift+1);
ma21 = iMA ( Symbol(), Period(), MA2_period, MA2_shift, MA2_method, MA2_price, bars_shift+1);

if (Revers)
{
if(rsi>50 && rsi<70)//--- включена инверсия
{
//--- Условие для продажи
if(ma11 < ma21 && ma10 > ma20 && ma30 > ma10 && new_bar_sell)
{
sell_open=true;
new_bar_sell = false;
}
}
if(rsi>30 && rsi<50)//--- включена инверсия
{
//--- Условие для продажи
if(ma11 > ma21 && ma10 < ma20 && ma30 < ma10 && new_bar_buy)
{
buy_open=true;
new_bar_buy = false;
}
}
}
//--- выставление рыночных ордеров
if(IsTradeAllowed())
{
Trade_BUY();
Trade_SELL();
}
return(0);
//+------------------------------------------------------------------+
void Trade_BUY()
//+------------------------------------------------------------------+
{

for ( int i = 0; i < OrdersTotal(); i++ )
{
if ( OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) )
{
if ((OrderSymbol() != Symbol()) || (OrderMagicNumber() != Magic)) continue; //не наш ордер
if ( OrderType() == OP_BUY) // если ордер OP_BUY
{
min_level = MarketInfo( Symbol(), MODE_STOPLEVEL );
//--- проверка на работу трейлинг стопа
if (trailing_stop !=0.0 && Ask > NormalizeDouble(OrderStopLoss() + (stop_loss_buy + MathMax(min_level, trailing_stop)) * Point, Digits) && OrderProfit() > 0)
{

if ( OrderModify ( OrderTicket(), OrderOpenPrice(),
NormalizeDouble (OrderStopLoss() + MathMax(min_level, trailing_stop) * Point, Digits),
OrderTakeProfit(), 0, CLR_NONE))
{
Print("Сработал трейлинг стоп для Buy");
}
else
{
Print ("Ошибка модификации ордера #", GetLastError());
}

RefreshRates();
Sleep(3000);
} //end modify

}// end BUY
}//end OrderSelect
else
{
Print( "OrderSelect ошибка #", GetLastError() );
Sleep(3000);
RefreshRates();
return;
}
}// end for
//--- Открываем ордер если есть сигнал
while (buy_open)
{
//--- нормализация лота
lot = Normalize_Lot(Lots);
//--- проверка на наличие свободной маржи
if( AccountFreeMarginCheck(Symbol(),OP_BUY, lot) <= 0 || GetLastError() == 134 )
{
Print("Недостаточно свободной маржи для открытия ордера");
buy_open = false;
break;
}
min_level = MarketInfo( Symbol(), MODE_STOPLEVEL );
if ( OrderSend( Symbol(), OP_BUY, lot, NormalizeDouble(Ask, Digits), slippage,
NormalizeDouble(Bid - MathMax(stop_loss_buy, min_level) * Point, Digits),
NormalizeDouble(Bid + MathMax(take_profit_buy,min_level) * Point, Digits),
DoubleToStr(Magic, 0), Magic, 0, Blue) > 0 )
{
PlaySound("Wait.wav");
buy_open = false; // ордер открыт
break;
}
else
{
int Error = GetLastError(); // Не получилось :(
switch(Error) // Преодолимые ошибки
{
case 138:Alert("Ошибка: ",Error," Новые цены.");
RefreshRates();
continue;
case 135:Alert("Ошибка: ",Error," Цена изменилась.");
RefreshRates();
continue;
case 136:Alert("Нет цен.");
while(RefreshRates() == false)
Sleep(500);
continue;
case 146:Alert("Подсистема торговли занята.");
Sleep(500);
RefreshRates();
continue;
default: Alert("Возникла ошибка ", Error," Выход из подпрограммы."); // Другие варианты ошибок
}// end switch
}// end else
break;
}// end while
}// end Trade_BUY
//+------------------------------------------------------------------+
void Trade_SELL()
//+------------------------------------------------------------------+
{

for ( int i = 0; i < OrdersTotal(); i++ )
{
if ( OrderSelect( i, SELECT_BY_POS, MODE_TRADES ) )
{
if ((OrderSymbol() != Symbol()) || (OrderMagicNumber() != Magic)) continue; //не наш ордер
if ( OrderType() == OP_SELL) //если ордер OP_SELL
{
min_level = MarketInfo( Symbol(), MODE_STOPLEVEL );

//--- проверка на работу трейлинг стопа
if (trailing_stop !=0.0 && Bid < NormalizeDouble(OrderStopLoss() - (stop_loss_sell + MathMax(min_level, trailing_stop)) * Point, Digits)&&OrderProfit() > 0)
{
if ( OrderModify ( OrderTicket(), OrderOpenPrice(),
NormalizeDouble (OrderStopLoss() - MathMax(min_level, trailing_stop) * Point, Digits),
OrderTakeProfit(), 0, CLR_NONE))
{
Print("Сработал трейлинг стоп для Sell");
}
else
{
Print ( "Ошибка модификации ордера #", GetLastError());
}

RefreshRates();
Sleep(3000);
}
}// end BUY
}//end OrderSelect
else
{
Print( "OrderSelect ошибка #", GetLastError() );
Sleep(3000);
RefreshRates();
return;
}
}// end for
//--- Открываем ордер если есть сигнал
while (sell_open)
{

//--- нормализация лота
lot = Normalize_Lot(Lots);
//--- проверка на наличие свободной маржи
if( AccountFreeMarginCheck(Symbol(),OP_SELL, lot) <= 0 || GetLastError() == 134 )
{
Print("Недостаточно свободной маржи для открытия ордера");
sell_open = false;
break;
}
min_level = MarketInfo( Symbol(), MODE_STOPLEVEL );
if ( OrderSend( Symbol(), OP_SELL, lot, NormalizeDouble(Bid, Digits), slippage,
NormalizeDouble(Ask + MathMax(stop_loss_sell, min_level) * Point, Digits),
NormalizeDouble(Ask - MathMax(take_profit_sell, min_level) * Point, Digits),
DoubleToStr(Magic, 0), Magic, 0, Blue) > 0 )
{
PlaySound("Wait.wav");
sell_open = false; // ордер открыт
break;
}
else
{
int Error = GetLastError(); // Не получилось :(
switch(Error) // Преодолимые ошибки
{
case 138:Alert("Ошибка: ",Error," Новые цены.");
RefreshRates();
continue;
case 135:Alert("Ошибка: ",Error," Цена изменилась.");
RefreshRates();
continue;
case 136:Alert("Нет цен.");
while(RefreshRates() == false)
Sleep(500);
continue;
case 146:Alert("Подсистема торговли занята.");
Sleep(500);
RefreshRates();
continue;
default: Alert("Возникла ошибка ", Error," Выход из подпрограммы."); // Другие варианты ошибок
}// end switch
}// end else
break;
}// end while
}// end Trade_SELL


//+------------------------------------------------------------------+
double Normalize_Lot(double lot)// Проверка на допустимое значение лота
//+------------------------------------------------------------------+
{
double lot_min = MarketInfo(Symbol(), MODE_MINLOT);
double lot_max = MarketInfo(Symbol(), MODE_MAXLOT);
double lot_step = MarketInfo(Symbol(), MODE_LOTSTEP);
if ( lot <= lot_min ) lot = lot_min; // минимальный
else if ( lot >= lot_max ) lot = lot_max; // максимальный
else lot = MathFloor( lot / lot_step ) * lot_step ; // округление до ближайшего меньшего
return(lot);
}

//+------------------------------------------------------------------+
int MathMax4(int i1,int i2,int i3,int i4)// Возврат максимального значения
//+------------------------------------------------------------------+
{
int imax=i1;
if(i2>imax)imax=i2;
if(i3>imax)imax=i3;
if(i4>imax)imax=i4;
return(imax);
}








 

Привет всем )))

Помогите в советнике ограничить открытие ордеров до 1-го в сутки, неважно сколько он раз точку входа проходить будет...

Пытаюсь написать типа чтоб перед открытием проверял историю последнего закрытого ордера и если совпадает тогда не открывать...

for(int i=0;i<OrdersTotal();i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==true)
{
if(OrderCloseTime()==Day()
break;

}

что то фигово получается, помогите плз ламочинке ))))

 

ордер на одном баре site:mql4.com

https://www.mql5.com/ru/forum/102366/page3

 
Добрый день,уважаемые форумчане.
Нужна помощь в изменении советника,т.е. оставить всё как есть,только изменить действие(покупка/продажа) на (продажа/покупка),мои тесты показали что на восходящем тренде происходит sell,а при нисходящем buy.Простое изменение в коде BUY на SELL мне ничего не дало,либо что-то пропустил,либо.... вобщем,ай нид хелп
Заранее благодарю.
Файлы:
 
rusa:








Хорошо, сделаю. Только на выходных, подождете? (командировка).