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

 
Ihor Herasko:

Такой метод начисления свопа называют ролловер (roll over). В МТ4 о нем невозможно узнать программно. Только косвенно после того, как произошел переход через полночь с рабочими рыночными ордерами. Таких вот мелких, но достаточно неприятных проблем в МТ4 множество. В МТ5 чуть меньше, но все равно имеются.

Это величины свопа в пунктах. Их нужно преобразовать в валюту депозита, исходя из объема рыночного ордера. Тогда будет получен реальный размер свопа.

"В МТ4 о нем невозможно узнать программно." - спасибо за уделенное время, за ответы. 

 

Добрый день! Дорогие форумчане прошу помочь разобраться с алгоритмом. Задача определять в указанный промежуток времени ценовой диапазон и на максимум и минимум ставить байстоп и селлстоп. Стоплосы устанавливается на противоположные ордера тейкпрофит должен быть равен стоплосс*2.

Далее после каждого закрытия по стоплоссу ордер восстанавливается с теми же стоплосами и тейкпрофитами как у закрывшегося, весь цикл заканчивается после закрытия по тейкпрофиту одного из ордеров. И все с начала определяем диапазон и поехали.

Но что-то сейчас он просто не ставит ТП точнее ставит, но на цену открытия и стоплосс не с размер диапазона т.е. не на противоположно направленном  ордере. Заранее благодарю за помощь.

static int prevtime = 0;
int MagicNumber = 12345678;
input int stoploss = 40;
input int takeprofit = 50;
input int padding = 5;
int a=1;
input string startTime = "14:35";
input string endTime = "18:35";
int expertBars;
double max, min;
bool isEndTime = true;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   //sendOrders();
   
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
#include <expert.mq4>
 
int start()
{  
    //Возвращает максимум и минимум за промежуток
    if(isTime()) getMaxMin();
    
    // всё, что задается ниже - будет работать по "ценам открытия"
    //нового бара, т.е. будет срабатывать в момент его появления
    //на том графике, на кот. стоит советник
    CheckEvents( MagicNumber );
    if ( eventBuyClosed_SL > 0 ) {
        Alert( _Symbol, OrderClosePrice(), ": Buy-позиция закрыта по СтопЛоссу!" );
        double minstoplevel=MarketInfo(Symbol(),MODE_STOPLEVEL);
        Alert("Минимальный стоп левел: ", minstoplevel);
        OrderSend(_Symbol,OP_BUYSTOP,OrderLots(),OrderOpenPrice(),3,OrderStopLoss(),OrderTakeProfit(),"My order",MagicNumber,0,clrGreen);
    }
    
    if ( eventBuyClosed_TP > 0 ) {
        Alert( _Symbol, OrderClosePrice(), ": Buy-позиция закрыта по ТейкПрофиту!" );
        deleteAllPaddingOrders();
    }
    
    if ( eventSellClosed_SL > 0 ) {
        Alert( _Symbol, OrderClosePrice(), ": Sell-позиция закрыта по СтопЛоссу!" );
        double minstoplevel=MarketInfo(Symbol(),MODE_STOPLEVEL);
        Alert("Минимальный стоп левел: ", minstoplevel);
        OrderSend(_Symbol,OP_SELLSTOP,OrderLots(),OrderOpenPrice(),3,OrderStopLoss(),OrderTakeProfit(),"My order",MagicNumber,0,clrRed);
    }
    
    if ( eventSellClosed_TP > 0 ) {
        Alert( _Symbol, OrderClosePrice(), ": Sell-позиция закрыта по ТейкПрофиту!" );
        deleteAllPaddingOrders();
    }
    
    if ( eventBuyLimitOpened > 0 || eventBuyStopOpened > 0 || 
          eventSellLimitOpened > 0 || eventSellStopOpened > 0 )
        Alert( _Symbol, OrderType(), ": сработал отложенный ордер!" );
return(0);
}
//-----------------------------------------------------------------+
void deleteAllPaddingOrders() {
  int total = OrdersTotal();
  for(int i=total-1;i>=0;i--)
  {
    OrderSelect(i, SELECT_BY_POS);
    int type   = OrderType();
    if (OrderMagicNumber() != MagicNumber) continue;
    if (OrderSymbol() != _Symbol) continue;
    bool result = false;
    
    switch(type)
    {
      //Close opened long positions
      case OP_BUY       : result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red );
                          break;
      
      //Close opened short positions
      case OP_SELL      : result = OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red );
      //                    break;

      //Close pending orders
      //case OP_BUYLIMIT  :
      //case OP_SELLLIMIT :
      case OP_BUYSTOP   :
      case OP_SELLSTOP  : result = OrderDelete( OrderTicket() );
    }
    
    if(result == false)
    {
      Alert("Order " , OrderTicket() , " failed to close. Error:" , GetLastError() );
      Sleep(3000);
    }
    return;
  }
  
  return;
}
void sendOrders(bool isFirst) {
   //--- получим минимальное значение Stop level
   double minstoplevel=MarketInfo(Symbol(),MODE_STOPLEVEL);
   Print("Minimum Stop Level=",minstoplevel," points");
   //--- BUYSTOP
   //--- вычисленные значения цен SL и TP должны быть нормализованы
   //--- размещаем рыночный ордер на покупку 1 лота
   int ticketBuyStop, ticketSellStop;
   if(!isFirst) {
      ticketBuyStop=OrderSend(Symbol(),OP_BUYSTOP,1,Ask + padding * Point,20,Bid -padding*Point,Ask + padding * Point,"My order",MagicNumber,0,clrGreen);
      ticketSellStop=OrderSend(Symbol(),OP_SELLSTOP,1,Bid - padding * Point,20,Ask + padding*Point,Bid - padding * Point,"My order",MagicNumber,0,clrRed);
   } else { 
      ticketBuyStop=OrderSend(Symbol(),OP_BUYSTOP,1,max + padding * Point,20,min -padding*Point,max + (max - min + padding) * Point,"My order",MagicNumber,0,clrGreen);
      ticketSellStop=OrderSend(Symbol(),OP_SELLSTOP,1,min - padding * Point,20,max + padding*Point,min - (max - min  + padding)*Point,"My order",MagicNumber,0,clrRed);
   }
   if(ticketBuyStop<0)
     {
     Print("OrderSend завершилась с ошибкой #",GetLastError());
      
         deleteAllPaddingOrders();
         if(a <=5) {
         //sendOrders(isFirst);
         a= a+1;
      }
     }
   else
      Print("Функция OrderSend успешно выполнена");
   //---BUYSTOP
   
   //---SELLSTOP
   //--- вычисленные значения цен SL и TP должны быть нормализованы
   //--- размещаем рыночный ордер на покупку 1 лота
   
   if(ticketSellStop<0)
     {
      
         deleteAllPaddingOrders();
         if(a <= 5) {
            //sendOrders();
            a= a+1;
            Print("a", a);
         }
         Print("OrderSend завершилась с ошибкой #",GetLastError());
       
     }
   else
      Print("Функция OrderSend успешно выполнена");
   //---SELLSTOP
   return;
}
bool getMaxMin() {
   int startIndex = iBarShift(_Symbol, 0, StrToTime(startTime), true);
   min=iLow(NULL,0,iLowest(NULL,0,MODE_LOW,startIndex,0));
   max=iHigh(NULL,0,iHighest(NULL,0,MODE_HIGH,startIndex,0));
   Alert("Min: ", min);
   Alert("Max: ", max);
   sendOrders(true);
   return true;
}

//===============================================================================+
//======| возвращает true если временной диапозон кончился                       |
//===============================================================================+
bool isTime() {
   if (TimeHour(StrToTime(startTime)) == Hour() && TimeMinute(StrToTime(startTime)) == Minute() && isEndTime) { Alert("Start Timeline"); isEndTime = false; deleteAllPaddingOrders();};
   if(TimeHour(StrToTime(endTime)) == Hour() && TimeMinute(StrToTime(endTime)) <= Minute() && !isEndTime) { Alert("End Timeline"); isEndTime = true; return true;};
   return false;
}

//=====================================================================+
//======| возвращает true если появился новый бар, иначе false |
//=====================================================================+
//bool isNewBar()
//{
//bool res=false;
//if(expertBars!=iBars(Symbol(),0))
//{
//expertBars=iBars( Symbol (),0);
//res=true;
//}
//return(res);
//}
 
Sobbaka:

Не нужно дублировать вопросы в разных ветках

 

Добрый день!

При тестировании в журнале выдается ошибка OrderSend error 130 - она если я правильно понял может быть связана только со стопами или тэйками, посмотрите пожалуйста, что не так:

#define MagicNumber1 100            //Buy
input double MaximumRisk=0.03;      //Max риск в сделке
input double K=1;                   //Коэффициент риск к прибыли
input int OrderPoint=30;            //Расстояние до отложенного ордера
double Price=0;                     //Цена для установки отложенного ордера
double SL=0;                        //Stop Loss
double TP=0;                        //Take Profit
double Lots=0;                      //Просчет лотности исходя из max риска одной сделки


void OnTick()
{
//Параметры для открытия ордера                   
Price = NormalizeDouble(High[1]+OrderPoint*Point,Digits); //Цена открытия ордера
SL = NormalizeDouble(Low[1]-Point,Digits); //Стоп лосс
if ((Price-SL)<NormalizeDouble(MarketInfo(Symbol(),MODE_STOPLEVEL)*Point,Digits))
{SL=Price-NormalizeDouble(MarketInfo(Symbol(),MODE_STOPLEVEL)*Point,Digits);}
TP = NormalizeDouble((Price-SL)*K+Price,Digits); //Тэйк профит
//Просчет лотности исходя из риска в сделке
Lots = NormalizeDouble(((AccountBalance()*MaximumRisk/100.0)/((Price-SL)*1000.0)),1);

//Установка отложенного ордера
bool send1=OrderSend(Symbol(),OP_BUYSTOP,Lots,Price,3,SL,TP,"comment",MagicNumber1,0,clrGreen);
}
 
YanSay:

Добрый день!

При тестировании в журнале выдается ошибка OrderSend error 130 - она если я правильно понял может быть связана только со стопами или тэйками,

Цены открытия отложенных ордеров тоже касается. Поэтому нужно проверять еще и расстояние между текущей рыночной ценой и ценой открытия ордера. В данном случае: Price - Ask.

 
Ihor Herasko:

Цены открытия отложенных ордеров тоже касается. Поэтому нужно проверять еще и расстояние между текущей рыночной ценой и ценой открытия ордера. В данном случае: Price - Ask.

Благодарю!
 
Artyom Trishkin:
Что возвращает функция Hour() ?

Возвращает текущий час. я и работаю: если текущий час больше 11 и меньше 17,

if(Hour()>=17&&Hour()<=11)continue;

а как надо?

 
Tigerfreerun:

Сложновато для меня. Вы могли бы объяснить в какую именно часть кода добавить и что значит это mn и mag_n?   куда мне тут свой меджик советника вписать?

Перед своим условием ставьте 

if(Hour()>=0&&Hour()<=8&&!OP_TO(mag_n))step = 5; else step =10;

mag_n - сюда меджик советника вписать.

 
PolarSeaman:

Возвращает текущий час. я и пишу: если текущий час больше 11 и меньше 17, а как надо?

Я так понял, вопрос по индикатору. Вместо Hour() -> time[i]

 
Vitaly Muzichenko:

Я так понял, вопрос по индикатору. Вместо Hour() -> time[i]

Да, это вы помогали, теперь хочу время ограничить. Исключить подсчёт с 17 до 11 часов.

  for(int i=limit-2; i>0; i--) 
     {
     if(Hour()>=17&&Hour()<=11)continue;
      if(i%2==0) 
        {
         if(open[i]<close[i] && open[i+1]>close[i+1]) 
           {
            k1++;
           // if(k1>max) {max=k1; dat_max=time[i];}
            if(k1>=4)Print("Num: ",k1,"dat_max ",time[i]);
            SetText("Obj_"+(string)time[i],(string)k1,time[i],high[i],Arr);
           }
         else k1=0;
         
           } else {
         if(open[i]<close[i] && open[i+1]>close[i+1]) 
           {
            k2++;
            //if(k2>max){ max=k2; dat_max=time[i];}
            if(k2>=4)Print("Num: ",k2,"dat_max ",time[i]);
            SetText("Obj_"+(string)time[i],(string)k2,time[i],high[i],Arr);
           }
         else k2=0;
         
        }
      
     }
Причина обращения: