Criando um robô - página 4

 
Sim, eu fiz, eu fiz, eu pensei sobre isso, eu não disse com precisão. Sempre tenho dificuldade de articular meus pensamentos. Na décima mudança, as palavras parecem fazer sentido
 
Роман Жилин:

Oooh, muito obrigado, com tanta informação você pode conseguir fazer tanta coisa...

Estou prestes a partir em uma viagem de negócios, então estou pensando em ir mais fundo nos materiais que me foram dados, mas a codificação... Eu também poderia fazê-lo em uma folha de papel, seria uma boa ferramenta de treinamento...


Cumprimentos, romano

Esta é uma pequena fração do que você precisa saber, um grão de areia no mar do código do programa. Mas não basta saber o que usar, onde usar e quando usar!

Se procedendo do nome do assunto"Criação de Robôs", então você precisa ter uma estratégia comercial de break-even (lucrativa, ou como você quiser chamá-la), e só então estudar a linguagem de programação MQL5.

A propósito, o MetaEditor do terminal MT5 possui o MQL5 Wizard, com a ajuda do qual você pode facilmente obter o código do Expert Advisor pronto usando os módulos de sinais comerciais, que por sua vez foram criados com base em indicadores populares, sem qualquer conhecimento da linguagem de programação. Com a ajuda do MQL5 Wizard, você pode construir rapidamente um Expert Advisor e testar sua estratégia, se ela for baseada apenas em indicadores. Aqui está o link para o artigo sobre a construção de um robô comercial usando o MQL5 Wizard: https://www.mql5.com/ru/articles/171.

Atenciosamente, Vladimir.

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

57 e um pouco. E a resposta à sua pergunta sobre a forma como já é conhecida, e passo a citar:

"Roman Zhilin ":

Não, não há nenhum processo em freelancing, que você pode desenvolver por conta própria, conforme sua necessidade. E o único culpado pelos meus erros será eu mesmo, não um programador de terceiros. Portanto, você terá que aprender, aprender, codificar, tropeçar, melhorar suas estratégias e aprender novamente".

Atenciosamente, Vladimir.

Uma boa seleção, obrigado.

Faz-me lembrar a vontade de Lênin :) Mas é certo, nunca é tarde demais para aprender.

A fim de entender que tipo de Expert Advisor você precisa, você deve começar a trabalhar nisso em primeiro lugar.

 

Acrescentei mais dois botões para fechar uma posição

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

... Eu ainda não entendo o significado da frase constante que começa com a palavra"Retorna".

Quem retorna, a quem retorna, para onde retorna, por que retorna? Eu ainda não consigo entender...

Talvez eu possa explicar.

Suponha que você tenha um símbolo (símbolo, por exemplo, EUR/USD) que esteja oscilando na tela e um programa/conselheiro/robô esteja rodando no terminal. O robô está executando o código que você preencheu nele. E este código tem estas cordas:

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

           double OpenPrice = OrderOpenPrice(); 

	   ...
A "orderSelect" é uma função comercial, ela seleciona uma ordem já aberta para continuar trabalhando com ela.
// Neste exemplo, se a seleção da ordem falhar (...==falso), a execução da função " se " é interrompida pelo comando "break".

A seguir. Selecionamos o pedido usando a função OrderSelect trade. Agora trabalhamos com ele, com uma ordem específica. Para simplificar, aceitaremos a condição de ter apenas dois pedidos em aberto.

Em seguida, inserimos uma variável OpenPrice [tipo duplo] e atribuímos a ela o valor do preço ao qual a ordem que selecionamos foi aberta (seção de código OpenPrice=OrderOpenPrice(); )

AQUI está uma explicação para você sobre o que significa o VOLTAMENTO de um parâmetro. A função OrderOpenPrice retorna o valor do preço atual do instrumento. Ou seja, depois que o programa solicitou o preço atual ao servidor, ele devolveu o valor desse preço a você e atribuiu esse valor a uma variável.

 

Indicador MACD adicionado

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

Adicionado o indicador MACD

O básico está aí - agora tudo depende de você

 
4elovechishe:

Talvez eu seja capaz de explicar.

Digamos que você tenha atualmente um símbolo (por exemplo, EUR/USD) flutuando em sua tela e um programa/conselheiro/robô rodando no terminal. O robô está executando o código que você preencheu nele. E este código tem estas cordas:

A "orderSelect" é uma função comercial, ela seleciona uma ordem já aberta para continuar trabalhando com ela.
// Neste exemplo, se a seleção da ordem falhar (...==falso), a execução da função " se " é interrompida pelo comando "break".

A seguir. Selecionamos o pedido usando a função OrderSelect trade. Agora trabalhamos com ele, com uma ordem específica. Para simplificar, aceitaremos a condição de ter apenas dois pedidos em aberto.

Em seguida, inserimos uma variável OpenPrice [tipo duplo] e atribuímos a ela o valor do preço ao qual a ordem que selecionamos foi aberta (seção de código OpenPrice=OrderOpenPrice(); )

AQUI está uma explicação para você sobre o que significa o VOLTAMENTO de um parâmetro. A função OrderOpenPrice retorna o valor do preço atual do instrumento. Ou seja, após o programa ter solicitado o preço atual ao servidor, ele devolveu o valor desse preço a você e atribuiu esse valor a uma variável.

Obrigado por seus esclarecimentos. Espero que ela também ajude o romano a dominar a linguagem de programação.

Cumprimentos, Vladimir.

 

Olá! Bem, talvez alguém possa me ajudar também...

Atualmente lidando com mecanismos de abertura/fechamento de pedidos e encontraram um problema com o fechamento de posições abertas.

O código é simples. A idéia do algoritmo é desenhar o MA (média móvel) com um período de 100 no gráfico. Se a vela anterior [1] abriu acima do MA, e fechou abaixo do MA, então a vela seguinte [0] abre uma ordem de vendapara vender.

//(As condições para comprar são invertidas. Não estou explicando)

Para o fechamento do pedido as seguintes condições - o preço atual passou do preço de abertura do pedido o valor estabelecido de pontos, por exemplo 40.

Exemplo: Um lote é aberto em Bid= 1.20045, ele deve fechar em Ask= 1.20005.

O código de abertura e fechamento é embalado em 2 funções correspondentes que, por sua vez, são chamadas com a função OnTick(). De fato, a cada tique a condição de fechamento deve ser verificada, mas na verdade o preço pode cair abaixo do nível especificado (nível de fechamento), mas o pedido não fechará. Telas e códigos são anexados.

 
4elovechishe:

Olá! Bem, talvez alguém possa me ajudar também...

Atualmente lidando com mecanismos de abertura/fechamento de pedidos e encontraram um problema com o fechamento de posições abertas.

O código é simples. A idéia do algoritmo é desenhar o MA (média móvel) com um período de 100 no gráfico. Se a vela anterior [1] abriu acima do MA, e fechou abaixo do MA, então a vela seguinte [0] abre uma ordem de vendapara vender.

//(As condições para comprar são invertidas. Não estou explicando)

Para o fechamento do pedido as seguintes condições - o preço atual passou do preço de abertura do pedido o valor estabelecido de pontos, por exemplo 40.

Exemplo: Um lote é aberto em Bid= 1.20045, ele deve fechar em Ask= 1.20005.

O código de abertura e fechamento é embalado em 2 funções correspondentes que, por sua vez, são chamadas com a função OnTick(). De fato, a cada tique a condição de fechamento deve ser verificada, mas na verdade o preço pode cair abaixo do nível especificado (nível de fechamento), mas o pedido não fechará. Estou anexando os screenshots e o código.

Há um tópico do fórum em https://www.mql5.com/ru/forum/160683/page767#comment_10725713

Você pode conseguir ajuda lá mais rapidamente.

Atenciosamente, Vladimir.

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