« Предыдущий пост | На главную страницу | Следующий пост »

Торговля в ночное время

Что-то все так мне и не получается приступить к рассмотрению способов сортировки глобальных массивов. Сегодня я получил очередное письмо от читателя моего блога с просьбой помочь в реализации ночной торговли на языке MQL4. Данное письмо мне показалось интересным и я написал эксперта, который так интересовал автора письма.

Основная идея эксперта заключается в том, что определенное время (задается параметром StartTime) эксперт выставляет buy limit ордер на BuyLimit_Diff пипсов ниже Bid и sell limit ордер на SellLimit_Diff пипсов выше цены Ask. Дата эксперации ордеров задается в минутах в параметре Expiration. Если один из отложенных ордеров срабатывает, то второй удаляется (т.е. они OCO ордера - One Cancells Other). Stop Loss ордер выставляется на расстоянии BuyLimit_SL и SellLimit_SL пипсов от цены ордера соответственно.

Величина трейлинг стопа задается в параметре TrailingStop.

Исходный код эксперта:

//+-------------------------------------------------------------------------------------------+
//|                                                                Night_Trading.mq4 |
//|                                        Copyright (c) 2007, Andrey Vedikhin |
//|                                                         http://www.vedikhin.ru |
//|                                                                                           |
//|                                                                               Ver. 1.0 |
//|                                                                                           |
//| This expert advisor is distributed on an "AS IS" basis, WITHOUT   |
//| WARRANTY OF ANY KIND, either express or implied.                  |
//|                                                                                           |
//| You will use it on your own risk and Andrey Vedikhin will not be |
//| liable for any damage, loss or profit of any kind while using or    |
//| misusing this expert advisor.                                                   |
//+-------------------------------------------------------------------------------------------+
#property copyright "Copyright (c) 2007, Andrey Vedikhin"
#property link      "http://www.vedikhin.blog-forex.org"

//---- input parameters
extern int       BuyLimit_SL=17;
extern int       SellLimit_SL=17;
extern int       BuyLimit_Diff=15;
extern int       SellLimit_Diff=19;

// время в минутах, сколько отложенные ордера будут действительны
extern int       Expiration=240;       

// время, когда размещать отложенные ордера (по времени MetaTrader)
extern string    StartTime="16:00";    

// время, когда нужно закрывать позиции
extern string    CloseTime="08:00";    

extern int       TrailingStop=60;
extern double    Lots=1.0;
extern int       Slippage=3;

int              MyMagicNumber = 777;
datetime         LastTradeTime;
int              StartHour;
int              StartMinute;
int              CloseHour;
int              CloseMinute;
//+------------------------------------------------------------------+
//| expert initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//----    
    // установим ряд переменных, чтобы не вычислять их каждый раз
    StartHour   = TimeHour(StrToTime(StartTime));
    StartMinute = TimeMinute(StrToTime(StartTime));
    CloseHour   = TimeHour(StrToTime(CloseTime));
    CloseMinute = TimeMinute(StrToTime(CloseTime));

    // LastTradeTime - когда в последний раз выставляли отложенные ордера
    LastTradeTime = 0;
    int c_hour = TimeHour(TimeCurrent());
    int c_minute = TimeMinute(TimeCurrent());
    if ((c_hour>StartHour)||((c_hour==StartHour)&&(c_minute>=StartMinute))) 
      LastTradeTime = TimeCurrent();
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                      |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
    int i;
    int t;
    datetime c_time = TimeCurrent();
    int c_hour = TimeHour(c_time);
    int c_minute = TimeMinute(c_time);
    
    // Проверим, не пора ли нам выставлять отложенные ордера
    if (TimeDay(c_time)!=TimeDay(LastTradeTime)) 
      {
       if ((c_hour>StartHour)||((c_hour==StartHour)&&(c_minute>=StartMinute)))
         {
           // выставим buy limit
           t = OrderSend(Symbol(), OP_BUYLIMIT, Lots, Bid-Point*BuyLimit_Diff, Slippage,
                Bid-Point*BuyLimit_Diff-BuyLimit_SL*Point, 0, NULL, MyMagicNumber, 
                c_time+60*Expiration, Green);
           if (t==-1)
             {
              Print("Error ", GetLastError(), ": Start()->OrderSend() [Op=OP_BUYLIMIT]");
              return(0);
             }
          
           // выставим sell limit
           if (OrderSend(Symbol(), OP_SELLLIMIT, Lots, Ask+Point*SellLimit_Diff, Slippage, 
              Ask+Point*SellLimit_Diff+SellLimit_SL*Point, 0, NULL, MyMagicNumber, 
              c_time+60*Expiration, Red)==-1)
             {
              LastTradeTime = TimeCurrent();
              Print("Error ", GetLastError(), ": Start()->OrderSend() [Op=OP_SELLLIMIT]");
              if (OrderDelete(t)) Print("Pending order #", t, " has been deleted");
              else Print("Error ", GetLastError(), ": Start()->OrderDelete()");
             }
           LastTradeTime = TimeCurrent();
           return(0);          
         }
      }
      
    // если один отложенный ордер сработал, то удалим второй
    t = -1;
    for (i=0; i<OrdersTotal(); i++)
      {
        if (!OrderSelect(i, SELECT_BY_POS))
          {
           Print("Error ", GetLastError(), ": Start()->OrderSelect(", i, ") [OrderTotal()=", OrdersTotal(),"]");
           continue;
          }
        if (OrderSymbol()!=Symbol()) continue;
        if (OrderMagicNumber()!=MyMagicNumber) continue;
        if ((OrderType() == OP_BUYLIMIT)||(OrderType() == OP_SELLLIMIT))
          {
            if (t!=-1) 
              {
                t = -1;
                break;
              }
            else 
              {
               t = OrderTicket();
              }
          }
      }
    if (t!=-1) 
      {
        if (OrderDelete(t)) Print("Pending order #", t, " has been deleted [OCO]");
        else Print("Error ", GetLastError(), ": Start()->OrderDelete() [OCO]");
      }  
            
    // не пора закрывать позиции?
    if (((c_hour>CloseHour)||((c_hour==CloseHour)&&(c_minute>=CloseMinute)))&&
       (TimeDay(c_time)!=TimeDay(LastTradeTime)))
      {
       for (i=0; i<OrdersTotal(); i++)
         {
           if (!OrderSelect(i, SELECT_BY_POS))
             {
              Print("Error ", GetLastError(), ": Start()->OrderSelect(", i, ") [OrderTotal()=", OrdersTotal(),"]");
              continue;
             }
           if (OrderSymbol()!=Symbol()) continue;
           if (OrderMagicNumber()!=MyMagicNumber) continue;
           if (OrderType() == OP_BUY)
             {
               if (!OrderClose(OrderTicket(), OrderLots(), Bid, Slippage)) 
                   Print("Error ", GetLastError(), ": Start()->OrderClose() [cannot close",
                           " a buy position]");
               return(0);
             }           
           if (OrderType() == OP_SELL) 
             {
               if (!OrderClose(OrderTicket(), OrderLots(), Ask, Slippage)) 
                   Print("Error ", GetLastError(), ": Start()->OrderClose() [cannot close",
                           " a short position]");
               return(0);
             }                    
         }
      }
      
    // управление трейлинг стопом
    for (i=0; i<OrdersTotal(); i++)
      {
        if (!OrderSelect(i, SELECT_BY_POS))
          {
           Print("Error ", GetLastError(), ": Start()->OrderSelect(", i, ") [OrderTotal()=", OrdersTotal(),"]");
           continue;
          }
        if (OrderSymbol()!=Symbol()) continue;
        if (OrderMagicNumber()!=MyMagicNumber) continue;
        double diff;
        if (OrderType() == OP_BUY)
          {
            diff = Bid-Point*TrailingStop-OrderStopLoss();
            if (diff>0) 
              {
                if (!OrderModify(OrderTicket(), OrderOpenPrice(), Bid-Point*TrailingStop, 0,0)) 
                       Print("Error ", GetLastError(), ": Start()->OrderModify() [trailing stop]");
                else 
                       Print("Trailing stop on #", OrderTicket()," [place stop loss at ",
                               Bid-Point*TrailingStop, "]");
              }
            return(0);
          }           
        if (OrderType() == OP_SELL) 
          {
            diff = OrderStopLoss()-Ask-Point*TrailingStop;
            if (diff>0) 
              {
                if (!OrderModify(OrderTicket(), OrderOpenPrice(), Ask+Point*TrailingStop,0,0))
                       Print("Error ", GetLastError(), ": Start()->OrderModify() [trailing stop]");
                else 
                       Print("Trailing stop on #", OrderTicket()," [place stop loss at ", 
                               Ask+Point*TrailingStop, "]");
              }
            return(0);
          }                    
      }
    
//----
   return(0);
  }
//+------------------------------------------------------------------+

В следующем выпуске я разберу код эксперта "по косточкам" и расскажу о непонятных для Вас функциях.



Все статьи по теме "Пишем советников для MetaTrader 4".

« Предыдущий пост | На главную страницу | Следующий пост »

Комментарии по теме "Торговля в ночное время"

Здравствуйте Андрей.

Спасибо за ваши старания, ваш блог достаточно интересен, особенно в вопросах программирования на MQL4.
Однако в данном случае есть некоторое противоречие. Дело в том, что вы пытаетесь выставить одновременно два ордера с привязкой к условию «время». В таком случае, если один из ордеров по какой-то причине не будет установлен, то значение переменной LastTradeTime все равно будет установлено как текущее время и повторно условие уже не сработает до завтра. Далее, естественным образом должен будет удалиться и второй ордер, так как он останется один. Вероятно, следовало бы устанавливать текущее значение LastTradeTime только в том случае, если оба ордера были выставлены.
Плюс к этому не плохо было бы использовать глобальные переменные (из другой вашей статьи), на тот случай, если торговля будет осуществляться по нескольким инструментам в одно и то же время. В противном случае, вероятность потерять ордера (или ордеры?) будет увеличиваться.
Возможно, я не прав и цель данной статью в том, чтобы показать, как работают функции времени, а не как торговать по времени. В таком случае, извините
:)

Благодарю за столь лестные отзывы в адрес моего проекта.

Я абсолютино согласен с Ваши замечанием про LastTradeTime, однако Ваше решение, к сожалению, тоже не лишено недостатков. Если будет выставлен только один ордер, то на следующем тике эксперт снова попытается выставить оба ордера и мы получим в итоге три ордера. Решением может быть предварительный просмотр, не был ли уже какой-то из ордеров выставлен.

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

Я подытожу весь предыдущий опыт и напишу идеального (с точки зрения реагирования на проблемные ситуации) эксперта позже. Это будет давно мною обещаемый эксперт по теории хаоса.

Подписаться на мою рассылку



Размещение статьи "Торговля в ночное время" на Вашем сайте

Размещение статьи "Торговля в ночное время" на Вашем сайте возможно при условии выполнениия следующих условий:

  • Запрещается изменение оригинального текста без согласия автора - Андрея Ведихина.
  • Должен быть указан первоисточник. В случае публикации в интернете Вы должны разместить следующий код гиперссылки без изменений:
  • Запрещается коммерческое использование материалов, взятых с блога "Интернет-трейдинг на форекс / forex". Доступ к ним должен быть свободным, без взимания какой-либо платы, без обязательной регистрации и/или заполнения опросного листа (анкеты) и т.д.

В случае выполнения данных условий не требуется согласия автора блога "Интернет-трейдинг на форекс / forex" на размещение статьи "Торговля в ночное время" на Вашем сайте.

Журнал FOREX MAGAZINE:



Архив номеров FOREX MAGAZINE
Котировки Forex:

Счетчики:

Авторские права © 2005-2006 Андрей Ведихин

Условия использования материалов блога "Интернет-трейдинг на форекс / forex"

Контакты с автором:


Движок сайта:
Movable Type 5.04