Creación de un robot - página 4

 
Sí, escribí, escribí, lo pensé, no lo dije con precisión. Siempre me cuesta articular mis pensamientos. En el décimo cambio, las palabras parecen tener sentido
 
Роман Жилин:

Oooh, muchas gracias, con tanta información se pueden hacer muchas cosas...

Estoy a punto de salir de viaje de negocios, así que estoy pensando en profundizar en los materiales que me han dado, pero la codificación... También podría hacerlo en una hoja de papel, sería una buena herramienta de entrenamiento...


Saludos, Roman

Esto es una pequeña fracción de lo que necesitas saber, un grano de arena en el mar del código del programa. Pero no basta con saber qué usar, dónde usarlo y cuándo usarlo.

Si se procede a partir del nombre del tema"Creación de Robots", entonces usted necesita tener una estrategia de comercio de equilibrio (rentable, o como quiera llamarlo), y sólo entonces estudiar el lenguaje de programación MQL5.

Por cierto, el MetaEditor del terminal MT5 tiene el MQL5 Wizard, con la ayuda del cual se puede obtener fácilmente el código del Asesor Experto ya hecho, utilizando los módulos de señales de comercio, que a su vez fueron creados sobre la base de los indicadores populares, sin ningún conocimiento del lenguaje de programación. Con la ayuda del Asistente MQL5, puede construir rápidamente un Asesor Experto y probar su estrategia, si se basa sólo en indicadores. Aquí está el enlace al artículo sobre la construcción de un robot de comercio utilizando MQL5 Wizard: https://www.mql5.com/ru/articles/171.

Sinceramente, Vladimir.

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

57 y pico. Y la respuesta a tu pregunta sobre el camino ya se conoce, y cito:

"Roman Zhilin ":

No, no hay ningún proceso en el trabajo autónomo, que puedas desarrollar por tu cuenta según tus necesidades. Y el único culpable de mis errores seré yo mismo, no un programador ajeno. Así que tendrás que aprender, aprender, codificar, tropezar, mejorar tus estrategias y volver a aprender".

Sinceramente, Vladimir.

Una buena selección, gracias.

Me recuerda al testamento de Lenin :) Pero tiene razón, nunca es tarde para aprender.

Para entender qué tipo de Asesor Experto necesita, debe empezar a trabajar en él en primer lugar.

 

Se han añadido dos botones más para cerrar una posición

//+------------------------------------------------------------------+
//|                                                         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);
  }
//+------------------------------------------------------------------+
Archivos adjuntos:
0002.mq5  11 kb
 
MrBrooklin:

... Sigo sin entender el significado de la frase constante que comienza con la palabra"Retornos".

¿Quién vuelve, a quién vuelve, dónde vuelve, por qué vuelve? Todavía no puedo entenderlo...

Tal vez pueda explicarlo.

Supongamos que tiene un símbolo (símbolo, por ejemplo, EUR/USD) que está oscilando en la pantalla y un programa/asesor/robot se está ejecutando en el terminal. El robot está ejecutando el código que has introducido en él. Y este código tiene estas cadenas:

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

           double OpenPrice = OrderOpenPrice(); 

	   ...
"orderSelect" es una función comercial, selecciona una orden ya abierta para seguir trabajando con ella.
//En este ejemplo, si la selección de la orden falla (...==false), la ejecución posterior de la función " if " se interrumpe con el comando "break".

Siguiente. Hemos seleccionado la orden mediante la función comercial OrderSelect. Ahora trabajamos con él, con un orden específico. Para simplificar, tomaremos la condición de que sólo tenemos dos órdenes abiertas.

A continuación, introducimos una variable OpenPrice [tipo double] y le asignamos el valor del precio al que se abrió la orden que hemos seleccionado (sección de código OpenPrice=OrderOpenPrice(); )

AQUÍ te explicamos qué significa el RETORNO de un parámetro. La función OrderOpenPrice devuelve el valor del precio actual del instrumento. Es decir, después de que el programa pidiera el precio actual al servidor, le devolvía el valor de ese precio y asignaba ese valor a una variable.

 

Indicador MACD agregado

 //+------------------------------------------------------------------+
//|                                                         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);
  }
//+------------------------------------------------------------------+
Archivos adjuntos:
0003.PNG  107 kb
0003.mq5  15 kb
 
SanAlex:

Añadido el indicador MACD

Los fundamentos están ahí, ahora todo depende de ti

 
4elovechishe:

Quizá pueda explicarlo.

Digamos que actualmente tiene un símbolo (por ejemplo, EUR/USD) fluctuando en su pantalla y un programa/asesor/robot ejecutándose en su terminal. El robot está ejecutando el código que has introducido en él. Y este código tiene estas cadenas:

"orderSelect" es una función comercial, selecciona una orden ya abierta para seguir trabajando con ella.
//En este ejemplo, si la selección de la orden falla (...==false), la ejecución posterior de la función " if " se interrumpe con el comando "break".

Siguiente. Hemos seleccionado la orden mediante la función comercial OrderSelect. Ahora trabajamos con él, con un orden específico. Para simplificar, tomaremos la condición de que sólo tenemos dos órdenes abiertas.

A continuación, introducimos una variable OpenPrice [tipo double] y le asignamos el valor del precio al que se abrió la orden que hemos seleccionado (sección de código OpenPrice=OrderOpenPrice(); )

AQUÍ te explicamos qué significa el RETORNO de un parámetro. La función OrderOpenPrice devuelve el valor del precio actual del instrumento. Es decir, después de que el programa haya solicitado el precio actual al servidor, le ha devuelto el valor de ese precio y ha asignado ese valor a una variable.

Gracias por su aclaración. Espero que también ayude a Roman a dominar el lenguaje de programación.

Saludos, Vladimir.

 

¡Hola! Bueno, tal vez alguien pueda ayudarme...

Actualmente estoy tratando con mecanismos de apertura/cierre de órdenes y me he encontrado con un problema al cerrar posiciones abiertas.

El código es sencillo. La idea del algoritmo es dibujar la MA (media móvil) con un periodo de 100 en el gráfico. Si la vela anterior [1] abrió por encima de la MA, y cerró por debajo de la MA, entonces la siguiente vela [0] abre una ordende VENTApara vender.

//(Las condiciones para comprar se invierten, no las explico)

Para el cierre de la orden las siguientes condiciones - el precio actual ha pasado del precio de apertura de la orden el valor establecido de puntos, por ejemplo 40.

Ejemplo: Un lote se abre a Bid= 1,20045, debería cerrar a Ask= 1,20005.

El código de apertura y cierre está empaquetado en 2 funciones correspondientes que a su vez son llamadas con la función OnTick(). De hecho, con cada tick se debería comprobar la condición de cierre, pero de hecho el precio puede caer por debajo del nivel especificado (nivel de cierre) pero la orden no se cerrará. Se adjuntan capturas de pantalla y código.

 
4elovechishe:

¡Hola! Bueno, tal vez alguien pueda ayudarme también...

Actualmente estoy tratando con mecanismos de apertura/cierre de órdenes y me he encontrado con un problema al cerrar posiciones abiertas.

El código es sencillo. La idea del algoritmo es dibujar la MA (media móvil) con un periodo de 100 en el gráfico. Si la vela anterior [1] abrió por encima de la MA, y cerró por debajo de la MA, entonces la siguiente vela [0] abre una ordende VENTApara vender.

//(Las condiciones para comprar se invierten. No las explico)

Para el cierre de la orden las siguientes condiciones - el precio actual ha pasado del precio de apertura de la orden el valor establecido de puntos, por ejemplo 40.

Ejemplo: Un lote se abre a Bid= 1,20045, debería cerrar a Ask= 1,20005.

El código de apertura y cierre está empaquetado en 2 funciones correspondientes que a su vez son llamadas con la función OnTick(). De hecho, con cada tick se debería comprobar la condición de cierre, pero en realidad el precio puede caer por debajo del nivel especificado (nivel de cierre) pero la orden no se cerrará. Adjunto las capturas de pantalla y el código.

Hay un hilo del foro en https://www.mql5.com/ru/forum/160683/page767#comment_10725713

Puede que allí consigas ayuda más rápido.

Sinceramente, Vladimir.

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