Ищу код чтобы вписать в советник. Торговое расписание. - страница 5

 
Eugene Maslyukov:

жаль что никак не протестить

можно протестить  - только выбираете дату начала тестирования ,и выставляете время старта эксперта и время закрытия - правда как сработает время закрытия , тестирование прекратится 

1

2

3

а в реале каждый день будет открываться и закрываться в заданное время 

только - создайте шаблоны, на шаблоне эксперт заданным временем  и как он сработает откроет другой шаблон, с другими настройками и так далее  

 
буду учить язык mql5. спасибо
 
Alexey Viktorov:

time_st_mon - time_st_day  - time_st_evn --- это переменные. Что они означают попытайтесь понять самостоятельно.

int  - double - datetime --- это типы переменных. Не знать этого вам должно быть стыдно.

Не сто́ит благодарности.

человек просто спросил чему равны переменные и к какому отнести их типу. не на то ответили, причём грубо


если кому-либо понадобится, то освежил расписание и добавил пару комментариев с учётом утренней сессии на FORTS


//торгуем с начала утренней сессии до промежуточного клиринга 
// 07:00-14:00
// с пром клиринга до конца основной сессии
// 14:03:00-18:44:30
// с вечерней до конца торгов календарного дня
// 19:05-23:49:00
bool CheckTradingTime(MqlDateTime &tick_time)
{
  datetime lk_time = TimeTradeServer(tick_time);

#ifdef DEBUG
  if ((tick_time.hour >= 0) && (tick_time.hour < 6))   // DEBUG 6-00
  {
    return(false);
  }
#else
  if ((tick_time.hour >= 0) && (tick_time.hour < 10))
  {
    return(false);
  }
#endif

// пример вычисления нужного времени в секундах (в одном часе 3600 сек)
// 7 * 3600                 = 25200 - 07:00:00
// 14 * 3600                = 50400 - 14:00:00
// 14 * 3600 + 60           = 50460 - 14:01:00

// 18 * 3600 + 44 * 60 + 30 = 67470 - 18:44:30
// 18 * 3600 + 45 * 60      = 67500 - 18:45:00

// 19 * 3600                = 68400 - 19:00:00
// 19 * 3600 + 60           = 68460 - 19:01:00  

// 23 * 3600 + 49 * 60 + 30 = 85770 - 23:49:30
// 23 * 3600 + 50 * 60      = 85800 - 23:50:00

//---
  lk_time = TimeCurrent(tick_time);
//переменные для начала времени торговой сессии  
  ulong time_start_morning_session=25200;   // после ночного перерыва
  ulong time_start_afternoon_session=50580; // старт торгов после промежуточного клиринга
  ulong time_start_evening_session=68700;   // старт торгов после основного клиринга
  ulong trade_time = tick_time.hour * 3600 + tick_time.min * 60 + tick_time.sec;  
//---                    //10:00:02                      


  if(((trade_time >= time_start_morning_session) && (trade_time < 50370)) ||
      ((trade_time >= time_start_afternoon_session) && (trade_time < 67470)) ||
      ((trade_time >= time_start_evening_session) && (trade_time < 85770)))
  {
    return(true);
  }

return(false);
}
 
John Peterson:

человек просто спросил чему равны переменные и к какому отнести их типу. не на то ответили, причём грубо


если кому-либо понадобится, то освежил расписание и добавил пару комментариев с учётом утренней сессии на FORTS


Ты спустя полтора года решил поумничать?

 
Alexey Viktorov:

Ты спустя полтора года решил поумничать?

Наверное, хотя я не разрешал публиковать мой код (часть кода).

Весь опубликованный мною код, предназначен только для личного пользования.

 
SanAlex:

Вот еще вариант намудрил - главное работает! 

Хорошо, что эти моменты времени фиксированы и их не нужно оптимизировать. Глянуть бы что-то изящнее чем у меня.  

 
Dmytryi Voitukhov:

Хорошо, что эти моменты времени фиксированы и их не нужно оптимизировать. Глянуть бы что-то изящнее чем у меня.  

Увы, начало вечёрки - не фиксировано. 19:00 или 19:05, а через год-другой, глядишь, и ещё на пару минут клиринг(дневной или вечерний) продлят, как уже было.

 

Вот еще вариант намудрил - главное работает! 

//+------------------------------------------------------------------+
//|                                                    timestart.mq5 |
//|                                  Copyright 2021, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
//---
sinput group "1"
sinput datetime HoursFrom0 = D'1970.01.01 10:01'; // START | 00::00->off |
//---
sinput datetime HoursTo0   = D'1970.01.01 13:59'; // STOP Close | 00::00->off |
sinput group "2"
sinput datetime HoursFrom1 = D'1970.01.01 14:05'; // START | 00::00->off |
//---
sinput datetime HoursTo1   = D'1970.01.01 18:44'; // STOP Close | 00::00->off |
sinput group "3"
sinput datetime HoursFrom2 = D'1970.01.01 19:00'; // START | 00::00->off |
//---
sinput datetime HoursTo2   = D'1970.01.01 23:49'; // STOP Close | 00::00->off |
//---
datetime Today0=D'1970.01.01';
datetime Today1=D'1970.01.01';
datetime Today2=D'1970.01.01';
datetime Todayx=D'1970.01.01';
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//---
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(void)
  {
//---
   timeStart();
   timeClose();
  }
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void timeStart(void)
  {
//---
   MqlDateTime currTime;
   TimeToStruct(TimeLocal(),currTime);
   Todayx=currTime.hour*60*60+currTime.min*60;
   if((HoursFrom0 < HoursTo0 && Todayx >= HoursFrom0 && Todayx< HoursTo0) ||
      (HoursFrom0 > HoursTo0 && (Todayx< HoursTo0 || Todayx >= HoursFrom0))
      ||(HoursFrom1 < HoursTo1 && Todayx >= HoursFrom1 && Todayx < HoursTo1) ||
      (HoursFrom1 > HoursTo1 && (Todayx< HoursTo1 || Todayx >= HoursFrom1))
      ||(HoursFrom2 < HoursTo2 && Todayx >= HoursFrom2 && Todayx < HoursTo2) ||
      (HoursFrom2 > HoursTo2 && (Todayx< HoursTo2 || Todayx >= HoursFrom2)))
     {
      //--- Сюда
      Print("START = ",Todayx);
     }
  }
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void timeClose(void)
  {
//---
   MqlDateTime currTime;
   TimeToStruct(TimeLocal(),currTime);
   Todayx=currTime.hour*60*60+currTime.min*60;
   if((Todayx != Today0 && Todayx == HoursTo0)||
      (Todayx != Today1 && Todayx == HoursTo1)||
      (Todayx != Today2 && Todayx == HoursTo2))
     {
      Today0 = Todayx;
      Today1 = Todayx;
      Today2 = Todayx;
      //--- Сюда
      Print("STOP Close = ",Todayx);
     }
  }
//+------------------------------------------------------------------+


 
SanAlex:

Вот еще вариант намудрил - главное работает! 


Вот именно, намудрили!

Нельзя брать 

TimeLocal()

Время сервера и Ваше локальное время могут существенно отличаться.

Да и торговля ведется по времени сервера.

Добавлено

Самое правильное, это проверять время последнего тика

//+------------------------------------------------------------------+
//|                                                    Test_time.mq5 |
//|                                      Copyright 2021 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021 prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"
//
MqlTick cur_tick[];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Ontick function                                                  |
//+------------------------------------------------------------------+
bool CheckTradeTime()
{
  int res = CopyTicks(Symbol(), cur_tick, COPY_TICKS_ALL, 0, 1);
  if(res == 1)
  {
    datetime cur_time = cur_tick[0].time;
    //Здесь проверяем время, если в границах, то возвращаем TRUE
  }
  return(false);
}
//+------------------------------------------------------------------+
//| Ontick function                                                  |
//+------------------------------------------------------------------+
void OnTick()
{
  if (CheckTradeTime() == true)
  {
    //Continue trade
  }
}
//+------------------------------------------------------------------+
 
prostotrader:

Вот именно, намудрили!

Нельзя брать 

Время сервера и Ваше локальное время могут существенно отличаться.

Да и торговля ведется по времени сервера.

Добавлено

Самое правильное, это проверять время последнего тика

можно заменить TimeLocal() на TimeCurrent()

TimeCurrent

Возвращает последнее известное время сервера, время прихода последней котировки по одному из выбранных в "Обзоре рынка" символов. В обработчике OnTick() данная функция вернет время пришедшего обрабатываемого тика. В других случаях (например, вызов в обработчиках OnInit(), OnDeinit(), OnTimer() и так далее) это – время прихода последней котировки по любому символу, доступного в окне "Обзор рынка", то самое время, которое показано в заголовке этого окна. Значение времени формируется на торговом сервере и не зависит от настроек времени на компьютере пользователя. Существует 2 варианта функции.

//+------------------------------------------------------------------+
//|                                              Moving Averages.mq5 |
//|                   Copyright 2009-2017, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2009-2017, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//---
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
CTrade            m_trade;    // trading object
CSymbolInfo       m_symbol;   // symbol info object
CPositionInfo     m_position; // trade position object
//---
input double MaximumRisk        = 0.02;    // Maximum Risk in percentage
input double DecreaseFactor     = 3;       // Descrease factor
input int    MovingPeriod       = 12;      // Moving Average period
input int    MovingShift        = 6;       // Moving Average shift
//---
sinput group "1"
sinput datetime HoursFrom0 = D'1970.01.01 10:01'; // START
//---
sinput datetime HoursTo0   = D'1970.01.01 13:59'; // STOP Close
sinput group "2"
sinput datetime HoursFrom1 = D'1970.01.01 14:05'; // START
//---
sinput datetime HoursTo1   = D'1970.01.01 18:44'; // STOP Close
sinput group "3"
sinput datetime HoursFrom2 = D'1970.01.01 19:00'; // START
//---
sinput datetime HoursTo2   = D'1970.01.01 23:49'; // STOP Close
//---
datetime Today0=D'1970.01.01';
datetime Today1=D'1970.01.01';
datetime Today2=D'1970.01.01';
datetime Todayx=D'1970.01.01';
//---
int    ExtHandle=0;
bool   ExtHedging=false;
//---
#define MA_MAGIC 1234501
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double TradeSizeOptimized(void)
  {
   double price=0.0;
   double margin=0.0;
//--- select lot size
   if(!SymbolInfoDouble(_Symbol,SYMBOL_ASK,price))
      return(0.0);
   if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin))
      return(0.0);
   if(margin<=0.0)
      return(0.0);
   double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_MARGIN_FREE)*MaximumRisk/margin,2);
//--- calculate number of losses orders without a break
   if(DecreaseFactor>0)
     {
      //--- select history for access
      HistorySelect(0,TimeCurrent());
      //---
      int    orders=HistoryDealsTotal();  // total history deals
      int    losses=0;                    // number of losses orders without a break
      for(int i=orders-1; i>=0; i--)
        {
         ulong ticket=HistoryDealGetTicket(i);
         if(ticket==0)
           {
            Print("HistoryDealGetTicket failed, no trade history");
            break;
           }
         //--- check symbol
         if(HistoryDealGetString(ticket,DEAL_SYMBOL)!=_Symbol)
            continue;
         //--- check Expert Magic number
         if(HistoryDealGetInteger(ticket,DEAL_MAGIC)!=MA_MAGIC)
            continue;
         //--- check profit
         double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
         if(profit>0.0)
            break;
         if(profit<0.0)
            losses++;
        }
      //---
      if(losses>1)
         lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
     }
//--- normalize and check limits
   double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lot=stepvol*NormalizeDouble(lot/stepvol,0);
   double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
   if(lot<minvol)
      lot=minvol;
   double maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
   if(lot>maxvol)
      lot=maxvol;
//--- return trading volume
   return(lot);
  }
//+------------------------------------------------------------------+
//| Check for open position conditions                               |
//+------------------------------------------------------------------+
void CheckForOpen(void)
  {
   MqlRates rt[2];
//--- go trading only for first ticks of new bar
   if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return;
     }
   if(rt[1].tick_volume>1)
      return;
//--- get current Moving Average
   double   ma[1];
   if(CopyBuffer(ExtHandle,0,0,1,ma)!=1)
     {
      Print("CopyBuffer from iMA failed, no data");
      return;
     }
//--- check signals
   ENUM_ORDER_TYPE signal=WRONG_VALUE;
   if(rt[0].open>ma[0] && rt[0].close<ma[0])
      signal=ORDER_TYPE_SELL;    // sell conditions
   else
     {
      if(rt[0].open<ma[0] && rt[0].close>ma[0])
         signal=ORDER_TYPE_BUY;  // buy conditions
     }
//--- additional checking
   if(signal!=WRONG_VALUE)
     {
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
         m_trade.PositionOpen(_Symbol,signal,TradeSizeOptimized(),
                              SymbolInfoDouble(_Symbol,signal==ORDER_TYPE_SELL ? SYMBOL_BID:SYMBOL_ASK),
                              0,0);
     }
//---
  }
//+------------------------------------------------------------------+
//| Check for close position conditions                              |
//+------------------------------------------------------------------+
void CheckForClose(void)
  {
   MqlRates rt[2];
//--- go trading only for first ticks of new bar
   if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return;
     }
   if(rt[1].tick_volume>1)
      return;
//--- get current Moving Average
   double   ma[1];
   if(CopyBuffer(ExtHandle,0,0,1,ma)!=1)
     {
      Print("CopyBuffer from iMA failed, no data");
      return;
     }
//--- positions already selected before
   bool signal=false;
   long type=PositionGetInteger(POSITION_TYPE);
   if(type==(long)POSITION_TYPE_BUY && rt[0].open>ma[0] && rt[0].close<ma[0])
      signal=true;
   if(type==(long)POSITION_TYPE_SELL && rt[0].open<ma[0] && rt[0].close>ma[0])
      signal=true;
//--- additional checking
   if(signal)
     {
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
         m_trade.PositionClose(_Symbol,3);
     }
//---
  }
//+------------------------------------------------------------------+
//| Position select depending on netting or hedging                  |
//+------------------------------------------------------------------+
bool SelectPosition()
  {
   bool res=false;
//--- check position in Hedging mode
   if(ExtHedging)
     {
      uint total=PositionsTotal();
      for(uint i=0; i<total; i++)
        {
         string position_symbol=PositionGetSymbol(i);
         if(_Symbol==position_symbol && MA_MAGIC==PositionGetInteger(POSITION_MAGIC))
           {
            res=true;
            break;
           }
        }
     }
//--- check position in Netting mode
   else
     {
      if(!PositionSelect(_Symbol))
         return(false);
      else
         return(PositionGetInteger(POSITION_MAGIC)==MA_MAGIC); //---check Magic number
     }
//--- result for Hedging mode
   return(res);
  }
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//--- prepare trade class to control positions if hedging mode is active
   ExtHedging=((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING);
   m_trade.SetExpertMagicNumber(MA_MAGIC);
   m_trade.SetMarginMode();
   m_trade.SetTypeFillingBySymbol(Symbol());
//--- Moving Average indicator
   ExtHandle=iMA(_Symbol,_Period,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE);
   if(ExtHandle==INVALID_HANDLE)
     {
      printf("Error creating MA indicator");
      return(INIT_FAILED);
     }
//--- ok
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(void)
  {
//---
   MqlDateTime currTime;
   TimeToStruct(TimeCurrent(),currTime);
   Todayx=currTime.hour*60*60+currTime.min*60;
   if((HoursFrom0 < HoursTo0 && Todayx >= HoursFrom0 && Todayx< HoursTo0) ||
      (HoursFrom0 > HoursTo0 && (Todayx< HoursTo0 || Todayx >= HoursFrom0))
      ||(HoursFrom1 < HoursTo1 && Todayx >= HoursFrom1 && Todayx < HoursTo1) ||
      (HoursFrom1 > HoursTo1 && (Todayx< HoursTo1 || Todayx >= HoursFrom1))
      ||(HoursFrom2 < HoursTo2 && Todayx >= HoursFrom2 && Todayx < HoursTo2) ||
      (HoursFrom2 > HoursTo2 && (Todayx< HoursTo2 || Todayx >= HoursFrom2)))
     {
      //--- Сюда
      if(SelectPosition())
         CheckForClose();
      else
         CheckForOpen();
     }
//---
   if((Todayx != Today0 && Todayx == HoursTo0)||
      (Todayx != Today1 && Todayx == HoursTo1)||
      (Todayx != Today2 && Todayx == HoursTo2))
     {
      Today0 = Todayx;
      Today1 = Todayx;
      Today2 = Todayx;
      //--- Сюда
      CloseAll();
      Print("STOP Close = ",Todayx);
     }
//---
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }
//+------------------------------------------------------------------+
//| start function                                                   |
//+------------------------------------------------------------------+
void CloseAll(void)
  {
   for(int i=PositionsTotal()-1; i>=0; i--)
      if(m_position.SelectByIndex(i))
        {
         ClosePosition(m_position.Symbol());
        }
  }
//+------------------------------------------------------------------+
//| Close selected position                                          |
//+------------------------------------------------------------------+
void ClosePosition(const string symbol)
  {
   if(InitTrade(symbol))
      m_trade.PositionClose(m_position.Ticket());
   PlaySound("ok.wav");
  }
//+------------------------------------------------------------------+
//| Init trade object                                                |
//+------------------------------------------------------------------+
bool InitTrade(const string symbol)
  {
   if(!m_symbol.Name(symbol))
      return(false);
//---
   if(IsFillingTypeAllowed(symbol,SYMBOL_FILLING_FOK))
      m_trade.SetTypeFilling(ORDER_FILLING_FOK);
   else
      if(IsFillingTypeAllowed(symbol,SYMBOL_FILLING_IOC))
         m_trade.SetTypeFilling(ORDER_FILLING_IOC);
      else
         m_trade.SetTypeFilling(ORDER_FILLING_RETURN);
//---
   return(true);
//---
  }
//+------------------------------------------------------------------+
//| Checks if the specified filling mode is allowed                  |
//+------------------------------------------------------------------+
bool IsFillingTypeAllowed(string symbol,int fill_type)
  {
//--- Obtain the value of the property that describes allowed filling modes
   int filling=(int)SymbolInfoInteger(symbol,SYMBOL_FILLING_MODE);
//--- Return true, if mode fill_type is allowed
   return((filling & fill_type)==fill_type);
  }
//+------------------------------------------------------------------+


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