Как начать работу с MQL5 - страница 4

 
Vladimir Karputov:

Вам нужно переделать код: запрашивать данные не с одного бара, а с двух. И проверять условие не на одном баре - а на двух.

Так и было ) :


Будет:

Спасибо. Я пробовал редактировать его, но я почти разбросал весь код. Как я могу отредактировать это, пожалуйста, чтобы добавить покупку на следующем баре, а не сразу, т.е. либо по цене закрытия текущей свечи или по цене открытия новой свечи. Или даже сказать ему, чтобы проверить последний бар, если условия были выполнены, то триггер покупки (не думаю, что это будет работать хорошо, но что я знаю).


 if (ask <= Highoo && ask >= low_value && ask<= 10500 )
   {
    if(IsNewCandle()){tradenow=1;}
      if(Allowed_position() < allowedposition && tradenow==1)
       if(rat_value[0] >= current_stoch_low_value && rat_value[0] <= current_stoch_high_value &&
          rat_value[1] >= prev_stoch_low_value   && rat_value[1] <= prev_stoch_high_value &&
          rsi_value[0] >= rsi_low_value           && rsi_value[0] <= rsi_high_value &&
          rsi_value[1] > rsi_value [0] )
      
          { if(trade.Buy(NormalizeDouble(lot_size, 2),NULL,ask,0,0,NULL))
             {
              ulong ticket = trade.ResultOrder();
              tradenow=0;
              set_tp(ticket);
             }
          
         }
 
aodunusi:

Спасибо. Я пробовал редактировать его, но почти разбросал весь код. Как я могу отредактировать это, чтобы добавить покупку на следующем баре, а не сразу, т.е. либо по цене закрытия текущей свечи, либо по цене открытия новой свечи. Или даже сказать ему, чтобы он проверял последний бар, если условия были выполнены, то запускал покупку (не думаю, что это будет работать хорошо, но что я знаю).


Ваши объяснения очень запутанны. В таких случаях я рекомендую нарисовать картинку. На картинке покажите условие для сигнала.
 
aodunusi :

Спасибо. Я пробовал редактировать его, но почти разбросал весь код. Как я могу отредактировать это, чтобы добавить покупку на следующем баре, а не сразу, т.е. либо по цене закрытия текущей свечи, либо по цене открытия новой свечи. Или даже сказать ему, чтобы он проверял последний бар, если условия были выполнены, то запускал покупку (не думаю, что это будет работать хорошо, но что я знаю).


Простой советник iRSI, версия1.006

Вот как советник работает сейчас: мы проверяем сигнал ТОЛЬКО В МОМЕНТ РОЖДЕНИЯ НОВОГО БАРА. Новый бар имеет индекс # 0, мы называем новый бар "Текущий бар". Пример сигнала на покупку: если два предыдущих бара (бар № 1 и бар № 2) находятся ниже линии "30", это сигнал на покупку:

Простой советник iRSI 1.006

Рис. 1. Простой советник iRSI, версия1.006

Код:

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- we work only at the time of the birth of new bar
   datetime time_0=iTime(Symbol(),Period(),0);
   if(time_0==m_prev_bars)
      return;
   m_prev_bars=time_0;
//---
   double rsi_2=iRSIGet(2);
   double rsi_1=iRSIGet(1);
   if(rsi_2==EMPTY_VALUE || rsi_1==EMPTY_VALUE)
      return;
//---
   if(rsi_2>Inp_RSI_Level_UP && rsi_1>Inp_RSI_Level_UP)
      m_trade.Sell(1.0);
   else if(rsi_2<Inp_RSI_Level_DOWN && rsi_1<Inp_RSI_Level_DOWN)
      m_trade.Buy(1.0);
  }
Файлы:
 
Vladimir Karputov:

Простой советник iRSI, версия1.006

Советник работает следующим образом: мы проверяем сигнал ТОЛЬКО В МОМЕНТ РОЖДЕНИЯ НОВОГО БАРА. Новый бар имеет индекс # 0, мы называем его "Текущий бар". Пример сигнала на покупку: если два предыдущих бара (бар № 1 и бар № 2) находятся ниже линии "30", это сигнал на покупку:

Рис. 1. Простой советник iRSI, версия1.006

Код:

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

Я хочу, чтобы он проверял текущий бар до тех пор, пока не будут выполнены параметры или условия, и как только это произойдет, он обычно открывает покупку, но вместо этого я хочу, чтобы он удерживал эту заявку, а затем запускал покупку на открытии новой свечи или когда текущая свеча заканчивается (все то же самое).

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

Спасибо за помощь до сих пор
Файлы:
 
aodunusi:
Не смог заставить его работать... Это файл для советника, пожалуйста, помогите мне взглянуть на него, чтобы понять меня.

Я хочу, чтобы он проверял текущий бар до тех пор, пока не будут выполнены параметры или условия, и как только это произойдет, он обычно открывает покупку, но вместо этого я хочу, чтобы он удерживал эту заявку, а затем запускал покупку на открытии новой свечи или когда текущая свеча заканчивается (все то же самое).

Ваш советник проверяет бары за барами, то есть каждый бар показывает среднее значение, а я проверяю каждый тик своим советником, и как только тик на текущем баре удовлетворяет моим условиям, я
Покупка срабатывает сразу после получения сигнала, а сигнал обычно медленный, поэтому я хочу отложить покупку с текущей свечи на следующую после выполнения условия. То есть я проверяю тики предыдущей свечи и, как только мое условие выполнено, я хочу отложить или задержать ордер на покупку или продажу до следующего бара, который откроется или когда закроется текущий бар (это одно и то же).
Файлы:
 
aodunusi :
Не смог заставить его работать... Это файл для советника, пожалуйста, помогите мне посмотреть на него, чтобы понять меня.

Я хочу, чтобы он проверял текущий бар до тех пор, пока не будут выполнены параметры или условия, и как только это произойдет, он обычно открывает покупку, но вместо этого я хочу, чтобы он удерживал эту заявку, а затем запускал покупку на открытии новой свечи или когда текущая свеча заканчивается (все то же самое).

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

Спасибо за помощь до сих пор

Простой советник iRSI, версия1.007

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


//+------------------------------------------------------------------+
//|                                          iRSI simple advisor.mq5 |
//|                              Copyright © 2020, Vladimir Karputov |

//+------------------------------------------------------------------+
#property copyright "Copyright © 2020, Vladimir Karputov"

#property version   "1.007"
//---
#include <Trade\Trade.mqh>
CTrade         m_trade;                         // trading object
//--- input parameters
input int                  Inp_RSI_ma_period       = 14;          // RSI: averaging period
input ENUM_APPLIED_PRICE   Inp_RSI_applied_price   = PRICE_CLOSE; // RSI: type of price
input double               Inp_RSI_Level_UP        = 70;          // RSI Level UP
input double               Inp_RSI_Level_DOWN      = 30;          // RSI Level DOWN
//---
int      handle_iRSI;                           // variable for storing the handle of the iRSI indicator
datetime m_prev_bars                = 0;        // "0" -> D'1970.01.01 00:00';
int      m_signal                   = 0;        // "-1" -> SELL, "0" -> NONE, "1" ->BUY
bool     m_wait                     = false;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create handle of the indicator iRSI
   handle_iRSI=iRSI(Symbol(),Period(),Inp_RSI_ma_period,Inp_RSI_applied_price);
//--- if the handle is not created
   if(handle_iRSI==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iRSI indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double rsi_0=iRSIGet(0);
   if(rsi_0==EMPTY_VALUE)
      return;
//--- we check the signal at each tick
   if(!m_wait)
     {
      if(rsi_0<Inp_RSI_Level_DOWN)
        {
         m_signal=1; // we remember the BUY signal
         m_wait=true;
        }
      else
        {
         if(rsi_0>Inp_RSI_Level_UP)
           {
            m_signal=-1; // we remember the SELL signal
            m_wait=true;
           }
        }
     }
//--- we work only at the time of the birth of new bar
   datetime time_0=iTime(Symbol(),Period(),0);
   if(time_0==m_prev_bars)
      return;
   m_prev_bars=time_0;

   if(m_signal==1)
      m_trade.Buy(1.0);
   else
      if(m_signal==-1)
         m_trade.Sell(1.0);
//--- we reset the signal
   if(m_signal!=0)
     {
      m_signal=0;
      m_wait=false;
     }
//---
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//---
   int d=0;
  }
//+------------------------------------------------------------------+
//| Get value of buffers for the iRSI                                |
//+------------------------------------------------------------------+
double iRSIGet(const int index)
  {
   double RSI[1];
//--- reset error code
   ResetLastError();
//--- fill a part of the iRSI array with values from the indicator buffer that has 0 index
   if(CopyBuffer(handle_iRSI,0,index,1,RSI)<0)
     {
      //--- if the copying fails, tell the error code
      PrintFormat("Failed to copy data from the iRSI indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(EMPTY_VALUE);
     }
   return(RSI[0]);
  }
//+------------------------------------------------------------------+
Файлы:
 

Пример CopyRates

Используется первая форма вызова CopyRates:

int  CopyRates(
   string           symbol_name,       // symbol name
   ENUM_TIMEFRAMES  timeframe,         // period
   int              start_pos,         // start position
   int              count,             // data count to copy
   MqlRates         rates_array[]      // target array to copy
   );


Обратите внимание, что ArraySetAsSeries применяется к массиву ' rates' - в данном случае rates [0] соответствует самому правому бару на графике.

   MqlRates rates[];
   ArraySetAsSeries(rates,true);


Полный код:

//+------------------------------------------------------------------+
//|                                            Example CopyRates.mq5 |
//|                              Copyright © 2020, Vladimir Karputov |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2020, Vladimir Karputov"
#property version   "1.000"
//--- input parameters
input uchar InpCount = 9; // Data count to copy
//---
datetime m_prev_bars                = 0;        // "0" -> D'1970.01.01 00:00';
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- we work only at the time of the birth of new bar
   datetime time_0=iTime(Symbol(),Period(),0);
   if(time_0==m_prev_bars)
      return;
   m_prev_bars=time_0;

   MqlRates rates[];
   ArraySetAsSeries(rates,true);

   int start_pos=0,count=(InpCount<1 || InpCount>9)?9:InpCount;
   if(CopyRates(Symbol(),Period(),start_pos,count,rates)!=count)
     {
      m_prev_bars=0;
      return;
     }

   string text="";
   for(int i=count-1; i>=0; i--)
     {
      text=text+
           TimeToString(rates[i].time,TIME_DATE|TIME_SECONDS)+
           " Open "+DoubleToString(rates[i].open,Digits())+
           " High "+DoubleToString(rates[i].high,Digits())+
           " Low "+DoubleToString(rates[i].low,Digits())+
           " Close "+DoubleToString(rates[i].close,Digits())+"\n";
     }
   Comment(text);
  }
//+------------------------------------------------------------------+


Результат:

Пример CopyRates

Documentation on MQL5: Timeseries and Indicators Access / CopyRates
Documentation on MQL5: Timeseries and Indicators Access / CopyRates
  • www.mql5.com
Gets history data of MqlRates structure of a specified symbol-period in specified quantity into the rates_array array. The elements ordering of the copied data is from present to the past, i.e., starting position of 0 means the current bar. If you know the amount of data you need to copy, it should better be done to a statically allocated...
Файлы:
 

Пример: удалить все отложенные ордера определенного типа.

Пример в виде скрипта: во входном параметре ' Delete all: ' задается тип отложенного ордера, а затем вызывается функция удаления 'DeleteOrders '

//+------------------------------------------------------------------+
//|                                               Pending Delete.mq5 |
//|                              Copyright © 2020, Vladimir Karputov |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2020, Vladimir Karputov"
#property version   "1.000"
//---
#include <Trade\Trade.mqh>
#include <Trade\OrderInfo.mqh>
//---
CTrade         m_trade;                      // object of CTrade class
COrderInfo     m_order;                      // object of COrderInfo class
//---
#property script_show_inputs
//---
//+------------------------------------------------------------------+
//| Enum Pending                                                     |
//+------------------------------------------------------------------+
enum ENUM_PENDING
  {
   buy_limit=2,   // Buy Limit
   sell_limit=3,  // Sell limit
   buy_stop=4,    // Buy Stop
   sell_stop=3,   // Sell Stop
  };
//--- input parameters
input ENUM_PENDING   InpPending  = buy_limit; // Delete all:
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   DeleteOrders((ENUM_ORDER_TYPE)InpPending);
  }
//+------------------------------------------------------------------+
//| Delete Orders                                                    |
//+------------------------------------------------------------------+
void DeleteOrders(const ENUM_ORDER_TYPE order_type)
  {
   for(int i=OrdersTotal()-1; i>=0; i--) // returns the number of current orders
      if(m_order.SelectByIndex(i))     // selects the pending order by index for further access to its properties
         if(m_order.OrderType()==order_type)
           {
            m_trade.OrderDelete(m_order.Ticket());
            continue;
           }
  }
//+------------------------------------------------------------------+

Это самый простой пример: нет фильтра по символу, нет фильтра по магическому номеру, нет проверки минимального расстояния (уровня заморозки), нет цикла, гарантирующего удаление.

Файлы:
 

Пример: Расчет позиций и отложенных ордеров

Код: Calculate Positions and Pending Orders.mq5

Используются торговые классы CPositionInfo и COrderInfo(Не путайте текущие отложенные ордера с позициями, которые также отображаются на вкладке "Торговля" панели "Инструменты" клиентского терминала).

Код:

//+------------------------------------------------------------------+
//|                       Calculate Positions and Pending Orders.mq5 |
//|                         Copyright © 2019-2020, Vladimir Karputov |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2019-2020, Vladimir Karputov"
#property version   "1.001"
//---
#include <Trade\Trade.mqh>
#include <Trade\OrderInfo.mqh>
//---
CPositionInfo  m_position;                   // object of CPositionInfo class
COrderInfo     m_order;                      // object of COrderInfo class
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   int buys=0,sells=0;
   int buy_limits=0,sell_limits=0,buy_stops=0,sell_stops=0;

   CalculateAllPositions(buys,sells);
   CalculateAllPendingOrders(buy_limits,sell_limits,buy_stops,sell_stops);

   string text="BUY: "+IntegerToString(buys)+", SELL: "+IntegerToString(sells)+"\n"+
               "Buy limits "+IntegerToString(buy_limits)+", Sell limits "+IntegerToString(sell_limits)+
               ", Buy stops "+IntegerToString(buy_stops)+", Sell stops "+IntegerToString(sell_stops);
   Comment(text);
//---
  }
//+------------------------------------------------------------------+
//| Calculate all positions Buy and Sell                             |
//+------------------------------------------------------------------+
void CalculateAllPositions(int &count_buys,int &count_sells)
  {
   count_buys=0;
   count_sells=0;

   for(int i=PositionsTotal()-1; i>=0; i--)
      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()==POSITION_TYPE_BUY)
            count_buys++;

         if(m_position.PositionType()==POSITION_TYPE_SELL)
            count_sells++;
        }
//---
   return;
  }
//+------------------------------------------------------------------+
//| Calculate all pending orders                                     |
//+------------------------------------------------------------------+
void CalculateAllPendingOrders(int &count_buy_limits,int &count_sell_limits,int &count_buy_stops,int &count_sell_stops)
  {
   count_buy_limits  = 0;
   count_sell_limits = 0;
   count_buy_stops   = 0;
   count_sell_stops  = 0;

   for(int i=OrdersTotal()-1; i>=0; i--) // returns the number of current orders
      if(m_order.SelectByIndex(i))     // selects the pending order by index for further access to its properties
         //if(m_order.Symbol()==m_symbol.Name() && m_order.Magic()==InpMagic)
        {
         if(m_order.OrderType()==ORDER_TYPE_BUY_LIMIT)
            count_buy_limits++;
         else
            if(m_order.OrderType()==ORDER_TYPE_SELL_LIMIT)
               count_sell_limits++;
            else
               if(m_order.OrderType()==ORDER_TYPE_BUY_STOP)
                  count_buy_stops++;
               else
                  if(m_order.OrderType()==ORDER_TYPE_SELL_STOP)
                     count_sell_stops++;
        }
  }
//+------------------------------------------------------------------+
Documentation on MQL5: Standard Library / Trade Classes / CPositionInfo
Documentation on MQL5: Standard Library / Trade Classes / CPositionInfo
  • www.mql5.com
Standard Library / Trade Classes / CPositionInfo - Reference on algorithmic/automated trading language for MetaTrader 5
 

Простой пример. Отображение значений индикатора iADX на графике

Это простой пример: как получить значения индикатора iADX. Для контроля полученные значения выводятся на экран.

Код:

//+------------------------------------------------------------------+
//|                               Example iADX values on a chart.mq5 |
//|                              Copyright © 2020, Vladimir Karputov |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2020, Vladimir Karputov"
#property version   "1.00"
//--- input parameters
input int      Inp_ADX_adx_period= 14;       // ADX: averaging period
//---
int    handle_iADX;                          // variable for storing the handle of the iADX indicator
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create handle of the indicator iADX
   handle_iADX=iADX(Symbol(),Period(),Inp_ADX_adx_period);
//--- if the handle is not created
   if(handle_iADX==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iADX indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   string text="";
   double adx[],plus_di[],minus_di[];
   ArraySetAsSeries(adx,true);
   ArraySetAsSeries(plus_di,true);
   ArraySetAsSeries(minus_di,true);
   int start_pos=0,count=3;
   if(!iGetArray(handle_iADX,MAIN_LINE,start_pos,count,adx) ||
      !iGetArray(handle_iADX,PLUSDI_LINE,start_pos,count,plus_di) ||
      !iGetArray(handle_iADX,MINUSDI_LINE,start_pos,count,minus_di))
     {
      return;
     }

   string text_adx="",text_plus_di="",text_minus_di="";
   for(int i=count-1; i>=0; i--)
     {
      text_adx       = text_adx     +"ADX"+"["+(string)i+"]"+" "+DoubleToString(adx[i],2)      +" | ";
      text_plus_di   = text_plus_di +"+DI"+"["+(string)i+"]"+" "+DoubleToString(plus_di[i],2)  +" | ";
      text_minus_di  = text_minus_di+"-DI"+"["+(string)i+"]"+" "+DoubleToString(minus_di[i],2) +" | ";
     }
   Comment(text_adx+"\n"+text_plus_di+"\n"+text_minus_di);
  }
//+------------------------------------------------------------------+
//| Get value of buffers                                             |
//+------------------------------------------------------------------+
bool iGetArray(const int handle,const int buffer,const int start_pos,
               const int count,double &arr_buffer[])
  {
   bool result=true;
   if(!ArrayIsDynamic(arr_buffer))
     {
      PrintFormat("ERROR! EA: %s, FUNCTION: %s, this a no dynamic array!",__FILE__,__FUNCTION__);
      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("ERROR! EA: %s, FUNCTION: %s, amount to copy: %d, copied: %d, error code %d",
                  __FILE__,__FUNCTION__,count,copied,GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(false);
     }
   return(result);
  }
//+------------------------------------------------------------------+

Результат:

Пример значений iADX на графике

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