← К каталогу
Исходный код · ID 4411

Auto_Sessions

! auto sessions sos !.mq5
Вы автор или правообладатель?

Сообщите нам, если считаете, что материал размещён без разрешения.

Краткий обзор

О программе

Индикатор «Auto_Sessions» для MetaTrader 5 — инструмент визуализации торговых сессий Forex на графике. Он отображает до пяти настраиваемых сессионных периодов (по умолчанию: Сидней, Токио, Франкфурт, Лондон, Нью-Йорк) в виде цветных прямоугольников, линий или вертикальных/горизонтальных маркеров, что позволяет трейдеру быстро оценивать активность рынка.

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

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

Настройки программы

НастройкаОписание
ExcludeSundayData Исключить данные воскресенья (YES/NO)
SessionNames Названия сессий (строка из пяти значений, разделённых «/»)
ShowSessions Отображать сессии (строка из пяти значений 1/0, разделённых «/»)
ShowNames Отображать названия сессий (строка из пяти значений 1/0, разделённых «/»)
ShowPips Отображать значения пипов сессий (строка из пяти значений 1/0, разделённых «/»)
TimeMethod Метод определения времени сессий: смещение восточного часового пояса брокера или ручной ввод
__OffsetNote Примечание: при использовании смещения восточного часового пояса
BrokerEasternOffset Смещение восточного часового пояса брокера (целое число, используется при методе «Broker Eastern offset»)
Manual_SessionBegins Вручную задаваемое время начала сессий (строка из пяти значений, разделённых «/»)
Manual_SessionEnds Вручную задаваемое время окончания сессий (строка из пяти значений, разделённых «/»)
Note_SessionSelections Индивидуальные параметры сессий (разделитель групп настроек)
Color1 Цвет сессии 1
Style1 Стиль отображения сессии 1
Color2 Цвет сессии 2
Style2 Стиль отображения сессии 2
Color3 Цвет сессии 3
Style3 Стиль отображения сессии 3
Color4 Цвет сессии 4
Style4 Стиль отображения сессии 4
Color5 Цвет сессии 5
Style5 Стиль отображения сессии 5
Note_CommonSessionSelections Общие параметры сессий (разделитель групп настроек)
LineWidth Ширина линии (для общих параметров сессий)
LineStyle Стиль линии (для общих параметров сессий)
SessionTextColor Цвет текста названия/пипов сессии
SessionTextFont Шрифт текста названия/пипов сессии
SessionTextFontSize Размер шрифта текста названия/пипов сессии
SessionTextBaseCorner Базовый угол текста сессии (угол расположения метки)
SessionTextAnchorPoint Точка привязки текста сессии (точка якоря)
PipsRounded Округлять значения пипов (true/false)
PipsWord Отображать слово «пипы» после значения пипов (true/false)
Note_IndicatorSelections Параметры индикатора (разделитель групп настроек)
MinTimeframe Минимальный таймфрейм для отображения сессий
MaxTimeframe Максимальный таймфрейм для отображения сессий
MaxBars Максимальное количество баров для обработки
Note_OpenLinesSelections Параметры линий открытия (разделитель групп настроек)
Plot_Open_Lines Построить уровни открытия (YES/NO)
OpenClr1 Цвет линии открытия сессии 1
OpenClr2 Цвет линии открытия сессии 2
OpenClr3 Цвет линии открытия сессии 3
OpenClr4 Цвет линии открытия сессии 4
OpenClr5 Цвет линии открытия сессии 5
SessLineStyle Стиль линий открытия
SessLineLineWidth Ширина линий открытия
LinesInForeground Линии на переднем плане (YES/NO)
SessNameOnLine Название сессии на линии открытия (YES/NO)
AllSessions Построить все сессии (включая скрытые)?
Получить полный код

Поиск по коду файла

#property indicator_chart_window
#property indicator_buffers 0

#define PROPERTY_COPYRIGHT     "2021 Modifications by iDiamond  ©  25 May 2022 modified by Tankk "
#define PROPERTY_VERSION       "22.145"                          // Year.Day of Year
#define PROPERTY_LINK          ""

#define PROPERTY_DESCRIPTION_1 "Highlight Session Trading Periods"
#define PROPERTY_DESCRIPTION_2 " "
#define PROPERTY_DESCRIPTION_3 "Display up to a maximum of 5 different Session periods"
#define PROPERTY_DESCRIPTION_4 " "
#define PROPERTY_DESCRIPTION_5 "Check Eastern local time: www.timeanddate.com/worldclock/usa/new-york"
#define PROPERTY_DESCRIPTION_6 "Reliable Forex hours: www.forexmarkethours.com, www.markethours.net"

#ifdef __MQL4__
#define MQL4(x) x
#else
#define MQL4(x)
#endif

#define DEBUG 0                // #define DEBUG 1   // Print useful info in the Experts tab.
#define DbugInfo(x) x          // define as x for informational debugging 4

#define INPUTVARDELIMITER      "================================"

#define ONEHOURsecs 3600       // 1 hour in seconds
#define ONEDAYsecs  86400      // 1 day in seconds
#define ONEDAYmins  1440       // 1 day in minutes
#define NAMEPIPDELIMITER " "   // String between Session Name and Session Pips
#define NAMEPIPMARGIN    " "   // Pad the Session Text with this string
#define REASON_USER_INIT 2021  // Custom OnDeinit() reason
#define WINMAXVAL 1.5  //100.0        // Sufficiently large Window Minimum/Maximum that will ever be visible during whole Timeseries scroll

#define MAX_SESSIONS 5  // This should be equal to the number of input colors and >= the number of sessions in $SESS_NAMES_DFAULT
#define SESS_NAMES_DEFAULT "Sydney/Tokyo/Frankfurt/London/NY"   // These should all be unique.

enum ENUM_TimeMethod   { Broker_Eastern_Offset, // Broker Eastern Time Zone Offset
                         Manual                 // Manual Input of Start and End Times 
                       };
enum ENUM_SessionStyle { Rectangle_Fill,            // Filled Rectangle
                         Rectangle_Line,            // Line Bordered Rectangle 
                         Vertical_Fill,             // Filled Vertical
                         Vertical_Lines,            // Vertical Lines, Begin and End
                         Vertical_Line_Begin,       // Vertical Line, Begin
                         Vertical_Line_End,         // Vertical Line, End
                         Vertical_Fill_All,         // Filled Vertical in all Sub-Windows                         
                         Vertical_Lines_All,        // Vertical Lines in all Sub-Windows, Begin and End
                         Vertical_Lines_All_Begin,  // Vertical Lines in all Sub-Windows, Begin
                         Vertical_Lines_All_End,    // Vertical Lines in all Sub-Windows, End
                         Horizontal_Lines,          // Horizontal Lines, High and Low
                         Horizontal_Line_High,      // Horizontal Line, High
                         Horizontal_Line_Low        // Horizontal Line, Low
                       };                  
enum ENUM_LineType     { VLine_Begin, VLine_End, HLine_High, HLine_Low };

enum ENUM_YESNO
  {
   YES,
   NO, 
  };
sinput ENUM_YESNO        ExcludeSundayData      = YES;                              // Exclude Sunday Data?        
sinput string            SessionNames           = SESS_NAMES_DEFAULT;               // Session Names
sinput string            ShowSessions           = "1/0/0/1/1";                      // Show Sessions
sinput string            ShowNames              = "1/0/0/1/1";                      // Show Session Names
sinput string            ShowPips               = "1/0/0/1/1";                      // Show Session Pips
sinput ENUM_TimeMethod   TimeMethod             = Broker_Eastern_Offset;            // Time Method
sinput string            __OffsetNote           = "..exactly *5* sessions above.";  // Note: If Using Eastern Time Zone Offset...
sinput int               BrokerEasternOffset    = 7;                                // Broker Eastern Time Zone Offset

sinput string            Manual_SessionBegins   = "00:00:00/02:00:00/09:00:00/10:00:00/14:00:00";  // Manual Session Begin Times
sinput string            Manual_SessionEnds     = "08:59:59/10:59:59/17:59:59/18:59:59/23:59:59";  // Manual Session End Times

sinput string Note_SessionSelections            = INPUTVARDELIMITER;                // Individual Session Options
sinput color             Color1                 = clrBlue;                          // Session 1 Color
sinput ENUM_SessionStyle Style1                 = Rectangle_Fill;                   // Session 1 Style
sinput color             Color2                 = clrRed;                           // Session 2 Color
sinput ENUM_SessionStyle Style2                 = Rectangle_Fill;                   // Session 2 Style 
sinput color             Color3                 = clrOrange;                        // Session 3 Color
sinput ENUM_SessionStyle Style3                 = Rectangle_Fill;                   // Session 3 Style
sinput color             Color4                 = clrGreen;                         // Session 4 Color
sinput ENUM_SessionStyle Style4                 = Rectangle_Fill;                   // Session 4 Style
sinput color             Color5                 = clrGray;                          // Session 5 Color
sinput ENUM_SessionStyle Style5                 = Rectangle_Fill;                   // Session 5 Style

sinput string Note_CommonSessionSelections      = INPUTVARDELIMITER;                // Common Session Options

sinput int               LineWidth              = 1;                                // Line Width
sinput ENUM_LINE_STYLE   LineStyle              = STYLE_SOLID;                      // Line Style
sinput color             SessionTextColor       = clrGoldenrod;                     // Session Name/Pip Text Colot
sinput string            SessionTextFont        = "Arial Bold";                     // Session Name/Pip Text Font
sinput int               SessionTextFontSize    = 9;                                // Session Name/Pip Text Font Size
sinput ENUM_BASE_CORNER  SessionTextBaseCorner  = CORNER_LEFT_UPPER;                // Session Name/Pip Text Base Corner
sinput ENUM_ANCHOR_POINT SessionTextAnchorPoint = ANCHOR_LEFT_UPPER;                // Session Name/Pip Text Anchor Point
sinput bool              PipsRounded            = true;                             // Round Off Pip Values?

sinput bool              PipsWord               = false;                            // Display " pips" After Pip Value?

sinput string Note_IndicatorSelections          = INPUTVARDELIMITER;                // Indicator Options
sinput ENUM_TIMEFRAMES   MinTimeframe           = PERIOD_M1;                        // Minimum Timeframe to Display Sessions
sinput ENUM_TIMEFRAMES   MaxTimeframe           = PERIOD_H1;                        // Maximum Timeframe to Display Sessions
sinput int               MaxBars                = 1440;                             // Max Bars to Use

sinput string                               Note_OpenLinesSelections  = INPUTVARDELIMITER;  // Open Lines Options
sinput ENUM_YESNO                           Plot_Open_Lines           = YES;                // Plot Opem levels?
sinput color                                OpenClr1                  = clrLightBlue;       // Session 1 Open lines color
sinput color                                OpenClr2                  = clrLightSalmon;     // Session 2 Open lines color
sinput color                                OpenClr3                  = clrLightCoral;      // Session 3 Open lines color
sinput color                                OpenClr4                  = clrLightGreen;      // Session 4 Open lines color
sinput color                                OpenClr5                  = clrDimGray;         // Session 5 Open lines color
sinput ENUM_LINE_STYLE                      SessLineStyle             = STYLE_SOLID;        // Open lines style
sinput int                                  SessLineLineWidth         = 4;                  // Open lines width
sinput ENUM_YESNO                           LinesInForeground         = YES;                // Lines on foreground?
sinput ENUM_YESNO                           SessNameOnLine            = YES;                // Session name on Open Line?
sinput ENUM_YESNO                           AllSessions               = NO;                 // Plot all sessions?

const string asEASTERN_BEGINS[MAX_SESSIONS] = {"17:00:00", "19:00:00", "02:00:00", "03:00:00", "08:00:00"};
const string asEASTERN_ENDS  [MAX_SESSIONS] = {"01:59:59", "03:59:59", "10:59:59", "11:59:59", "16:59:59"};

string   gsObjectPrefix;              // For unique Object Names with multiple indicators

int               giNSessions;                 // Number of Sessions to Display
string            gasNames         [MAX_SESSIONS];  // Session Name
bool              gabShowSess      [MAX_SESSIONS],  // Show Session?
                  gabShowName      [MAX_SESSIONS],  // Show Session Text with Session Name
                  gabShowPips      [MAX_SESSIONS];  // Show Session Text with Session Pips range value 
color             gaoColors        [MAX_SESSIONS];  // Session Color
ENUM_SessionStyle gaeStyles        [MAX_SESSIONS];  // Session Style  

color             sesColors        [MAX_SESSIONS];  // Open Session Color

datetime          galTimeBeginSecs [MAX_SESSIONS],  // Session Begin in seconds, Date portion is 0000.00.00
                  galTimeEndSecs   [MAX_SESSIONS];  // Session End in seconds,   Date portion is 0000.00.00

int OnInit(void)
{
      // код доступен только после оплаты
   } // OnInit()

int OnCalculate(const int       rates_total,      // size of input time series
                const int       prev_calculated,  // bars handled in previous call
                const datetime& time[],           // Time
                const double&   open[],           // Open
                const double&   high[],           // High
                const double&   low[],            // Low
                const double&   close[],          // Close
                const long&     tick_volume[],    // Tick Volume
                const long&     volume[],         // Real Volume
                const int&      spread[])         // Spread
{
    bool bResult;
    int giS, iBr, iStartCalcAt, iLimit, iBarSessionBegin, iBarSessionEnd;
    datetime dtOldest = 0, dtNewest = 0, dtCalled = TimeLocal(), dtExit, dtSessionBegin, dtSessionEnd;
    double dHighest, dLowest, dOpen;

    if ((PeriodSeconds(PERIOD_CURRENT) < PeriodSeconds(MinTimeframe))  ||  (PeriodSeconds(PERIOD_CURRENT) > PeriodSeconds(MaxTimeframe)))
        return(rates_total);  // Inactive Timeframe now (Can be switched to an allowed Timeframe later)

    bResult = ArraySetAsSeries(time, true);

    bResult = ArraySetAsSeries(high, true);

    bResult = ArraySetAsSeries(low, true);

    /* int iSize = ArraySize(time);
    DbugInfo( Print(__FILE__, " ", __FUNCTION__, "@", __LINE__, " ArraySize(time) = ", iSize, " vs ", rates_total); )
    iSize = ArraySize(high);
    DbugInfo( Print(__FILE__, " ", __FUNCTION__, "@", __LINE__, " ArraySize(high) = ", iSize, " vs ", rates_total); )
    iSize = ArraySize(low);
    DbugInfo( Print(__FILE__, " ", __FUNCTION__, "@", __LINE__, " ArraySize(low)  = ", iSize, " vs ", rates_total); ) */

    if (rates_total > 0)
      {
          dtOldest = time[(rates_total > 0) ? (rates_total - 1) : 0];
          dtNewest = time[0];
      }

    iStartCalcAt = rates_total - prev_calculated;
    if (iStartCalcAt > MaxBars)
        iStartCalcAt = MaxBars;
    if (iStartCalcAt > 0)  // Subtract one as array index, but process at least the [0] bar otherwise
      iStartCalcAt--; 

    for (giS = 0; giS < giNSessions; giS++)
      {
    while(ExcludeSundayData==YES && TimeDayOfWeek(iTime(NULL,PERIOD_D1,giS))==0) giS++;
          if (! gabShowSess[giS])  // Skip unselected Sessions 
              continue;

          iLimit = iStartCalcAt;
          if(AllSessions==NO&&_Period<PERIOD_D1)
          iLimit = PERIOD_D1/_Period-(24-Hour())*_Period;

          for (iBr = 0; iBr <= iLimit; iBr++) // Process newest to oldest, assuming most recent bars are most likely visible    
            {
                if ( ((dtSessionBegin = GetSessionBegin(galTimeBeginSecs[giS], galTimeEndSecs[giS], time[iBr])) < 0) ||
                     ((dtSessionEnd   = GetSessionEnd  (galTimeBeginSecs[giS], galTimeEndSecs[giS], time[iBr])) < 0) )
                  {
                      /* DbugInfo( Print(__FILE__, " ", __FUNCTION__, "@", __LINE__, " ", gasNames[giS], " Skip (", iBr, ") ",
                                      TimeToString(time[iBr], TIME_DATE|TIME_MINUTES), " ! ",
                                      TimeToString(galTimeBeginSecs[giS], TIME_SECONDS), " - ", 
                                      TimeToString(galTimeEndSecs  [giS], TIME_SECONDS)); ) */
                      continue;
                  }

                iBarSessionBegin = GetBeginBar(dtSessionBegin, dtSessionEnd, iBr, time, (rates_total > 0) ? (rates_total - 1) : 0);
                iBarSessionEnd   = GetEndBar  (dtSessionBegin, dtSessionEnd, iBr, time, 0);

                dHighest = HighestPrice(high, iBarSessionBegin, iBarSessionEnd);
                dLowest  = LowestPrice (low,  iBarSessionBegin, iBarSessionEnd);
                dOpen = iOpen(_Symbol,_Period,iBarSessionBegin);

                /* DbugInfo( Print(__FILE__, " ", __FUNCTION__, "@", __LINE__, " ", gasNames[giS], 
                                " Draw (", iBr, ",", iBarSessionBegin, ",", iBarSessionEnd, ") ", 
                                TimeToString(time[iBr], TIME_DATE|TIME_MINUTES), ",  (",
                                time[iBarSessionBegin], " - ", time[iBarSessionEnd], ", highest= ", 
                                DoubleToString(dHighest, _Digits), ", lowest= ", DoubleToString(dLowest, _Digits), ")"); ) */
                DrawSession(gasNames[giS], gaoColors[giS], gaeStyles[giS], gabShowName[giS], gabShowPips[giS], 
                            time[iBarSessionBegin], time[iBarSessionEnd], dHighest, dLowest, dOpen);
                if(Plot_Open_Lines==YES)
                HLINE(gsObjectPrefix+gasNames[giS]+" Open level"+iBr,dOpen,dOpen,time[iBarSessionBegin],time[iBarSessionEnd],sesColors[giS],SessLineStyle,SessLineLineWidth);           

                iBr = iBarSessionBegin;
            }
      } 

    ChartRedraw();  // Per ChartRedraw() documentation, Usually it is used after changing the object properties.

    dtExit = TimeLocal();
    /* DbugInfo( Print(__FILE__, " ", __FUNCTION__, "@", __LINE__, 
                    " rates_total= ",  rates_total, " (",  TimeToString(dtOldest, TIME_DATE|TIME_SECONDS), ")", 
                    ", prev_calculated= " , prev_calculated, " (", TimeToString(dtNewest, TIME_DATE|TIME_SECONDS), ")  <",
                    TimeToString(dtCalled, TIME_SECONDS), "-", TimeToString(dtExit, TIME_SECONDS), "> Elapsed= ", 
                    TimeToString(dtExit - dtCalled, TIME_SECONDS)); ) */
    return(rates_total); 
} // OnCalculate()

/*
void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
{
    switch (id)
      {
          case CHARTEVENT_KEYDOWN:
               break;
          case CHARTEVENT_MOUSE_MOVE:
          case CHARTEVENT_MOUSE_WHEEL:
               break;
          case CHARTEVENT_CLICK:         // Mouse click on a chart
               break;
          case CHARTEVENT_OBJECT_CLICK:  // lparam = X coordinate, dparam = Y coordinate, sparam = Name of the graphical object
          case CHARTEVENT_OBJECT_DRAG:
               break;
          case CHARTEVENT_OBJECT_ENDEDIT:
               break;                                                  
          case CHARTEVENT_OBJECT_CREATE: 
          case CHARTEVENT_OBJECT_CHANGE:
          case CHARTEVENT_OBJECT_DELETE:
               break;
          case CHARTEVENT_CHART_CHANGE:
               break;
          case CHARTEVENT_CUSTOM:
          case CHARTEVENT_CUSTOM_LAST:
               break;
          default:
               break;
      }
}
*/ 

void OnDeinit(const int reason)
{
    int iResult;   Comment("");

    iResult = ObjectsDeleteAll(0, gsObjectPrefix);    

}

inline void DrawSession(const string sName, color clrSession, ENUM_SessionStyle SessionStyle, bool bShowName, bool bShowPips, 
                        datetime dtSessionBegin, datetime dtSessionEnd, double dHighest, double dLowest, double dOpen)
{
    bool bResult, bResult1, bResult2, bResult3, bResult4, bResult5, bResult6, bResult7, bResult8, bResult9, 
         bBack = true, bFill, bAllWins;
    int iTotalWindows=0, iSubWin=0, iResult1, iResult2;
    datetime dtMidnight, dtSessionTextDatetime;
    double dTextPrice;
    string sObjName, sText = "";

    iResult1 = iResult2 = 0;
    bResult = bResult1 = bResult2 = bResult3 = bResult4 = bResult5 = bResult6 = bResult7 = bResult8 = bResult9 = true;

    dtMidnight = DateFloorMidnight(dtSessionBegin);

    switch (SessionStyle)
      {
          case Vertical_Lines:
          case Vertical_Line_Begin:
          case Vertical_Line_End:
          case Vertical_Lines_All:
          case Vertical_Lines_All_Begin:
          case Vertical_Lines_All_End:
               if ( (SessionStyle == Vertical_Lines_All)       || 
                    (SessionStyle == Vertical_Lines_All_Begin) || (SessionStyle == Vertical_Lines_All_End) )
                   bAllWins = true;
               else
                   bAllWins = false;

               if ( (SessionStyle == Vertical_Lines)     || (SessionStyle == Vertical_Line_Begin)  ||
                    (SessionStyle == Vertical_Lines_All) || (SessionStyle == Vertical_Lines_All_Begin) )
                 {
                   sObjName = FormSessionObjName(0, dtMidnight, sName, "Begin");
                   if ( (iResult1 = ObjectFind(0, sText)) < 0 )
                     {   // If object doesn't exist..
                         bResult  = ObjectCreate    (0, sObjName, OBJ_VLINE, 0,   dtSessionBegin, 0.0);                
                         bResult1 = ObjectSetInteger(0, sObjName, OBJPROP_COLOR,  clrSession);
                         bResult2 = ObjectSetInteger(0, sObjName, OBJPROP_FILL,   true);                      
                         bResult3 = ObjectSetInteger(0, sObjName, OBJPROP_STYLE,  LineStyle);
                         bResult4 = ObjectSetInteger(0, sObjName, OBJPROP_WIDTH,  LineWidth);
                         bResult5 = ObjectSetInteger(0, sObjName, OBJPROP_BACK,   true);

                         bResult7 = ObjectSetInteger(0, sObjName, OBJPROP_RAY,    bAllWins);
                                    ObjectSetInteger(0, sObjName, OBJPROP_SELECTABLE, false);
                     }
                   bResult8 = ObjectSetInteger(0, sObjName, OBJPROP_TIME, dtSessionBegin);                   
                 } 

               if ( (SessionStyle == Vertical_Lines)     || (SessionStyle == Vertical_Line_End)  ||
                    (SessionStyle == Vertical_Lines_All) || (SessionStyle == Vertical_Lines_All_End) )
                 {
                   sObjName = FormSessionObjName(0, dtMidnight, sName, "End");
                   if ( (iResult2 = ObjectFind(0, sObjName)) < 0 )
                     {   // If object doesn't exist..
                         bResult  = ObjectCreate    (0, sObjName, OBJ_VLINE, 0,  dtSessionEnd,   0.0);                
                         bResult1 = ObjectSetInteger(0, sObjName, OBJPROP_COLOR, clrSession);  
                         bResult2 = ObjectSetInteger(0, sObjName, OBJPROP_FILL,  true);                         
                         bResult3 = ObjectSetInteger(0, sObjName, OBJPROP_STYLE, LineStyle);
                         bResult4 = ObjectSetInteger(0, sObjName, OBJPROP_WIDTH, LineWidth);
                         bResult5 = ObjectSetInteger(0, sObjName, OBJPROP_BACK,  true);  

                         bResult7 = ObjectSetInteger(0, sObjName, OBJPROP_RAY,   bAllWins);   
                                    ObjectSetInteger(0, sObjName, OBJPROP_SELECTABLE, false);
                     }
                   bResult8 = ObjectSetInteger(0, sObjName, OBJPROP_TIME, dtSessionEnd);
                 }
               break;                

          case Horizontal_Lines:
          case Ho

Показано первые 50% кода (символов: 29449)

Открыть по тарифу

Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.

Разовая покупка файла

На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.

Чтобы оформить заказ, введите email и перейдите к оплате.

Стоимость полного кода
2 944,90₽ ≈ $35.99