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

 
Александр #:
Задача такая, перебирая все акции из списка, смотреть значения скользящей. Как проще всего сделать?
Кого нибудь озадачить.
 

Вот, вроде бы, простая логика. Но не открывает ордера советник. Есть мысли, как заставить? Спасибо.

/*#include <MT5API.mqh>*/
/*#include <MT5TimeSeries.mqh>*/

/*CMT5API mt5;*/
CMT5TimeSeries;
data;

bool is_trend(CMT5TimeSeries, data)
{
   MqlRates ma[];
   if(data.GetMa(data.Close, ma, 50, 0, data.Total()) != -1)
   {
       if(data.Close[data.Total()-1] > ma[data.Total()-1].close)
           return true;
       else
           return false;
   }
   return false;
}

double sl = 0.05;
double locksl = 0.02;

void open_order(string action, double volume, double sl_price)
{
   MqlTick tick;
   SymbolInfoTick(tick, "EURUSD");
   double price = action == "BUY" ? tick.ask : tick.bid;
   MqlTradeRequest request = {0};
   request.action = TRADE_ACTION_DEAL;
   request.symbol = "EURUSD";
   request.volume = volume;
   request.type = action == "BUY" ? ORDER_TYPE_BUY : ORDER_TYPE_SELL;
   request.price = price;
   request.sl = sl_price;
   request.tp = 0;
   request.type_time = ORDER_TIME_GTC;
   request.expiration = ORDER_TIME_GTC;
   request.magic = 5;
   request.comment = "TMSL order";
   request.position = 0;
   MqlTradeResult result;
   if(!OrderSend(request, result))
       Print("Failed to open ", action, " order: ", result.retcode);
   else
       Print("Opened position ", result.order);
}

void close_order(ulong position, double volume, double sl_price)
{
   MqlPosition positions[];
   int total = PositionsGetAll(positions);
   for(int i = 0; i < total; i++)
   {
       if(positions[i].ticket == position)
       {
           string symbol = positions[i].symbol;
           string action = "";
           double price = 0.0;
           if(positions[i].type == ORDER_TYPE_BUY)
           {
               action = "SELL";
               SymbolInfoTick(tick, symbol);
               price = tick.bid;
           }
           else
           {
               action = "BUY";
               SymbolInfoTick(tick, symbol);
               price = tick.ask;
           }
           MqlTradeRequest request = {0};
           request.action = TRADE_ACTION_DEAL;
           request.position = position;
           request.type = positions[i].type == ORDER_TYPE_BUY ? ORDER_TYPE_SELL : ORDER_TYPE_BUY;
           request.volume = volume;
           request.price = price;
           request.symbol = symbol;
           request.sl = sl_price;
           request.tp = 0;
           request.magic = 5;
           request.comment = "Close TMSL order";
           request.type_time = ORDER_TIME_GTC;
           request.type_filling = ORDER_FILLING_RETURN;
           MqlTradeResult result;
           if(!OrderSend(request, result))
               Print("Failed to close position ", position, ": ", result.retcode);
           else
               Print("Closed position ", position);
           break;
       }
   }
}

int OnInit()
{
   if(!mt5.Initialize())
       return INIT_FAILED;

   while(!IsStopped())
   {
       void OnTick()
       {
                   if(!data.CopyRates("EURUSD", PERIOD_M5, 0, 288))
                   {
                           Print("Failed to copy rates");
                           break;
                   }

                   bool trend = is_trend(data);
                   double sl = calc_sl(data);
                   ulong position = 0;
                   double sl_price = 0.0;
                   double volume = 0.0;

                   for(int i = 50; i < data.Total(); i++)
                   {
                           if(position != 0)
                           {
                                   close_order(position, volume, sl_price);
                                   position = 0;
                           }
                           if(trend && position == 0)
                           {
                                   volume = 1000 / data.Close[i];
                                   sl_price = data.Close[i] - sl;
                                   open_order("BUY", volume, sl_price);
                           }
                           else if(!trend && position == 0)
                           {
                                   volume = 1000 / data.Close[i];
                                   sl_price = data.Close[i] + sl;
                                   open_order("SELL", volume, sl_price);
                           }
                           if(position != 0 && (data.Close[i] - sl_price <= 0))
                           {
                                   close_order(position, volume, sl_price);
                                   volume = position.volume * 2;
                                   sl_price = data.Close[i] + locksl;
                                   open_order("SELL", volume, sl_price);
                           }
                           else if(position != 0 && (sl_price - data.Close[i] <= 0))
                           {
                                   close_order(position, volume, sl_price);
                                   volume = position.volume * 2;
                                   sl_price = data.Close[i] - locksl;
                                   open_order("BUY", volume, sl_price);
                           }

/*                         # Sleep(10); // Wait for the next tick*/
                   }
       }   
   }

   return 0;
}

void OnDeinit(const int reason)
{
   mt5.Shutdown();
}
 
maxvoronin74 #:

Вот, вроде бы, простая логика. Но не открывает ордера советник. Есть мысли, как заставить? Спасибо.

OnTick(() внутри бесконечного цикла внутри OnInit() ?

И как OnTick() должен исполниться по Вашему?

 
Artyom Trishkin #:

OnTick(() внутри бесконечного цикла внутри OnInit() ?

И как OnTick() должен исполниться по Вашему?

Сперва даже не понял, что это. Жестоко)))

 

Является ли данный список(желтый) НЕ пользовательским  массивом?

 
ANDREY #:

Является ли данный список(желтый) НЕ пользовательским  массивом?

да

 
Nikolay Ivanov #:

да

А как он называется?  Какое его имя нужно указывать, если из него нужно копировать что то , или передавать в другие функции в качестве аргумента ? 


 
ANDREY #:

А как он называется?  Какое его имя нужно указывать, если из него нужно копировать что то , или передавать в другие функции в качестве аргумента ? 


В данном случае нужно производить поэлементное копирование.

 
Artyom Trishkin #:

В данном случае нужно производить поэлементное копирование.

Как я понял , поэлементно - это при помощи функции OrderSelect () Тем не менее меня раздирает любопытство - есть у этого массива имя или нет ?
У меня такое ощущение что имя этого массива является государственной тайной.

Спасибо

 

Есть индикатор написанной на mql5, надо переводить на mql4.

#property version   "2.000"
#property description "When the 'Main' and 'Signal' lines cross, the indicator signals ..."
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot MACD_Last_Сrossing
#property indicator_label1  "MACD"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrSilver
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2
#property indicator_label2  "Signal"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_DASH
#property indicator_width2  2
//--- input parameters
input group             "MACD"
input int                  Inp_MACD_fast_ema_period= 12;             // MACD: period for Fast average calculation
input int                  Inp_MACD_slow_ema_period= 26;             // MACD: period for Slow average calculation
input int                  Inp_MACD_signal_period  = 9;              // MACD: period for their difference averaging
input ENUM_APPLIED_PRICE   Inp_MACD_applied_price  = PRICE_CLOSE;    // MACD: type of price
input group             "Alerts"
input string               InpSoundName            = "alert.wav";    // Sound Name
input uchar                InpSoundRepetitions     = 3;              // Repetitions
input uchar                InpSoundPause           = 3;              // Pause, in seconds
input bool                 InpMain_and_Signal      = true;           // Main AND Signal
input bool                 InpMain_and_Zero        = true;           // Main AND '0'
input bool                 InpSignal_and_Zero      = true;           // Signal AND '0'
//--- indicator buffers
double   MACDBuffer[];
double   SignalBuffer[];
//---
int      handle_iMACD;                       // variable for storing the handle of the iMACD indicator
int      bars_calculated         = 0;        // we will keep the number of values in the Moving Averages Convergence/Divergence indicator
int      start                   = 0;
datetime m_last_sound            = 0;        // "0" -> D'1970.01.01 00:00';
uchar    m_repetitions           = 0;        //
string   m_text                  = "";       //
datetime m_prev_bars             = 0;        // "0" -> D'1970.01.01 00:00';
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,MACDBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,SignalBuffer,INDICATOR_DATA);
//--- create handle of the indicator iMACD
   handle_iMACD=iMACD(Symbol(),Period(),Inp_MACD_fast_ema_period,Inp_MACD_slow_ema_period,
                      Inp_MACD_signal_period,Inp_MACD_applied_price);
//--- if the handle is not created
   if(handle_iMACD==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iMACD indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
   start=Inp_MACD_fast_ema_period+Inp_MACD_slow_ema_period+Inp_MACD_signal_period;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   if(rates_total<start)
      return(0);
//--- number of values copied from the iMACD indicator
   int values_to_copy;
//--- determine the number of values calculated in the indicator
   int calculated=BarsCalculated(handle_iMACD);
   if(calculated<=0)
     {
      PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError());
      return(0);
     }
//--- if it is the first start of calculation of the indicator or if the number of values in the iMACD indicator changed
//---or if it is necessary to calculated the indicator for two or more bars (it means something has changed in the price history)
   if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1)
     {
      //--- if the MACDBuffer array is greater than the number of values in the iMACD indicator for symbol/period, then we don't copy everything
      //--- otherwise, we copy less than the size of indicator buffers
      if(calculated>rates_total)
         values_to_copy=rates_total;
      else
         values_to_copy=calculated;
     }
   else
     {
      //--- it means that it's not the first time of the indicator calculation, and since the last call of OnCalculate()
      //--- for calculation not more than one bar is added
      values_to_copy=(rates_total-prev_calculated)+1;
     }
//--- fill the arrays with values of the iMACD indicator
//--- if FillArraysFromBuffer returns false, it means the information is nor ready yet, quit operation
   if(!FillArraysFromBuffers(MACDBuffer,SignalBuffer,handle_iMACD,values_to_copy))
      return(0);
//--- memorize the number of values in the Moving Averages indicator Convergence/Divergence
   bars_calculated=calculated;
//--- main loop
//--- we work only at the time of the birth of new bar
   datetime time_0=time[rates_total-1];
   if(time_0!=m_prev_bars)
     {
      m_last_sound   = 0;  // "0" -> D'1970.01.01 00:00';
      m_repetitions  = 0;  //
      m_text         = "";
      m_prev_bars    = time_0;
     }
//---
   int i=rates_total-1;
   if((MACDBuffer[i-1]<SignalBuffer[i-1] && MACDBuffer[i]>SignalBuffer[i]) || (MACDBuffer[i-1]>SignalBuffer[i-1] && MACDBuffer[i]<SignalBuffer[i]) ||
      (MACDBuffer[i-1]<0.0 && MACDBuffer[i]>0.0) || (MACDBuffer[i-1]>0.0 && MACDBuffer[i]<0.0))
     {
      if(m_repetitions>=InpSoundRepetitions)
         return(rates_total);
      //---
      datetime time_current=TimeCurrent();
      if(time_current-m_last_sound>InpSoundPause)
        {
         //--- Main AND Signal
         if(InpMain_and_Signal)
           {
            if(MACDBuffer[i-1]<SignalBuffer[i-1] && MACDBuffer[i]>SignalBuffer[i])
              {
               PlaySound(InpSoundName);
               Alert("MACD and Signal Intersection UP, ",TimeToString(time[i]));
               m_last_sound=time_current;
               m_repetitions++;
               return(rates_total);
              }
            if(MACDBuffer[i-1]>SignalBuffer[i-1] && MACDBuffer[i]<SignalBuffer[i])
              {
               PlaySound(InpSoundName);
               Alert("MACD and Signal Intersection DOWN, ",TimeToString(time[i]));
               m_last_sound=time_current;
               m_repetitions++;
               return(rates_total);
              }
           }
         //--- Main AND '0'
         if(InpMain_and_Zero)
           {
            if(MACDBuffer[i-1]<0.0 && MACDBuffer[i]>0.0)
              {
               PlaySound(InpSoundName);
               Alert("MACD and Zero Intersection UP, ",TimeToString(time[i]));
               m_last_sound=time_current;
               m_repetitions++;
               return(rates_total);
              }
            if(MACDBuffer[i-1]>0.0 && MACDBuffer[i]<0.0)
              {
               PlaySound(InpSoundName);
               Alert("MACD and Zero Intersection DOWN, ",TimeToString(time[i]));
               m_last_sound=time_current;
               m_repetitions++;
               return(rates_total);
              }
           }
         //--- Signal AND '0'
         if(InpSignal_and_Zero)
           {
            if(SignalBuffer[i-1]<0.0 && SignalBuffer[i]>0.0)
              {
               PlaySound(InpSoundName);
               Alert("Signal and Zero Intersection UP, ",TimeToString(time[i]));
               m_last_sound=time_current;
               m_repetitions++;
               return(rates_total);
              }
            if(SignalBuffer[i-1]>0.0 && SignalBuffer[i]<0.0)
              {
               PlaySound(InpSoundName);
               Alert("Signal and Zero Intersection DOWN, ",TimeToString(time[i]));
               m_last_sound=time_current;
               m_repetitions++;
               return(rates_total);
              }
           }
        }
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Indicator deinitialization function                              |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
//| Filling indicator buffers from the iMACD indicator               |
//+------------------------------------------------------------------+
bool FillArraysFromBuffers(double &macd_buffer[],    // indicator buffer of MACD values
                           double &signal_buffer[],  // indicator buffer of the signal line of MACD
                           int ind_handle,           // handle of the iMACD indicator
                           int amount                // number of copied values
                          )
  {
//--- reset error code
   ResetLastError();
//--- fill a part of the iMACDBuffer array with values from the indicator buffer that has 0 index
   if(CopyBuffer(ind_handle,0,0,amount,macd_buffer)<0)
     {
      //--- if the copying fails, tell the error code
      PrintFormat("Failed to copy data from the iMACD indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(false);
     }
//--- fill a part of the SignalBuffer array with values from the indicator buffer that has index 1
   if(CopyBuffer(ind_handle,1,0,amount,signal_buffer)<0)
     {
      //--- if the copying fails, tell the error code
      PrintFormat("Failed to copy data from the iMACD indicator, error code %d",GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(false);
     }
//--- everything is fine
   return(true);
  }
//
Причина обращения: