Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 1656

 
MakarFX , попробовал - без изменений, так же только на buy открывает, а sell в полном игноре...
 
artem artem #:
MakarFX , попробовал - без изменений, так же только на buy открывает, а sell в полном игноре...
Отсюда вывод что нет условий для переключения булов
 
Что тогда нужно добавить, что-бы условия были?
 
artem artem #:
Что тогда нужно добавить, что-бы условия были?

Объясни логику...

первое понятно: есть сигнал и нет ордеров открываем...

а дальше мне не понятно при каких условиях открывать или закрывать ордера

 
artem artem #:
Что тогда нужно добавить, что-бы условия были?

Попробуй так

//+------------------------------------------------------------------+
//| Start function                                                   |
//+------------------------------------------------------------------+
void start()
{
   StopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL); 
   
   // Определение направления пересечения мувингов
   if (Init) InitMetod(); 
   
   // Трейлинг стоп открытых позиций
   if (Trailing != 0 ) RealTrailOrder(TrailStop, TrailStep, StopLevel, MagicNumber);
   
   // Ожидание нового бара на графике
   if(timeprev == Time[0]) return;
   timeprev = Time[0];
   
   // Открытие ордера по методу Пуриа
   if(CheckForOpen()==0) // Если сигнал для покупок 
     {
      if(OrderSend(Symbol(),OP_BUY,Lots(),Ask,Slip,Bid-StopLoss*Point,Ask+TakeProfit*Point,"",MagicNumber,0,Blue))
         { Order=false; OrderBuy=true; OrderSell=false; Print("BUY OK"); } 
     } 
   if(CheckForOpen()==1) // Если сигнал для продаж 
     {
      if(OrderSend(Symbol(),OP_SELL,Lots(),Bid,Slip,Ask+StopLoss*Point,Bid-TakeProfit*Point,"",MagicNumber,0,Red))
        { Order=false; OrderBuy=false; OrderSell=true; Print("SELL OK");} 
     }
  }
//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
int CheckForOpen() // Открытие ордера по методу Пуриа
  {
   double malw,mas1,mas2,macd;
   int    res=-1, buy=0, sell=0;
   // Считывание параметров индикаторов 3 свечи (4ой)
   malw=iMA(NULL,0,MovingPeriodLw,0,MODE_EMA,PRICE_CLOSE,3);
   mas1=iMA(NULL,0,MovingPeriodS1,0,MODE_LWMA,PRICE_LOW,3);
   mas2=iMA(NULL,0,MovingPeriodS2,0,MODE_LWMA,PRICE_LOW,3);
   macd=iMACD(NULL,0,15,26,1,PRICE_CLOSE,MODE_MAIN,3);
   if(malw>mas1&&malw>mas2&&macd>0) {buy+=1; sell=0;}
   if(malw<mas1&&malw<mas2&&macd<0) {buy=0; sell+=1;}
   // Считывание параметров индикаторов 2 свечи (3ей)
   malw=iMA(NULL,0,MovingPeriodLw,0,MODE_EMA,PRICE_CLOSE,2);
   mas1=iMA(NULL,0,MovingPeriodS1,0,MODE_LWMA,PRICE_LOW,2);
   mas2=iMA(NULL,0,MovingPeriodS2,0,MODE_LWMA,PRICE_LOW,2);
   macd=iMACD(NULL,0,15,26,1,PRICE_CLOSE,MODE_MAIN,2);
   if(malw>mas1&&malw>mas2&&macd>0) {buy+=1; sell=0;}
   if(malw<mas1&&malw<mas2&&macd<0) {buy=0; sell+=1;}
   // Считывание параметров индикаторов 1 свечи (2ой)
   malw=iMA(NULL,0,MovingPeriodLw,0,MODE_EMA,PRICE_CLOSE,1);
   mas1=iMA(NULL,0,MovingPeriodS1,0,MODE_LWMA,PRICE_LOW,1);
   mas2=iMA(NULL,0,MovingPeriodS2,0,MODE_LWMA,PRICE_LOW,1);
   macd=iMACD(NULL,0,15,26,1,PRICE_CLOSE,MODE_MAIN,1);
   if(malw>mas1&&malw>mas2&&macd>0) {buy+=1; sell=0;}
   if(malw<mas1&&malw<mas2&&macd<0) {buy=0; sell+=1;}
   // Считывание параметров индикаторов 0 свечи (1ой)
   malw=iMA(NULL,0,MovingPeriodLw,0,MODE_EMA,PRICE_CLOSE,0);
   mas1=iMA(NULL,0,MovingPeriodS1,0,MODE_LWMA,PRICE_LOW,0);
   mas2=iMA(NULL,0,MovingPeriodS2,0,MODE_LWMA,PRICE_LOW,0);
   macd=iMACD(NULL,0,15,26,1,PRICE_CLOSE,MODE_MAIN,0);
   if(malw>mas1&&malw>mas2&&macd>0) {buy+=1; sell=0;}
   if(malw<mas1&&malw<mas2&&macd<0) {buy=0; sell+=1;}
   
   if(buy ==4 && OrderSell) res=0;
   if(sell==4 && OrderBuy)  res=1;
   return(res);
  }
//+------------------------------------------------------------------+
 

Хорошо, сейчас объясню всё по порядку, постараюсь конкретно и не перелить воды...

 За основу взята трендовая торговая стратегия "Метод Пуриа". Основана она на пересечении трех скользящих средних и открытии бара MACD. Две медленные с периодами (75) и (85), метод Linear Weighted применить к Low. Быстрая средняя с периодом (5), метод Exponential, применить к Close. Индикатор MACD с параметрами 15/26/1. Точка входа формируется при пересечении быстрой скользящей двух медленных и открытии бара MACD в соотвествующей зону с быстрой ( быстрая и бар MACD - в одой зоне должны быть):

  • Сигнал BUY - MA(5) пересекла и находится выше и MA(75), и MA(85), при этом MACD имеет открытый столбик в положительной области.
  • Сигнал SELL - MA(5) пересекла и находится ниже и MA(75), и MA(85), при этом MACD имеет открытый столбик в отрицательной области.

Советник ставит фиксированный профит и стоплосс. Размер профита и стопа задаются в исходных параметрах. Закрытие ордеров только по достижению тейкпрофита, или стоплосса. 

Это то, что было в исходных советниках по Пурии. Плюс, в последней версии, есть ещё трейлинг стопп, и вариант с торговлей по определённым часам. Функции полезны, но сейчас они меня не особо интересуют.

Теперь, собственно, какие дополнения я внёс/хочу внести:

     1. Сделать так, что-бы  открытие сделки и  проверка на соотвествие всех условий индикаторов (пересечение быстрой (5) двух медленных (75) (85) и открытие бара MACD в ту же сторону с  быстрой (5) ) осуществлялось  только по цене открытия новой свечи  (самый первый тик 30 минуной свечи каждой). С этим уже справился;
  1. Создать условия «обнуления» индикаторов. К примеру,  для быстрой скользящей (5): если она выше медленных — то это сигнал на buy. Если после этого, она уходит вниз, и  либо касается одного из, либо находится между медленными скользящими (75) и (85) — то тогда сигнал от быстрой скользящей как-бы  «обнуляется», и будет оставаться в таком  «нулевом» положении, пока будет касаться или оставаться между медленными. Если после этого,  быстрая пересекает обе медленных в одну из сторон (в том числе, если она вернулась в ту сторону, из которой пришла до касание медленных) —  то тогда это будет сигналом от этого индикатора.  C MACD ситуация аналогичная — только  «обнулением» будет являтся значение MACD=0 (если на свече 1. MACD открылся, к примеру, с значением  0,0043, а на свече 2. с значением  -0,0010, значит было  «обнуление» и MACD на свече 2. выдал новый сигнал). При этом, есть один момент:  быстрая (5) и  MACD должны быть как-бы «на равных правах» — если (5) не меняет своё положение относительно медленных, а в это время MACD открылся на прошлой свече в противоположной зоне (нет входа), а на следующей — в той же зоне что и быстрая — тогда все условия сошлись, и должен быть вход в ордер.  Обращаю внимание, что всё это должно быть только по ценам открытия свеч — только по этому одному тику;
  1. Ну и собственно последнее. Сделать так, что-бы после совпадения всех условий по индикаторам (по ценам открытия свеч),  советник выжидал 4 цены открытия свеч подряд

    1. Цена открытия 1ой свечи — (5) над (75) и (85) + бар MACD открылся выше 0 —  1 из 4 подтверждений есть;
    2. Цена открытия 2ой свечи — (5) над (75) и (85) + бар MACD открылся выше 0 —  2 из 4 подтверждений есть
    3. Цена открытия 3ей свечи — (5) над (75) и (85) + бар MACD открылся выше 0 —  3 из 4 подтверждений есть;
    4. Цена открытия 4ой свечи — (5) над (75) и (85) + бар MACD открылся выше 0 —  4 из 4 подтверждений есть   Открытие сделки на buy на этой же свече (4ой). 
           Аналогичная ситуация с ордерами на  sell, только в другом направлении индикаторы должны открываться. И есть важный момент —  если на, скажем, любом этапе от 1ой свечи до 4ой,  индикаторы изменят своё положение (к примеру, на 3ей свече открытия, бар MACD откроется либо ниже 0, либо =0) —  тогда всё сбрасывается, т.к. сигналы не прошли проверку по открытию 4ых свеч-подряд


Как-то так, если что-то непонятно и есть вопросы - пожайлуста, спрашивайте

 
artem artem #:

Хорошо, сейчас объясню всё по порядку, постараюсь конкретно и не перелить воды...


  1. Создать условия «обнуления» индикаторов.

Это и есть обнуление

   if(malw>mas1&&malw>mas2&&macd>0) {buy+=1; sell=0;}
   if(malw<mas1&&malw<mas2&&macd<0) {buy=0; sell+=1;}

Может я тебя не правильно понимаю...

попробуй скрин сделать

 
Прикрепил скрин, если что не понятно - сразу спрашивай
Файлы:
 
artem artem #:
Прикрепил скрин, если что не понятно - сразу спрашивай
я понял, подумаю
 
artem artem #:
Прикрепил скрин, если что не понятно - сразу спрашивай

а этот попробуйте - он в тех местах ,будет открывать ?

//+------------------------------------------------------------------+
//|                                                  artem artem.mq4 |
//|                        Copyright 2021, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//---
#define MagicNumber  122122
//---
#include <stdlib.mqh> // Стандартная библиотека
//---
input string s0 = "Баланс";            // 1
input string Template       = "ADX";   // Имя шаблона(without '.tpl')
input double TargetProfit   = 1000000; // Баланс + Прибыль(прибавить к балансу)
input double TargetLoss     = 0;       // Баланс - Убыток(отнять от баланса)
input string s1 = "Размер лота";       // 2
input double Lot            = 0.01;    // размер лота 0 - авт.расчет
input string s2 = "TP SL";             // 3
input double InpTProfit     = 1000;    // Exchange TP
input double InpStopLoss    = 1000000; // Exchange SL
input string s3 = "Индикатор";         // 4
input int    MovingPeriodLw = 13;      // MovingPeriodLw
input int    MovingPeriodS1 = 89;      // MovingPeriodS1
input int    MovingPeriodS2 = 144;     // MovingPeriodS2
input string s4 = "Day & Hour";        // 5
input int    HrStart        = 0;       // время начала торговли
input int    HrEnd          = 23;      // время окончания торговли
//+------------------------------------------------------------------+
int    Monday         = 1;      // Понедельник 1 вкд. 0 выкл.
int    Tuesday        = 1;      // Вторник
int    Wednesday      = 1;      // Среда
int    Thursday       = 1;      // Четверг
int    Friday         = 1;      // Пятница
//+------------------------------------------------------------------+
uint SLEEPTIME=1;
double Price[2];
datetime timeprev=0;
ENUM_TIMEFRAMES TimeFrame= PERIOD_CURRENT;
bool OrderBuy=false,OrderSell=false,Order=false,Init=true,ClOp=true;
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Закрыть Общий профит или профит на паре
   if(ProfitTarget())
     {
      return;
     }
//--- Закрыть профит BUY или SELL на паре
   ProfitOnTick();
// Определение направления пересечения мувингов
   if(Init)
      InitMetod();
// Ожидание нового бара на графике
   if(timeprev == Time[0])
      return;
   timeprev = Time[0];
// Открытие ордера по методу Пуриа
   CheckForOpen();
  }
//+------------------------------------------------------------------+
//| Check for open order conditions                                  |
//+------------------------------------------------------------------+
void CheckForOpen() // Открытие ордера по методу Пуриа
  {
   double malw,mas1,mas2,macd;
   int    res;
// Считывание параметров индикаторов
   malw=iMA(NULL,0,MovingPeriodLw,0,MODE_EMA,PRICE_CLOSE,0);
   mas1=iMA(NULL,0,MovingPeriodS1,0,MODE_LWMA,PRICE_LOW,0);
   mas2=iMA(NULL,0,MovingPeriodS2,0,MODE_LWMA,PRICE_LOW,0);
   macd=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0);
// Проверяем положение мувмнгов
   if(malw>mas1 && malw>mas2  && OrderSell)
     {
      OrderBuy=true;
      OrderSell=false;
      Order=true;
     }
   if(malw<mas1 && malw<mas2  && OrderBuy)
     {
      OrderBuy=false;
      OrderSell=true;
      Order=true;
     }
// Открываем ордер Buy
   if(macd>0 && OrderBuy && Order)
     {
      res=OrderSend(Symbol(),OP_BUY,Lots(),Ask,3,0,0,"",MagicNumber,0,Blue);
      Order=false;
      return;
     }
// Открываем ордер Sell
   if(macd<0 && OrderSell && Order)
     {
      res=OrderSend(Symbol(),OP_SELL,Lots(),Bid,3,0,0,"",MagicNumber,0,Red);
      Order=false;
      return;
     }
  }
//+------------------------------------------------------------------+
//| Init metod Puria function                                        |
//+------------------------------------------------------------------+
void InitMetod()  // Опредеоение начального пересечения мувингов
  {
   double malw,mas1,mas2;
   malw=iMA(NULL,0,MovingPeriodLw,0,MODE_EMA,PRICE_CLOSE,0);
   mas1=iMA(NULL,0,MovingPeriodS1,0,MODE_LWMA,PRICE_LOW,0);
   mas2=iMA(NULL,0,MovingPeriodS2,0,MODE_LWMA,PRICE_LOW,0);
   if((malw<=mas1 && malw>=mas2) || (malw>=mas1 && malw<=mas2))
     {
      Init=false;
      OrderBuy=true;
      OrderSell=true;
     }
   return;
  }
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double Lots()  // Расчет объема лота
  {
   double Lots;
   if(Lot > 0)
      return(Lot);
   Lots=AccountFreeMargin()/5000;
   Lots=MathMin(15,MathMax(0.01,Lots));
   if(Lots<0.1)
      Lots=NormalizeDouble(Lots,2);
   else
     {
      if(Lots<1)
         Lots=NormalizeDouble(Lots,1);
      else
         Lots=NormalizeDouble(Lots,0);
     }
   return(Lots);
  }
//+------------------------------------------------------------------+
// Permission to trade in this day                                   |
//+------------------------------------------------------------------+
bool TradingDay(int hmin, int hmax) // Определение времени и дня разрешения торговли
  {
   bool dtrade = false;
   switch(DayOfWeek())
     {
      case 1: // Monday
         if(Monday == 1)
            dtrade = true;
         break;
      case 2: // Tuesday
         if(Tuesday == 1)
            dtrade = true;
         break;
      case 3: // Wednesday
         if(Wednesday == 1)
            dtrade = true;
         break;
      case 4: // Thursday
         if(Thursday == 1)
            dtrade = true;
         break;
      case 5: // Friday
         if(Friday == 1)
            dtrade = true;
         break;
      default: //
         dtrade = false;
         break;
     }
   if(dtrade && !(Hour() >= hmin && Hour() <= hmax))
      dtrade = true;
   return dtrade;
  }
//+------------------------------------------------------------------+
//| Check for long position closing                                  |
//+------------------------------------------------------------------+
bool ProfitTarget(void)
  {
   bool res=false;
   if(AccountInfoDouble(ACCOUNT_EQUITY)<=TargetLoss ||
      AccountInfoDouble(ACCOUNT_EQUITY)>=TargetProfit)
     {
      CloseAllOrders();
      Sleep(SLEEPTIME*1000);
      CloseAllOrders();
      ExpertRemove();
      DeleteChart();
      PlaySound("expert.wav");
      res=true;
     }
//--- result
   return(res);
  }
//+------------------------------------------------------------------+
//| Check for long position closing                                  |
//+------------------------------------------------------------------+
bool ProfitOnTick(void)
  {
   bool res=false;
   double PROFIT_BUY=0.00;
   double PROFIT_SELL=0.00;
   for(int i=OrdersTotal()-1; i>=0; i--) // returns the number of open positions
     {
      if(OrderSelect(i,SELECT_BY_POS) && OrderSymbol()==Symbol())
        {
         if(OrderSymbol()==Symbol() && OrderType()==OP_BUY)
           {
            PROFIT_BUY=PROFIT_BUY+NormalizeDouble(OrderProfit(),2);
           }
         if(OrderSymbol()==Symbol() && OrderType()==OP_SELL)
           {
            PROFIT_SELL=PROFIT_SELL+NormalizeDouble(OrderProfit(),2);
           }
        }
     }
   int Close_ticketb=0;
   int totalb=OrdersTotal();
   int b = 0;
   for(b = totalb; b >=0; b--)
     {
      if(OrderSelect(b,SELECT_BY_POS) && OrderSymbol()==Symbol())
        {
         //OrderSelect(i,SELECT_BY_POS);
         if(OrderSymbol()==Symbol() && OrderType()==OP_BUY)
           {
            if(PROFIT_BUY<-InpStopLoss || PROFIT_BUY>=InpTProfit)
              {
               Close_ticketb = OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_BID),5);
               PlaySound("ok.wav");
              }
           }
        }
      res=true;
     }
   int Close_tickets=0;
   int totals=OrdersTotal();
   int s = 0;
   for(s = totals; s >=0; s--)
     {
      if(OrderSelect(s,SELECT_BY_POS) && OrderSymbol()==Symbol())
        {
         if(OrderSymbol()==Symbol() && OrderType()==OP_SELL)
           {
            if(PROFIT_SELL<-InpStopLoss || PROFIT_SELL>=InpTProfit)
              {
               Close_tickets = OrderClose(OrderTicket(),OrderLots(),MarketInfo(Symbol(),MODE_ASK),5);
               PlaySound("ok.wav");
              }
           }
        }
      res=true;
     }
//--- result
   return(res);
  }
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
void CloseAllOrders(void)
  {
   int iOrders=OrdersTotal()-1, i;
   if(ClOp)
     {
      for(i=iOrders; i>=0; i--)
        {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && (OrderType()<=OP_SELL) && GetMarketInfo() &&
            !OrderClose(OrderTicket(),OrderLots(),Price[1-OrderType()],0))
            Print(OrderError());
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
           {
            if(OrderDelete(OrderTicket()))
               Print(OrderError());
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Function..: OrderError                                           |
//+------------------------------------------------------------------+
string OrderError(void)
  {
   int iError=GetLastError();
   return(StringConcatenate("Order:",OrderTicket()," GetLastError()=",iError," ",ErrorDescription(iError)));
  }
//+------------------------------------------------------------------+
//| Function..: GetMarketInfo                                        |
//+------------------------------------------------------------------+
bool GetMarketInfo(void)
  {
   RefreshRates();
   Price[0]=MarketInfo(OrderSymbol(),MODE_ASK);
   Price[1]=MarketInfo(OrderSymbol(),MODE_BID);
   double dPoint=MarketInfo(OrderSymbol(),MODE_POINT);
   if(dPoint==0)
      return(false);
   return(Price[0]>0.0 && Price[1]>0.0);
  }
//+------------------------------------------------------------------+
//| start function                                                   |
//+------------------------------------------------------------------+
void DeleteChart(void)
  {
   long currChart,prevChart=ChartFirst();
   int i=0,limit=100;
   bool errTemplate;
   while(i<limit)
     {
      currChart=ChartNext(prevChart);
      if(TimeFrame!=PERIOD_CURRENT)
        {
         ChartSetSymbolPeriod(prevChart,ChartSymbol(prevChart),TimeFrame);
        }
      errTemplate=ChartApplyTemplate(prevChart,Template+".tpl");
      if(!errTemplate)
        {
         Print("Error ",ChartSymbol(prevChart),"-> ",GetLastError());
        }
      if(currChart<0)
         break;
      Print(i,ChartSymbol(currChart)," ID =",currChart);
      prevChart=currChart;
      i++;
     }
  }
//+------------------------------------------------------------------+
Причина обращения: