Создание робота - страница 4

 
Ну да, писал, писал, потом подумал, не точно сказал. У меня всегда проблема с формулированием мысли. С десятого изменения, вроде слова становятся вразумительными
 
Роман Жилин:

Ооо, огромное спасибо, с таким колличеством информации можно столько дел наворотить...

Как раз уезжаю в командировку, думаю посильнее углубиться в данные мне материалы, ну а кодить... Можно и на листе, думаю будет неплохая тренировка...


С уважением, Роман

Это мизерная часть того, что необходимо знать, можно сказать - песчинка в море програмнного кода. Но и этого мало, нужно ещё понимать, что применять, где применять и когда применять!

Если же исходить из самого названия темы "Создание робота", то прежде всего, Вам нужно иметь безубыточную (прибыльную, как хотите назовите) стратегию торговли, а уже затем заниматься изучением языка программирования MQL5.

Кстати, в MetaEditor терминала МТ5 имеется Мастер MQL5 с помощью которого можно без особых проблем, не зная языка программирования, получить код готового советника, используя Модули торговых сигналов, которые в свою очередь были созданы на основе популярных индикаторов. С помощью Мастера MQL5 можно, как говорится на коленке, быстро собрать советника и протестировать свою стратегию, если она у Вас основана только на индикаторах. Вот ссылка на статью о создании торгового робота при помощи Мастера MQL5:  https://www.mql5.com/ru/articles/171

С уважением, Владимир.

Мастер MQL5: Создание эксперта без программирования
Мастер MQL5: Создание эксперта без программирования
  • www.mql5.com
При создании автоматических торговых систем возникает необходимость написания алгоритмов анализа рыночной ситуации и генерации торговых сигналов, алгоритмов сопровождения открытых позиций, систем управления капиталом и контроля риска торговли. После того как код модулей написан самой сложной задачей является компоновка всех частей и отладка...
 
MrBrooklin:

57 с небольшим. А ответ на Ваш вопрос про путь уже знаете, цитирую:

"Роман Жилин:

Нет, во фрилансе нет того процесса, который есть в составлении своего детища, который сам можешь развивать как тебе надобно. И в своих ошибках буду виноват лишь я сам, а не сторонний програмист. Поэтому, учится, учиться, кодить, спотыкаться, совершенствовать свои стратегии, и снова учиться"

С уважением, Владимир.

Хорошая подборка, спасибо.

Напомнило завещание Ленина :) , но это правильно, учиться никогда не поздно.

Одна из проблем это нехватка времени, перелапатить гигабайты литературы занимает много времени, другая и в большинстве случаев основная оказывается стратегия по сравнению с которой написание советника оказывается ерундой, над этим то и надо начать работать в первую очередь, чтобы иметь чёткое представление какой именно нужен советник.

 

Добавил ещё две кнопки для закрытия позиции 

//+------------------------------------------------------------------+
//|                                                         0002.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#define   InpMagic  182979245
//---
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
//---
CPositionInfo  m_position; // trade position object
CTrade         m_trade;    // trading object
CSymbolInfo    m_symbol;   // symbol info object
//---
input double InpLots          =0.01; // Lots
//---
double m_adjusted_point;   // point value adjusted for 3 or 5 points
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(!m_symbol.Name(Symbol())) // sets symbol name
      return(INIT_FAILED);;
//---
   m_trade.SetExpertMagicNumber(InpMagic);
   m_trade.SetMarginMode();
   m_trade.SetTypeFillingBySymbol(m_symbol.Name());
//--- tuning for 3 or 5 digits
   int digits_adjust=1;
   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
      digits_adjust=10;
   m_adjusted_point=m_symbol.Point()*digits_adjust;
//---
   m_trade.SetDeviationInPoints(3*digits_adjust);
   if(!m_position.Select(Symbol()))
     {
      CheckObject();
      CheckObjectClose();
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   if(ObjectFind(0,"BUY")==0)
     {
      ObjectDelete(0,"BUY");
     }
   if(ObjectFind(0,"SELL")==0)
     {
      ObjectDelete(0,"SELL");
     }
//---
   if(ObjectFind(0,"Close BUY")==0)
     {
      ObjectDelete(0,"Close BUY");
     }
   if(ObjectFind(0,"Close SELL")==0)
     {
      ObjectDelete(0,"Close SELL");
     }
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   CheckButon();
   CheckButonClose();
  }
//+------------------------------------------------------------------+
//| Check for long position closing                                  |
//+------------------------------------------------------------------+
bool CheckButon(void)
  {
//---
   bool res=false;
     {
      if(ObjectGetInteger(0,"BUY",OBJPROP_STATE)!=0)
        {
         ObjectSetInteger(0,"BUY",OBJPROP_STATE,0);
         double price=m_symbol.Ask();
           {
            //--- open position
            if(m_trade.PositionOpen(m_symbol.Name(),ORDER_TYPE_BUY,InpLots,price,0.0,0.0))
               printf("Position by %s to be opened",m_symbol.Name());
            else
              {
               printf("Error opening BUY position by %s : '%s'",m_symbol.Name(),m_trade.ResultComment());
               printf("Open parameters : price=%f,TP=%f",price,0.0);
              }
            PlaySound("ok.wav");
           }
        }
      if(ObjectGetInteger(0,"SELL",OBJPROP_STATE)!=0)
        {
         ObjectSetInteger(0,"SELL",OBJPROP_STATE,0);
         double price0=m_symbol.Bid();
           {
            if(m_trade.PositionOpen(m_symbol.Name(),ORDER_TYPE_SELL,InpLots,price0,0.0,0.0))
               printf("Position by %s to be opened",m_symbol.Name());
            else
              {
               printf("Error opening SELL position by %s : '%s'",m_symbol.Name(),m_trade.ResultComment());
               printf("Open parameters : price=%f,TP=%f",price0,0.0);
              }
            PlaySound("ok.wav");
           }
        }
      res=true;
     }
//--- result
   return(res);
  }
//+------------------------------------------------------------------+
//| Check for long position closing                                  |
//+------------------------------------------------------------------+
bool CheckObject(void)
  {
//---
   bool res=false;
     {
      ObjectCreate(0,"BUY",OBJ_BUTTON,0,0,0);
      ObjectSetInteger(0,"BUY",OBJPROP_XDISTANCE,ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)-102);
      ObjectSetInteger(0,"BUY",OBJPROP_YDISTANCE,37);
      ObjectSetString(0,"BUY",OBJPROP_TEXT,"BUY");
      ObjectSetInteger(0,"BUY",OBJPROP_BGCOLOR,clrMediumSeaGreen);
      ObjectCreate(0,"SELL",OBJ_BUTTON,0,0,0);
      ObjectSetInteger(0,"SELL",OBJPROP_XDISTANCE,ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)-50);
      ObjectSetInteger(0,"SELL",OBJPROP_YDISTANCE,37);
      ObjectSetString(0,"SELL",OBJPROP_TEXT,"SELL");
      ObjectSetInteger(0,"SELL",OBJPROP_BGCOLOR,clrDarkOrange);
      res=true;
     }
//--- result
   return(res);
  }
//+------------------------------------------------------------------+
//| Check for long position closing                                  |
//+------------------------------------------------------------------+
bool CheckButonClose(void)
  {
//---
   bool res=false;
   double level;
     {
      if(ObjectGetInteger(0,"Close BUY",OBJPROP_STATE)!=0)
        {
         ObjectSetInteger(0,"Close BUY",OBJPROP_STATE,0);
         if(FreezeStopsLevels(level))
            ClosePositions(POSITION_TYPE_BUY,level);
         PlaySound("ok.wav");
        }
      if(ObjectGetInteger(0,"Close SELL",OBJPROP_STATE)!=0)
        {
         ObjectSetInteger(0,"Close SELL",OBJPROP_STATE,0);
         if(FreezeStopsLevels(level))
            ClosePositions(POSITION_TYPE_SELL,level);
         PlaySound("ok.wav");
        }
      res=true;
     }
//--- result
   return(res);
  }
//+------------------------------------------------------------------+
//| Check for long position closing                                  |
//+------------------------------------------------------------------+
bool CheckObjectClose(void)
  {
//---
   bool res=false;
     {
      ObjectCreate(0,"Close BUY",OBJ_BUTTON,0,0,0);
      ObjectSetInteger(0,"Close BUY",OBJPROP_XDISTANCE,ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)-102);
      ObjectSetInteger(0,"Close BUY",OBJPROP_YDISTANCE,57);
      ObjectSetString(0,"Close BUY",OBJPROP_TEXT,"Close BUY");
      ObjectSetInteger(0,"Close BUY",OBJPROP_BGCOLOR,clrTomato);
      ObjectCreate(0,"Close SELL",OBJ_BUTTON,0,0,0);
      ObjectSetInteger(0,"Close SELL",OBJPROP_XDISTANCE,ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)-50);
      ObjectSetInteger(0,"Close SELL",OBJPROP_YDISTANCE,57);
      ObjectSetString(0,"Close SELL",OBJPROP_TEXT,"Close SELL");
      ObjectSetInteger(0,"Close SELL",OBJPROP_BGCOLOR,clrFireBrick);
      res=true;
     }
//--- result
   return(res);
  }
//+------------------------------------------------------------------+
//| Check Freeze and Stops levels                                    |
//+------------------------------------------------------------------+
bool FreezeStopsLevels(double &level)
  {
//--- check Freeze and Stops levels
   if(!RefreshRates() || !m_symbol.Refresh())
      return(false);
//--- FreezeLevel -> for pending order and modification
   double freeze_level=m_symbol.FreezeLevel()*m_symbol.Point();
   if(freeze_level==0.0)
      freeze_level=(m_symbol.Ask()-m_symbol.Bid())*3.0;
//--- StopsLevel -> for TakeProfit and StopLoss
   double stop_level=m_symbol.StopsLevel()*m_symbol.Point();
   if(stop_level==0.0)
      stop_level=(m_symbol.Ask()-m_symbol.Bid())*3.0;
   if(freeze_level<=0.0 || stop_level<=0.0)
      return(false);
   level=(freeze_level>stop_level)?freeze_level:stop_level;
   double spread=m_symbol.Spread()*m_adjusted_point;
   level=(level>spread)?level:spread;
//---
   return(true);
  }
//+------------------------------------------------------------------+
//| Close positions                                                  |
//+------------------------------------------------------------------+
void ClosePositions(const ENUM_POSITION_TYPE pos_type,const double level)
  {
   for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of current positions
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name()/* && m_position.Magic()==InpMagic*/)
            if(m_position.PositionType()==pos_type)
              {
               if(m_position.PositionType()==POSITION_TYPE_BUY)
                 {
                  bool take_profit_level=(m_position.TakeProfit()!=0.0 && m_position.TakeProfit()-m_position.PriceCurrent()>=level) || m_position.TakeProfit()==0.0;
                  bool stop_loss_level=(m_position.StopLoss()!=0.0 && m_position.PriceCurrent()-m_position.StopLoss()>=level) || m_position.StopLoss()==0.0;
                  if(take_profit_level && stop_loss_level)
                     m_trade.PositionClose(m_position.Ticket()); // close a position by the specified symbol
                 }
               if(m_position.PositionType()==POSITION_TYPE_SELL)
                 {
                  bool take_profit_level=(m_position.TakeProfit()!=0.0 && m_position.PriceCurrent()-m_position.TakeProfit()>=level) || m_position.TakeProfit()==0.0;
                  bool stop_loss_level=(m_position.StopLoss()!=0.0 && m_position.StopLoss()-m_position.PriceCurrent()>=level) || m_position.StopLoss()==0.0;
                  if(take_profit_level && stop_loss_level)
                     m_trade.PositionClose(m_position.Ticket()); // close a position by the specified symbol
                 }
               PlaySound("ok.wav");
              }
  }
//+------------------------------------------------------------------+
//| Refreshes the symbol quotes data                                 |
//+------------------------------------------------------------------+
bool RefreshRates()
  {
//--- refresh rates
   if(!m_symbol.RefreshRates())
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: ","RefreshRates error");
      return(false);
     }
//--- protection against the return value of "zero"
   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: ","Ask == 0.0 OR Bid == 0.0");
      return(false);
     }
//---
   return(true);
  }
//+------------------------------------------------------------------+
Файлы:
0002.mq5  11 kb
 
MrBrooklin:

.. до сих пор не пойму смысл постоянно встречающейся фразы, начинающейся со слова "Возвращает".

Кто возвращает, кому возвращает, куда возвращет, зачем возвращает? До сих пор толком так и не могу разобраться...

Возможно, у меня получится пояснить.

Допустим, что у вас в данный момент на экране колеблются котировки инструмента(символа, он же, например EUR/USD), а также работает программа/советник/робот в терминале. Робот исполняет код, который вы в него забили. И в  этом коде есть такие строки:

           ... 
 
           if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;

           double OpenPrice = OrderOpenPrice(); 

	   ...
"orderSelect" - это торговая функция, она выбирает уже открытый ордер для дальнейшей работы с ним.
//В данном примере, если выбрать ордер не удалось (...==false), то дальнейшее выполнение функции " if " прерывается командой "break". 

Далее. Ордер у нас выбран торговой функцией OrderSelect. Теперь мы работаем с ним, с конкретным ордером. Для простоты восприятия примем условие, что у нас открыто всего два ордера.

Далее по коду  мы вводим переменную OpenPrice  [double типа] и присваиваем ей значение цены, по которой был открыт выбранный нами ордер (участок кода  OpenPrice=OrderOpenPrice(); )

ТАК ВОТ ТУТ как раз объяснение для вас, что значит ВОЗВРАЩЕНИЕ параметра. Торговая функция  OrderOpenPrice возвращает значение текущей цены инструмента. То есть, после того, как программа обратилась на сервер с запросом текущей цены, она вернула вам значение этой цены и присвоила это значение переменной.

 

Добавил Индикатор MACD 

//+------------------------------------------------------------------+
//|                                                         0003.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#define   InpMagic  182979245
//---
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
//---
CPositionInfo  m_position; // trade position object
CTrade         m_trade;    // trading object
CSymbolInfo    m_symbol;   // symbol info object
//---
input double InpLots=0.01; // Lots
//---
double   m_adjusted_point; // point value adjusted for 3 or 5 points
int      handle_iCustom;   // variable for storing the handle of the iStochastic indicator
datetime ExtPrevBars=0;    // "0" -> D'1970.01.01 00:00';
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(!m_symbol.Name(Symbol())) // sets symbol name
      return(INIT_FAILED);;
//---
   m_trade.SetExpertMagicNumber(InpMagic);
   m_trade.SetMarginMode();
   m_trade.SetTypeFillingBySymbol(m_symbol.Name());
//--- tuning for 3 or 5 digits
   int digits_adjust=1;
   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
      digits_adjust=10;
   m_adjusted_point=m_symbol.Point()*digits_adjust;
//---
   m_trade.SetDeviationInPoints(3*digits_adjust);
   if(!m_position.Select(Symbol()))
     {
      CheckObject();
      CheckObjectClose();
     }
   handle_iCustom=iMACD(m_symbol.Name(),Period(),12,26,9,PRICE_CLOSE);
//--- if the handle is not created
   if(handle_iCustom==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the handle_iCustom indicator for the symbol %s/%s, error code %d",
                  m_symbol.Name(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   if(ObjectFind(0,"BUY")==0)
     {
      ObjectDelete(0,"BUY");
     }
   if(ObjectFind(0,"SELL")==0)
     {
      ObjectDelete(0,"SELL");
     }
//---
   if(ObjectFind(0,"Close BUY")==0)
     {
      ObjectDelete(0,"Close BUY");
     }
   if(ObjectFind(0,"Close SELL")==0)
     {
      ObjectDelete(0,"Close SELL");
     }
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   CheckButon();
   CheckButonClose();
   if(SearchTradingSignals())
     {
      return;
     }
  }
//+------------------------------------------------------------------+
//| Check for long position closing                                  |
//+------------------------------------------------------------------+
bool CheckButon(void)
  {
//---
   bool res=false;
     {
      if(ObjectGetInteger(0,"BUY",OBJPROP_STATE)!=0)
        {
         ObjectSetInteger(0,"BUY",OBJPROP_STATE,0);
         double price=m_symbol.Ask();
           {
            //--- open position
            if(m_trade.PositionOpen(m_symbol.Name(),ORDER_TYPE_BUY,InpLots,price,0.0,0.0))
               printf("Position by %s to be opened",m_symbol.Name());
            else
              {
               printf("Error opening BUY position by %s : '%s'",m_symbol.Name(),m_trade.ResultComment());
               printf("Open parameters : price=%f,TP=%f",price,0.0);
              }
            PlaySound("ok.wav");
           }
        }
      if(ObjectGetInteger(0,"SELL",OBJPROP_STATE)!=0)
        {
         ObjectSetInteger(0,"SELL",OBJPROP_STATE,0);
         double price0=m_symbol.Bid();
           {
            if(m_trade.PositionOpen(m_symbol.Name(),ORDER_TYPE_SELL,InpLots,price0,0.0,0.0))
               printf("Position by %s to be opened",m_symbol.Name());
            else
              {
               printf("Error opening SELL position by %s : '%s'",m_symbol.Name(),m_trade.ResultComment());
               printf("Open parameters : price=%f,TP=%f",price0,0.0);
              }
            PlaySound("ok.wav");
           }
        }
      res=true;
     }
//--- result
   return(res);
  }
//+------------------------------------------------------------------+
//| Check for long position closing                                  |
//+------------------------------------------------------------------+
bool CheckObject(void)
  {
//---
   bool res=false;
     {
      ObjectCreate(0,"BUY",OBJ_BUTTON,0,0,0);
      ObjectSetInteger(0,"BUY",OBJPROP_XDISTANCE,ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)-102);
      ObjectSetInteger(0,"BUY",OBJPROP_YDISTANCE,37);
      ObjectSetString(0,"BUY",OBJPROP_TEXT,"BUY");
      ObjectSetInteger(0,"BUY",OBJPROP_BGCOLOR,clrMediumSeaGreen);
      ObjectCreate(0,"SELL",OBJ_BUTTON,0,0,0);
      ObjectSetInteger(0,"SELL",OBJPROP_XDISTANCE,ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)-50);
      ObjectSetInteger(0,"SELL",OBJPROP_YDISTANCE,37);
      ObjectSetString(0,"SELL",OBJPROP_TEXT,"SELL");
      ObjectSetInteger(0,"SELL",OBJPROP_BGCOLOR,clrDarkOrange);
      res=true;
     }
//--- result
   return(res);
  }
//+------------------------------------------------------------------+
//| Check for long position closing                                  |
//+------------------------------------------------------------------+
bool CheckButonClose(void)
  {
//---
   bool res=false;
   double level;
     {
      if(ObjectGetInteger(0,"Close BUY",OBJPROP_STATE)!=0)
        {
         ObjectSetInteger(0,"Close BUY",OBJPROP_STATE,0);
         if(FreezeStopsLevels(level))
            ClosePositions(POSITION_TYPE_BUY,level);
         PlaySound("ok.wav");
        }
      if(ObjectGetInteger(0,"Close SELL",OBJPROP_STATE)!=0)
        {
         ObjectSetInteger(0,"Close SELL",OBJPROP_STATE,0);
         if(FreezeStopsLevels(level))
            ClosePositions(POSITION_TYPE_SELL,level);
         PlaySound("ok.wav");
        }
      res=true;
     }
//--- result
   return(res);
  }
//+------------------------------------------------------------------+
//| Check for long position closing                                  |
//+------------------------------------------------------------------+
bool CheckObjectClose(void)
  {
//---
   bool res=false;
     {
      ObjectCreate(0,"Close BUY",OBJ_BUTTON,0,0,0);
      ObjectSetInteger(0,"Close BUY",OBJPROP_XDISTANCE,ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)-102);
      ObjectSetInteger(0,"Close BUY",OBJPROP_YDISTANCE,57);
      ObjectSetString(0,"Close BUY",OBJPROP_TEXT,"Close BUY");
      ObjectSetInteger(0,"Close BUY",OBJPROP_BGCOLOR,clrTomato);
      ObjectCreate(0,"Close SELL",OBJ_BUTTON,0,0,0);
      ObjectSetInteger(0,"Close SELL",OBJPROP_XDISTANCE,ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)-50);
      ObjectSetInteger(0,"Close SELL",OBJPROP_YDISTANCE,57);
      ObjectSetString(0,"Close SELL",OBJPROP_TEXT,"Close SELL");
      ObjectSetInteger(0,"Close SELL",OBJPROP_BGCOLOR,clrFireBrick);
      res=true;
     }
//--- result
   return(res);
  }
//+------------------------------------------------------------------+
//| Check Freeze and Stops levels                                    |
//+------------------------------------------------------------------+
bool FreezeStopsLevels(double &level)
  {
//--- check Freeze and Stops levels
   if(!RefreshRates() || !m_symbol.Refresh())
      return(false);
//--- FreezeLevel -> for pending order and modification
   double freeze_level=m_symbol.FreezeLevel()*m_symbol.Point();
   if(freeze_level==0.0)
      freeze_level=(m_symbol.Ask()-m_symbol.Bid())*3.0;
//--- StopsLevel -> for TakeProfit and StopLoss
   double stop_level=m_symbol.StopsLevel()*m_symbol.Point();
   if(stop_level==0.0)
      stop_level=(m_symbol.Ask()-m_symbol.Bid())*3.0;
   if(freeze_level<=0.0 || stop_level<=0.0)
      return(false);
   level=(freeze_level>stop_level)?freeze_level:stop_level;
   double spread=m_symbol.Spread()*m_adjusted_point;
   level=(level>spread)?level:spread;
//---
   return(true);
  }
//+------------------------------------------------------------------+
//| Close positions                                                  |
//+------------------------------------------------------------------+
void ClosePositions(const ENUM_POSITION_TYPE pos_type,const double level)
  {
   for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of current positions
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name()/* && m_position.Magic()==InpMagic*/)
            if(m_position.PositionType()==pos_type)
              {
               if(m_position.PositionType()==POSITION_TYPE_BUY)
                 {
                  bool take_profit_level=(m_position.TakeProfit()!=0.0 && m_position.TakeProfit()-m_position.PriceCurrent()>=level) || m_position.TakeProfit()==0.0;
                  bool stop_loss_level=(m_position.StopLoss()!=0.0 && m_position.PriceCurrent()-m_position.StopLoss()>=level) || m_position.StopLoss()==0.0;
                  if(take_profit_level && stop_loss_level)
                     m_trade.PositionClose(m_position.Ticket()); // close a position by the specified symbol
                 }
               if(m_position.PositionType()==POSITION_TYPE_SELL)
                 {
                  bool take_profit_level=(m_position.TakeProfit()!=0.0 && m_position.PriceCurrent()-m_position.TakeProfit()>=level) || m_position.TakeProfit()==0.0;
                  bool stop_loss_level=(m_position.StopLoss()!=0.0 && m_position.StopLoss()-m_position.PriceCurrent()>=level) || m_position.StopLoss()==0.0;
                  if(take_profit_level && stop_loss_level)
                     m_trade.PositionClose(m_position.Ticket()); // close a position by the specified symbol
                 }
               PlaySound("ok.wav");
              }
  }
//+------------------------------------------------------------------+
//| Refreshes the symbol quotes data                                 |
//+------------------------------------------------------------------+
bool RefreshRates()
  {
//--- refresh rates
   if(!m_symbol.RefreshRates())
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: ","RefreshRates error");
      return(false);
     }
//--- protection against the return value of "zero"
   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: ","Ask == 0.0 OR Bid == 0.0");
      return(false);
     }
//---
   return(true);
  }
//+------------------------------------------------------------------+
//| Search trading signals                                           |
//+------------------------------------------------------------------+
bool SearchTradingSignals(void)
  {
//--- we work only at the time of the birth of new bar
   datetime time_0=iTime(m_symbol.Name(),Period(),0);
   if(time_0==ExtPrevBars)
      return(false);
   ExtPrevBars=time_0;
   if(!RefreshRates())
     {
      ExtPrevBars=0;
      return(false);
     }
//---
   double level;
   double main[],signal[];
   ArraySetAsSeries(main,true);
   ArraySetAsSeries(signal,true);
   int start_pos=0,count=3;
   if(!iGetArray(handle_iCustom,MAIN_LINE,start_pos,count,main) ||
      !iGetArray(handle_iCustom,SIGNAL_LINE,start_pos,count,signal))
     {
      ExtPrevBars=0;
      return(false);
     }
//--- check for long position (BUY) possibility
   if(main[0]<0)
      if(main[0]>signal[0] && main[1]<signal[1])
        {
         double price=m_symbol.Ask();
           {
            //--- open position
            if(m_trade.PositionOpen(m_symbol.Name(),ORDER_TYPE_BUY,InpLots,price,0.0,0.0))
               printf("Position by %s to be opened",m_symbol.Name());
            else
              {
               printf("Error opening BUY position by %s : '%s'",m_symbol.Name(),m_trade.ResultComment());
               printf("Open parameters : price=%f,TP=%f",price,0.0);
              }
            PlaySound("ok.wav");
           }
         if(FreezeStopsLevels(level))
            ClosePositions(POSITION_TYPE_SELL,level);
        }
//--- check for short position (SELL) possibility
   if(main[0]>0)
      if(main[0]<signal[0] && main[1]>signal[1])
        {
         double price0=m_symbol.Bid();
           {
            if(m_trade.PositionOpen(m_symbol.Name(),ORDER_TYPE_SELL,InpLots,price0,0.0,0.0))
               printf("Position by %s to be opened",m_symbol.Name());
            else
              {
               printf("Error opening SELL position by %s : '%s'",m_symbol.Name(),m_trade.ResultComment());
               printf("Open parameters : price=%f,TP=%f",price0,0.0);
              }
            PlaySound("ok.wav");
           }
         if(FreezeStopsLevels(level))
            ClosePositions(POSITION_TYPE_BUY,level);
        }
//---
   return(true);
  }
//+------------------------------------------------------------------+
//| Get value of buffers                                             |
//+------------------------------------------------------------------+
double iGetArray(const int handle,const int buffer,const int start_pos,const int count,double &arr_buffer[])
  {
   bool result=true;
   if(!ArrayIsDynamic(arr_buffer))
     {
      Print("This a no dynamic array!");
      return(false);
     }
   ArrayFree(arr_buffer);
//--- reset error code
   ResetLastError();
//--- fill a part of the iBands array with values from the indicator buffer
   int copied=CopyBuffer(handle,buffer,start_pos,count,arr_buffer);
   if(copied!=count)
     {
      //--- if the copying fails, tell the error code
      PrintFormat("Failed to copy data from the indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(false);
     }
   return(result);
  }
//+------------------------------------------------------------------+
Файлы:
0003.PNG  107 kb
0003.mq5  15 kb
 
SanAlex:

Добавил Индикатор MACD 

Самое основное есть - теперь всё за Вами

 
4elovechishe:

Возможно, у меня получится пояснить.

Допустим, что у вас в данный момент на экране колеблются котировки инструмента(символа, он же, например EUR/USD), а также работает программа/советник/робот в терминале. Робот исполняет код, который вы в него забили. И в  этом коде есть такие строки:

"orderSelect" - это торговая функция, она выбирает уже открытый ордер для дальнейшей работы с ним.
//В данном примере, если выбрать ордер не удалось (...==false), то дальнейшее выполнение функции " if " прерывается командой "break". 

Далее. Ордер у нас выбран торговой функцией OrderSelect. Теперь мы работаем с ним, с конкретным ордером. Для простоты восприятия примем условие, что у нас открыто всего два ордера.

Далее по коду  мы вводим переменную OpenPrice  [double типа] и присваиваем ей значение цены, по которой был открыт выбранный нами ордер (участок кода  OpenPrice=OrderOpenPrice(); )

ТАК ВОТ ТУТ как раз объяснение для вас, что значит ВОЗВРАЩЕНИЕ параметра. Торговая функция  OrderOpenPrice возвращает значение текущей цены инструмента. То есть, после того, как программа обратилась на сервер с запросом текущей цены, она вернула вам значение этой цены и присвоила это значение переменной.

Спасибо Вам за разъяснение. Надеюсь, что оно также поможет Роману в освоении языка программирования.

С уважением, Владимир.

 

Здравствуйте! Ну может кто-нибудь и мне поможет...

Сейчас разбираюсь с механизмами открытия/закрытия ордеров и столкнулся с проблемой закрытия открытых позиций.

Код простой. Суть алгоритма - на графике рисуется МА (скользящая средняя) с периодом 100. Если предыдущая свеча [1] открылась выше MA, а закрылась ниже МА , то со следующей свечи [0] открывается SELL-ордер на продажу.

//(Условия для покупки противоположны. Я их не расписываю)

Для закрытия ордера следующие условия - текущая цена прошла от цены открытия ордера устанавливаемое значение пунктов, например 40.

Пример: открылся шот на Bid=1.20045, закрыться он должен на Ask= 1.20005.

Ну и короче не работает у меня что-то..(( Код открытия и закрытия запакованы в 2 соответствующие функции, которые в свою очередь вызываются функцией OnTick(). По идее с каждым тиком должно проверяться условие закрытие, но по факту цена может опуститься ниже заданного уровня (уровня закрытия), а ордер при этом не закроется. Скрины и код прилагаю.

 
4elovechishe:

Здравствуйте! Ну может кто-нибудь и мне поможет...

Сейчас разбираюсь с механизмами открытия/закрытия ордеров и столкнулся с проблемой закрытия открытых позиций.

Код простой. Суть алгоритма - на графике рисуется МА (скользящая средняя) с периодом 100. Если предыдущая свеча [1] открылась выше MA, а закрылась ниже МА , то со следующей свечи [0] открывается SELL-ордер на продажу.

//(Условия для покупки противоположны. Я их не расписываю)

Для закрытия ордера следующие условия - текущая цена прошла от цены открытия ордера устанавливаемое значение пунктов, например 40.

Пример: открылся шот на Bid=1.20045, закрыться он должен на Ask= 1.20005.

Ну и короче не работает у меня что-то..(( Код открытия и закрытия запакованы в 2 соответствующие функции, которые в свою очередь вызываются функцией OnTick(). По идее с каждым тиком должно проверяться условие закрытие, но по факту цена может опуститься ниже заданного уровня (уровня закрытия), а ордер при этом не закроется. Скрины и код прилагаю.

На форуме есть ветка по ссылке https://www.mql5.com/ru/forum/160683/page767#comment_10725713

Там Вы быстрее получите помощь.

С уважением, Владимир.

Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
  • 2019.02.21
  • www.mql5.com
В этой ветке я хочу начать свою помощь тем, кто действительно хочет разобраться и научиться программированию на новом MQL4 и желает легко перейти н...