В роботе АСК и БИД берутся не те - страница 2

 
Михаил:

Зачем Вы ещё раз берёте

 Если в структуре MqlTick уже есть эти данные?

 А это

 Ни "в какие ворота"!

last - double, ask -double,  а interval - int !!! 

Не используйте для ФОРТС  стандартную библиотеку.

И на ФОРТС лучше использовать стаканы, нежели OnTick() 

 Вот "рыба":

 

 

А где мне получать цену Last в OnBookEvent или в OnTick? И как?
 
Alexander Pavlov:
А где мне получать цену Last в OnBookEvent или в OnTick? И как?
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
{
  if ( symbol == _Symbol )
  {
    if ( PositionSelect( _Symbol ) )
    {
      //---
    }
    else
    {
      double ask, bid;
//---      
      if ( GetStakanValues( _Symbol, ask, bid ) )
      {
        double last = SymbolInfoDouble( _Symbol, SYMBOL_LAST );
      }
    }
  }   
}
 

Что то и в этот раз робот пропускает профит. Может я что то не так делаю? Это что касается брокера на букву Б. У брокера на букву О и без "рыбы" все нормально.

Что делать?

Код:

//+------------------------------------------------------------------+
//|                                                    LastPrice.mq5 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
input double interval=100;  //Мин. отклонение цены сделки
input double Lots=1;   //Лот
input int SlPips=100;   //Stop Loss
input ENUM_ORDER_TYPE_FILLING Filling=ORDER_FILLING_RETURN;  //Режим заполнения ордера
#include <trade/trade.mqh>
int tradeResult=0;
double tradePrice=0,LastPrice=0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   if(!MarketBookAdd(_Symbol))
     {
      MessageBox("Не добавлен стакан по символу "+_Symbol);
      return( INIT_FAILED );
     }
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   MarketBookRelease(_Symbol);
  }
//+------------------------------------------------------------------+
//| Get Stakan values function                                       |
//+------------------------------------------------------------------+ 
bool GetStakanValues(const string aSymbol,double &ask,double &bid)
  {
   MqlBookInfo book_price[];
   bid = 0;
   ask = DBL_MAX;

//--- Get stakan
   if(MarketBookGet(aSymbol,book_price))
     {
      int size=ArraySize(book_price);
      //---    
      if(size>0)
        {
         for(int i=0; i<size; i++)
           {
            if(book_price[i].type==BOOK_TYPE_SELL)
              {
               if(book_price[i].price<ask)
                 {
                  ask=book_price[i].price;
                 }
              }
            else
            if(book_price[i].type==BOOK_TYPE_BUY)
              {
               bid=book_price[i].price;
               return( true );
              }
           }
        }
     }
//---
   if(ask==DBL_MAX) ask=0;
   return( false);
  }
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
  {
   if(symbol==_Symbol)
     {
      double ask,bid;
      //---      
      if(GetStakanValues(_Symbol,ask,bid))
        {
         double last=SymbolInfoDouble(_Symbol,SYMBOL_LAST);

         ///ROBOT++++++++++++++++++++++++++++++++++++++++++++++++
         ///BUY
         if(tradeResult==0)
            if(last>=ask+interval)
              {
               MqlTradeRequest request={0};
               MqlTradeResult result={0};
               double spread = MathAbs(ask-bid);
               request.action=TRADE_ACTION_PENDING;         // setting a pending order
               request.magic=68975;                      // ORDER_MAGIC
               request.symbol=_Symbol;                   // symbol
               request.volume=Lots;                      // volume in 0.1 lots
               request.sl=ask-SlPips;        // Stop Loss is not specified
                                             //request.tp=NormalizeDouble(ask + TpPips * gTickSize, _Digits);        // Take Profit is not specified     
               request.type=ORDER_TYPE_BUY_LIMIT;              // order type
               request.price=ask;                        // open price
               request.type_filling=Filling;
               request.deviation=0;
               request.type_time=ORDER_TIME_DAY;
               request.expiration=0;
               //--- send a trade request
               int i=PositionsTotal();//Wait openedPosition 
               tradePrice=ask;
               if(OrderSend(request,result))
                 {
                  while(i==PositionsTotal())//Wait openedPosition
                    {
                     GetStakanValues(_Symbol,ask,bid);//Close freezy order
                     if(ask!=tradePrice)
                       {
                        CTrade trade;
                        trade.SetTypeFilling(Filling);
                        trade.OrderDelete(OrderGetTicket(0));
                        if(OrdersTotal()==0) break;
                       }
                    }
                  if(PositionSelect(_Symbol)) tradeResult=1;
                  LastPrice=last;
                 }
              }
         ///
         ///SELL
         if(tradeResult==0)
            if(last<=bid-interval)
              {
               MqlTradeRequest request={0};
               MqlTradeResult result={0};
               request.action=TRADE_ACTION_PENDING;         // setting a pending order
               request.magic=68975;                      // ORDER_MAGIC
               request.symbol=_Symbol;                   // symbol
               request.volume=Lots;                      // volume in 0.1 lots
               request.sl=bid+SlPips;        // Stop Loss is not specified
                                             //request.tp=NormalizeDouble(bid - TpPips * gTickSize, _Digits);        // Take Profit is not specified     
               request.type=ORDER_TYPE_SELL_LIMIT;             // order type
               request.price=bid;                        // open price
               request.type_filling=Filling;
               request.deviation=0;
               request.type_time=ORDER_TIME_DAY;
               request.expiration=0;            //--- send a trade request
               int i=PositionsTotal();//Wait openedPosition
               tradePrice=bid;
               if(OrderSend(request,result))
                 {
                  while(i==PositionsTotal())//Wait openedPosition
                    {
                     GetStakanValues(_Symbol,ask,bid);//Close freezy order
                     if(bid!=tradePrice)
                       {
                        CTrade trade;
                        trade.SetTypeFilling(Filling);
                        trade.OrderDelete(OrderGetTicket(0));
                       }
                     if(OrdersTotal()==0) break;
                    }
                  if(PositionSelect(_Symbol)) tradeResult=2;
                  LastPrice=last;
                 }
              }
         ///ClosePosition
         if(tradeResult==2) ///if SELL position
            if(((LastPrice>=ask || LastPrice>=bid) && (tradePrice>=ask)) || (tradePrice>ask))
              {
               CTrade trade;
               trade.SetTypeFilling(Filling);
               int i=PositionsTotal()-1;
               while(i>=0)
                 {
                  if(trade.PositionClose(_Symbol)) i--;
                 }
               tradeResult=0;
              }

         if(tradeResult==1) ///if BUY position
            if(((LastPrice<=bid || LastPrice<=ask) && (tradePrice<=bid)) || (tradePrice<bid))
              {
               CTrade trade;
               trade.SetTypeFilling(Filling);
               int i=PositionsTotal()-1;
               while(i>=0)
                 {
                  if(trade.PositionClose(_Symbol)) i--;
                 }
               tradeResult=0;
              }
         ///
         ///PositionSL
         if(tradeResult!=0)
            if(!PositionSelect(_Symbol))
               tradeResult=0;
         ///

         ///ROBOT++++++++++++++++++++++++++++++++++++++++++++++++

        }
     }
  }
//+------------------------------------------------------------------+
 

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

библиотеку. 

2. Нужно использовать PositionSelect()

Зачем спрашивать, если Вы игнорируете советы? 

И ещё...

Интервал Вы указываете не правильно, потому что это абсолютная величина,

никак не привязанная к цене тика.

Поэтому рекомендую само значение указывать в пунктах (long), а когда

сравниваете использовать эту функцию:

 

//+------------------------------------------------------------------+
//| Expert Points to price function                                  |
//+------------------------------------------------------------------+
double PointsToPrice( const long a_points )
{
  double step_price = SymbolInfoDouble( _Symbol, SYMBOL_TRADE_TICK_SIZE );
  double a_price = ( double( a_points ) * _Point ) / step_price;
  
  if ( a_points < 0 )
  {
    a_price = MathFloor( a_price ) * step_price;
  }
  else
  {
    a_price = MathCeil( a_price ) * step_price;
  }
  
  return( NormalizeDouble( a_price, _Digits ) );
}
 
Михаил:

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

библиотеку. 


 

Что за библиотека? Я и так использую букэвент.

ПС Посмотрите мой предыдущий комментария - там я представил исправленный код. 

 
Alexander Pavlov:

Что за библиотека? Я и так использую букэвент.

ПС Посмотрите мой предыдущий комментария - там я представил исправленный код. 

#include <trade/trade.mqh>
 

У Вас очень простой советник.

Гораздо разумнее использовать так:

if ( PositionSelect( _Symbol ) )
{
  // Позиция открыта
}
else
{
  // Нет позиции
}
 

Вот Вам в помощь, а дальше сами:

//+------------------------------------------------------------------+
//|                                                    LastPrice.mq5 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
input long Interval = 100; //Мин. отклонение цены сделки(пункты)
input long Lots     = 1;   //Лот
input long SlPips = 100;   //Stop Loss(пункты)
input ENUM_ORDER_TYPE_FILLING Filling = ORDER_FILLING_RETURN;  //Режим заполнения ордера
//
double tradePrice = 0;
double LastPrice = 0;
double interval;
double pips;
//
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  interval = PointsToPrice( Interval ); //Из пунктов в цену символa
pips = PointsToPrice( SlPips );
//---  
  if( !MarketBookAdd( _Symbol ) )
  {
    MessageBox("Не добавлен стакан по символу "+_Symbol);
    return( INIT_FAILED );
  }
  return( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
  MarketBookRelease(_Symbol);
}
//+------------------------------------------------------------------+
//| Get Stakan values function                                       |
//+------------------------------------------------------------------+ 
bool GetStakanValues(const string aSymbol,double &ask,double &bid)
{
  MqlBookInfo book_price[];
  bid = 0;
  ask = DBL_MAX;
//--- Get stakan
  if ( MarketBookGet( aSymbol, book_price ) )
  {
    int size = ArraySize( book_price );
//---    
    if ( size > 0 )
    {
      for ( int i = 0; i < size; i++ )
      {
        if ( book_price[i].type == BOOK_TYPE_SELL )
        {
          if ( book_price[i].price < ask )
          {
            ask = book_price[i].price;
          }
        }
        else
        if ( book_price[i].type == BOOK_TYPE_BUY )
        {
          bid = book_price[i].price;
          return( true );
        }
      }
    }
  }
  return( false);
}
//+------------------------------------------------------------------+
//| BookEvent function                                               |
//+------------------------------------------------------------------+
void OnBookEvent( const string &symbol )
{
  if( symbol == _Symbol )
  {
    double ask, bid, last, price = 0;
//---            
    if ( GetStakanValues( _Symbol, ask, bid ) )  //Берём здесь, потому что нужно как и для открытия позиции, так и для закрытия
    {
      last = SymbolInfoDouble( _Symbol, SYMBOL_LAST );
//---      
      if ( PositionSelect( _Symbol ) )
      {
        if ( ENUM_POSITION_TYPE( PositionGetInteger( POSITION_TYPE ) ) == POSITION_TYPE_BUY )
        {
          //--- Проверка закрытия, если да то
          if ( SetOrder( price, false ) ) 
          {
            //---
          }
        }
        else
        {
          //---Проверка закрытия, если да то
          if ( SetOrder( price, true ) ) 
          {
            //---
          } 
        }
      }
      else
      {
        //Делаем проверки какой ордер установить (BUY or SELL ) и берём цену
        //Устанавливаем ордер 
        if ( SetOrder( price, true ) ) // true ордер на покупку; false - ордер на продажу
        {
          /////Ордер установлен
        }
      } 
    }
  }
}
//+------------------------------------------------------------------+
//| Set order function                                               |
//+------------------------------------------------------------------+  
bool SetOrder( const double price, const bool buy_sell )
{
  MqlTradeRequest request = {0};
  MqlTradeResult result = {0};
  
//--- Fill structure
  request.action = TRADE_ACTION_PENDING;         // setting a pending order
  request.magic = 68975;                      // ORDER_MAGIC
  request.symbol = _Symbol;                   // symbol
  request.volume = double( Lots );            
//---   
  if ( buy_sell )
  {
    request.type = ORDER_TYPE_BUY_LIMIT;              // order type
    request.sl = price - pips;
  }
  else
  {
    request.type = ORDER_TYPE_SELL_LIMIT;
    request.sl = price + pips;
  }  
  request.price = price;                        // open price
  request.type_filling = Filling;
  request.type_time = ORDER_TIME_DAY;
//---
  if ( OrderSend( request, result ) )
  {
    if ( ( result.retcode == TRADE_RETCODE_PLACED ) && ( result.order > 0 ) )
    {
      return( true );
    }
  }
  else
  {
    Print( " Order not set!");
  }
  return( false );  
}  
//+------------------------------------------------------------------+
//| Expert Points to price function                                  |
//+------------------------------------------------------------------+
double PointsToPrice( const long a_points )
{
  double step_price = SymbolInfoDouble( _Symbol, SYMBOL_TRADE_TICK_SIZE );
  double a_price = ( double( a_points ) * _Point ) / step_price;
  
  if ( a_points < 0 )
  {
    a_price = MathFloor( a_price ) * step_price;
  }
  else
  {
    a_price = MathCeil( a_price ) * step_price;
  }
  
  return( NormalizeDouble( a_price, _Digits ) );
}
//+------------------------------------------------------------------+
 

Помните, что установив ОТЛОЖЕННЫЙ ордерORDER_FILLING_RETURN )

У Вас может быть и действующий ордер и открытая позиция. 

Для проверки существования ордера, вам понадобится его тикет (result.order)

if ( OrderSelect( ticket ) )
{
  // Ордер рабочий
}
 

А вообще, если честно (не обижайтесь) Вы пишите обыкновенный сливатор.

Почитайте про арбитражные стратегии, парный трейдинг и т.п

На это уйдёт много времени (пока разберётесь), но зато будете ЗАРАБАТЫВАТЬ. 

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