AlphaX RELAY
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «alphax_relay.mq5» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
AlphaX RELAY — это индикатор для MetaTrader 5, реализующий сканер ценовых паттернов с отслеживанием их жизненного цикла по фазам FORMING → ARMED → FIRED. Индикатор анализирует ценовые данные и технические показатели, выявляя классические графические модели на графике.
Индикатор поддерживает детектирование двойных вершин/дна, головы и плеч (включая инвертированный вариант), треугольников (возрастающих, нисходящих, симметричных), флагов и пиннаклов, а также восходящих и нисходящих клиньев. Для каждой обнаруженной модели рассчитывается уровень завершённости, линия шеи, точки входа, стоп-лосса и двух целей.
Система включает слой качества AlphaX: фильтрация по конфлюэнсу, анализ старших таймфреймов, оценка фрагментарности (chop) и сжатия объёма (volume coil). При достижении фазы FIRED индикатор отрисовывает на графике уровни входа, стопа и целей, а также отправляет JSON-уведомления. Все отображаемые элементы настраиваются через параметры цветов, видимости и расположения.
Настройки программы
| Настройка | Описание |
|---|---|
| InpPivLen | Длина поиска пивотов — количество баров по каждой стороне для определения вершин и впадин. |
| InpMaxPivots | Максимальное количество хранимых пивотов (вершин и впадин) при построении паттернов. |
| InpSymTolPct | Допустимое отклонение симметрии в процентах для определения парных элементов паттерна (например, вершин). |
| InpMinFormPct | Минимальный процент завершённости паттерна, при котором он отображается на графике. |
| InpArmedAtr | Множитель ATR, определяющий зону ARMED — расстояние от линии шеи, при котором паттерн считается частично сформированным. |
| InpAtrLen | Период расчёта индикатора ATR (Average True Range), используемого для определения волатильности. |
| InpMaxBarsBack | Максимальное количество баров, просматриваемых назад при поиске паттернов. Ограничение для производительности. |
| InpEnDouble | Включает или отключает детектирование паттернов «Двойная вершина» и «Двойное дно». |
| InpEnHS | Включает или отключает детектирование паттернов «Голова и плечи» и инвертированного варианта. |
| InpEnTriangle | Включает или отключает детектирование треугольников (возрастающих, нисходящих, симметричных). |
| InpEnFlag | Включает или отключает детектирование флагов и пиннаклов. |
| InpEnWedge | Включает или отключает детектирование восходящих и нисходящих клиньев. |
| InpMinConf | Минимальный балл конфлюэнса (из 10), при котором паттерн считается допустимым и отображается. |
| InpUseHtf | Включает или отключает слой анализа старшего таймфрейма (HTF Bias) для подтверждения направления паттерна. |
| InpHtfTf | Таймфрейм, используемый для слоя анализа старшего таймфрейма (HTF Bias Layer). |
| InpHtfFast | Период быстрой скользящей средней экспоненциального типа (EMA) для анализа старшего таймфрейма. |
| InpHtfSlow | Период медленной скользящей средней экспоненциального типа (EMA) для анализа старшего таймфрейма. |
| InpRequireHtfFire | При включении паттерн в фазе FIRED дополнительно должен подтверждаться совпадением направления старшего таймфрейма. |
| InpUseChop | Включает или отключает фильтрацию паттернов на основе индекса фрагментарности (Choppiness Index). |
| InpChopLen | Период расчёта индекса фрагментарности (Choppiness Index), используемого для фильтрации бокового движения. |
| InpChopMax | Пороговое значение индекса фрагментарности: при превышении этого уровня паттерн блокируется как чрезмерно фрагментированный. |
| InpUseVolCoil | Включает или отключает фильтр сжатия объёма (Volume Coil), который оценивает снижение объёма перед пробоем. |
| InpVolLen | Период расчёта скользящей средней объёма (SMA), используемой для фильтра сжатия объёма. |
| InpVolCoilMax | Максимальное отношение текущего объёма к среднему, при котором объём считается сжатым (coil condition). |
| InpBrkAtr | Множитель ATR для определения пробоя — расстояние от линии шеи, при котором паттерн переходит в фазу FIRED. |
| InpMinRR | Минимальное соотношение риска и доходности (R:R), требуемое для паттерна в фазе FIRED. |
| InpCooldown | Количество баров ожидания между последовательными сигналами FIRED для предотвращения повторных уведомлений. |
| InpShowFormBox | Включает или отключает отображение прямоугольника, обозначающего область формирования паттерна. |
| InpShowNeck | Включает или отключает отображение линии шеи (neckline) паттерна. |
| InpShowPhaseLbl | Включает или отключает отображение подписи фазы (FORMING/ARMED/FIRED) и процента завершения паттерна. |
| InpShowFiredLvls | Включает или отключает отображение уровней входа, стоп-лосса и целей для паттернов в фазе FIRED. |
| InpTp1Pct | Процент расстояния от входа до второй цели, определяющий уровень первой цели (TP1). |
| InpSlPctTgt | Процент расстояния до цели, на котором устанавливается стоп-лосс. |
| InpShowDash | Включает или отключает отображение информационной панели (дашборда) в углу графика. |
| InpDashCorner | Угол графика, в котором отображается информационная панель (дашборд). |
| InpColBull | Цвет для бычьих паттернов в основной фазе. |
| InpColBullBr | Цвет для бычьих паттернов в яркой (подсветочной) вариации. |
| InpColBear | Цвет для медвежьих (медвежьих) паттернов в основной фазе. |
| InpColBearBr | Цвет для медвежьих паттернов в яркой (подсветочной) вариации. |
| InpColForm | Цвет для паттернов в фазе FORMING (формируются). |
| InpColArmed | Цвет отображения паттернов в фазе ARMED на графике. |
| InpColFired | Цвет для паттернов в фазе FIRED (активированы). |
| InpColNeutral | Цвет для нейтральных или неактивных элементов интерфейса. |
| InpColSl | Цвет для отображения уровня стоп-лосса на графике. |
| InpColTp1 | Цвет для отображения первой цели (TP1) на графике. |
| InpColTp2 | Цвет для отображения второй цели (TP2) на графике. |
| InpColTextLt | Цвет для вспомогательного текста на графике (метки, подписи). |
| InpAlertEn | Включает или отключает отправку JSON-уведомлений при достижении паттерном фазы FIRED. |
Поиск по коду файла
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots 0
input group "Scanner Engine"
input int InpPivLen = 8; // Pivot Length
input int InpMaxPivots = 120; // Max Pivots Stored
input double InpSymTolPct = 8.0; // Level Symmetry (%)
input double InpMinFormPct = 55.0; // Min Formation % to Show
input double InpArmedAtr = 0.35; // ARMED Zone (xATR from neck)
input int InpAtrLen = 14; // ATR Length
input int InpMaxBarsBack = 500; // Max bars scanned back (perf cap)
input group "Pattern Types"
input bool InpEnDouble = true; // Double Top / Bottom
input bool InpEnHS = true; // Head & Shoulders / Inv H&S
input bool InpEnTriangle = true; // Triangles (Asc / Desc / Sym)
input bool InpEnFlag = true; // Flags & Pennants
input bool InpEnWedge = true; // Rising / Falling Wedge
input group "AlphaX Quality Layer"
input int InpMinConf = 5; // Min Confluence (of 10)
input bool InpUseHtf = true; // HTF Bias Layer
input ENUM_TIMEFRAMES InpHtfTf = PERIOD_H1; // HTF Timeframe
input int InpHtfFast = 21; // HTF Fast EMA
input int InpHtfSlow = 55; // HTF Slow EMA
input bool InpRequireHtfFire = false; // Hard Block Counter-HTF FIRED
input bool InpUseChop = true; // Block Extreme Chop
input int InpChopLen = 14; // Choppiness Length
input double InpChopMax = 62.0; // Chop Block Above
input bool InpUseVolCoil = true; // Volume Coil Before Break
input int InpVolLen = 20; // Volume SMA Length
input double InpVolCoilMax = 0.85; // Max Vol vs Avg (coil)
input double InpBrkAtr = 0.6; // FIRED Break Margin (xATR)
input double InpMinRR = 1.5; // Min R:R at FIRED
input int InpCooldown = 5; // Signal Cooldown (bars)
input group "Targets & Display"
input bool InpShowFormBox = true;
input bool InpShowNeck = true;
input bool InpShowPhaseLbl = true;
input bool InpShowFiredLvls = true;
input double InpTp1Pct = 50.0; // TP1 (% of Entry -> TP2)
input double InpSlPctTgt = 25.0; // SL % of Target Distance
input bool InpShowDash = true;
input ENUM_BASE_CORNER InpDashCorner = CORNER_RIGHT_UPPER;
input group "Colors (AlphaX Palette)"
input color InpColBull = C'200,230,36';
input color InpColBullBr = C'212,240,58';
input color InpColBear = C'255,23,68';
input color InpColBearBr = C'255,82,82';
input color InpColForm = C'139,111,208';
input color InpColArmed = C'255,152,0';
input color InpColFired = C'200,230,36';
input color InpColNeutral = C'85,85,85';
input color InpColSl = C'255,23,68';
input color InpColTp1 = C'156,204,101';
input color InpColTp2 = C'200,230,36';
input color InpColTextLt = C'204,204,204';
input group "Alerts"
input bool InpAlertEn = true; // JSON Alerts on FIRED
struct Pivot
{
double p;
int i;
};
struct RelaySetup
{
bool active;
string name;
string phase; // FORMING | ARMED | FIRED
bool isBull;
double completion;
double neck;
double height;
double entry;
double stop;
double tp2;
int startBar;
int endBar;
};
int atrHandle = INVALID_HANDLE;
int htfFastHandle = INVALID_HANDLE;
int htfSlowHandle = INVALID_HANDLE;
Pivot g_pivH[];
Pivot g_pivL[];
RelaySetup EmptySetup()
{
RelaySetup s;
s.active=false; s.name=""; s.phase=""; s.isBull=false;
s.completion=0; s.neck=0; s.height=0; s.entry=0; s.stop=0; s.tp2=0;
s.startBar=0; s.endBar=0;
return s;
}
bool Near(double a,double b,double tol)
{
return MathAbs(a-b) <= (a+b)*0.5*tol;
}
double Proj(double x1,double y1,double x2,double y2,double x)
{
if(x2==x1) return y1;
return y1 + (y2-y1)/(x2-x1)*(x-x1);
}
double RR(double ep,double sl,double tp)
{
double d = MathAbs(ep-sl);
return d>0 ? MathAbs(tp-ep)/d : 0.0;
}
double Tp1Level(double ep,double tp2,bool bull)
{
double d = MathAbs(tp2-ep);
return bull ? ep + d*(InpTp1Pct/100.0) : ep - d*(InpTp1Pct/100.0);
}
color PhaseColor(string ph)
{
if(ph=="FIRED") return InpColFired;
if(ph=="ARMED") return InpColArmed;
return InpColForm;
}
double HighestRange(const double &arr[], int i1, int i2)
{
double m = arr[i1];
for(int k=i1;k<=i2;k++) if(arr[k]>m) m=arr[k];
return m;
}
double LowestRange(const double &arr[], int i1, int i2)
{
double m = arr[i1];
for(int k=i1;k<=i2;k++) if(arr[k]<m) m=arr[k];
return m;
}
double TrueRangeAt(const double &high[], const double &low[], const double &close[], int idx)
{
if(idx<=0) return high[idx]-low[idx];
double a = high[idx]-low[idx];
double b = MathAbs(high[idx]-close[idx-1]);
double c = MathAbs(low[idx]-close[idx-1]);
return MathMax(a,MathMax(b,c));
}
double ChopIndex(const double &high[], const double &low[], const double &close[], int curIdx, int len)
{
int from = curIdx-len+1;
if(from<1) from=1;
double trSum=0.0;
for(int k=from;k<=curIdx;k++) trSum += TrueRangeAt(high,low,close,k);
double hh = HighestRange(high,from,curIdx);
double ll = LowestRange(low,from,curIdx);
double hl = hh-ll;
if(hl<=0) return 50.0;
return 100.0*MathLog10(trSum/hl)/MathLog10(len);
}
void BuildPivots(const double &high[], const double &low[], int ratesTotal, int pivLen,
int maxPivots, int scanStart, Pivot &outHigh[], Pivot &outLow[])
{
ArrayResize(outHigh,0);
ArrayResize(outLow,0);
int lastIdx = ratesTotal-1-pivLen;
int firstIdx = MathMax(pivLen, scanStart);
if(lastIdx<firstIdx) return;
for(int idx=lastIdx; idx>=firstIdx; idx--)
{
bool isPH=true, isPL=true;
double hv=high[idx], lv=low[idx];
for(int k=idx-pivLen;k<=idx+pivLen;k++)
{
if(k==idx) continue;
if(high[k]>=hv) isPH=false;
if(low[k]<=lv) isPL=false;
if(!isPH && !isPL) break;
}
if(isPH && ArraySize(outHigh)<maxPivots)
{
int n=ArraySize(outHigh); ArrayResize(outHigh,n+1);
outHigh[n].p=hv; outHigh[n].i=idx;
}
if(isPL && ArraySize(outLow)<maxPivots)
{
int n=ArraySize(outLow); ArrayResize(outLow,n+1);
outLow[n].p=lv; outLow[n].i=idx;
}
}
}
RelaySetup DetectDoubleForm(const Pivot &pivH[], const Pivot &pivL[], double atrVal,
double closeCur, double openCur, int curIdx)
{
RelaySetup s = EmptySetup();
if(!InpEnDouble) return s;
double tol = InpSymTolPct/100.0;
if(ArraySize(pivH)>=2 && ArraySize(pivL)>=1)
{
Pivot p1=pivH[0], p2=pivH[1], mid=pivL[0];
if(p1.i>mid.i && mid.i>p2.i && Near(p1.p,p2.p,tol))
{
double neck = mid.p;
double h = (p1.p+p2.p)*0.5 - neck;
if(h>atrVal)
{
double comp=70.0;
comp += (closeCur<neck) ? 15.0 : 0.0;
comp += (MathAbs(closeCur-neck)<=atrVal*InpArmedAtr) ? 15.0 : 0.0;
bool fired = closeCur < neck-atrVal*InpBrkAtr;
string ph = fired ? "FIRED" : (MathAbs(closeCur-neck)<=atrVal*InpArmedAtr ? "ARMED" : "FORMING");
double ep=openCur, tp2=neck-h, sl=ep+MathAbs(tp2-ep)*(InpSlPctTgt/100.0);
s.active=true; s.name="Double Top"; s.phase=ph; s.isBull=false; s.completion=comp;
s.neck=neck; s.height=h; s.entry=ep; s.stop=sl; s.tp2=tp2; s.startBar=p2.i; s.endBar=curIdx;
}
}
}
if(!s.active && ArraySize(pivL)>=2 && ArraySize(pivH)>=1)
{
Pivot p1=pivL[0], p2=pivL[1], mid=pivH[0];
if(p1.i>mid.i && mid.i>p2.i && Near(p1.p,p2.p,tol))
{
double neck = mid.p;
double h = neck - (p1.p+p2.p)*0.5;
if(h>atrVal)
{
double comp=70.0;
comp += (closeCur>neck) ? 15.0 : 0.0;
comp += (MathAbs(closeCur-neck)<=atrVal*InpArmedAtr) ? 15.0 : 0.0;
bool fired = closeCur > neck+atrVal*InpBrkAtr;
string ph = fired ? "FIRED" : (MathAbs(closeCur-neck)<=atrVal*InpArmedAtr ? "ARMED" : "FORMING");
double ep=openCur, tp2=neck+h, sl=ep-MathAbs(tp2-ep)*(InpSlPctTgt/100.0);
s.active=true; s.name="Double Bottom"; s.phase=ph; s.isBull=true; s.completion=comp;
s.neck=neck; s.height=h; s.entry=ep; s.stop=sl; s.tp2=tp2; s.startBar=p2.i; s.endBar=curIdx;
}
}
}
return s;
}
RelaySetup DetectHsForm(const Pivot &pivH[], const Pivot &pivL[], double atrVal,
double closeCur, double openCur, int curIdx)
{
RelaySetup s = EmptySetup();
if(!InpEnHS) return s;
double tol = InpSymTolPct/100.0;
if(ArraySize(pivH)>=3 && ArraySize(pivL)>=2)
{
Pivot rs=pivH[0], head=pivH[1], ls=pivH[2];
Pivot nl=pivL[1], nr=pivL[0];
if(head.p>rs.p && head.p>ls.p && Near(rs.p,ls.p,tol))
{
double neck = Proj(nl.i,nl.p,nr.i,nr.p,curIdx);
double h = head.p - (nl.p+nr.p)*0.5;
if(h>atrVal)
{
double comp=65.0;
comp += (closeCur<neck) ? 12.0 : 0.0;
comp += (MathAbs(closeCur-neck)<=atrVal*InpArmedAtr) ? 18.0 : 0.0;
string ph = (closeCur<neck-atrVal*InpBrkAtr) ? "FIRED" : (MathAbs(closeCur-neck)<=atrVal*InpArmedAtr ? "ARMED" : "FORMING");
double ep=openCur, tp2=neck-h, sl=ep+MathAbs(tp2-ep)*(InpSlPctTgt/100.0);
s.active=true; s.name="Head & Shoulders"; s.phase=ph; s.isBull=false; s.completion=comp;
s.neck=neck; s.height=h; s.entry=ep; s.stop=sl; s.tp2=tp2; s.startBar=ls.i; s.endBar=curIdx;
}
}
}
if(!s.active && ArraySize(pivL)>=3 && ArraySize(pivH)>=2)
{
Pivot rs=pivL[0], head=pivL[1], ls=pivL[2];
Pivot nh=pivH[1], rh=pivH[0];
if(head.p<rs.p && head.p<ls.p && Near(rs.p,ls.p,tol))
{
double neck = Proj(nh.i,nh.p,rh.i,rh.p,curIdx);
double h = (nh.p+rh.p)*0.5 - head.p;
if(h>atrVal)
{
double comp=65.0;
comp += (closeCur>neck) ? 12.0 : 0.0;
comp += (MathAbs(closeCur-neck)<=atrVal*InpArmedAtr) ? 18.0 : 0.0;
string ph = (closeCur>neck+atrVal*InpBrkAtr) ? "FIRED" : (MathAbs(closeCur-neck)<=atrVal*InpArmedAtr ? "ARMED" : "FORMING");
double ep=openCur, tp2=neck+h, sl=ep-MathAbs(tp2-ep)*(InpSlPctTgt/100.0);
s.active=true; s.name="Inv H&S"; s.phase=ph; s.isBull=true; s.completion=comp;
s.neck=neck; s.height=h; s.entry=ep; s.stop=sl; s.tp2=tp2; s.startBar=ls.i; s.endBar=curIdx;
}
}
}
return s;
}
RelaySetup DetectTriangleForm(const Pivot &pivH[], const Pivot &pivL[], double atrVal,
double closeCur, double openCur, int curIdx)
{
RelaySetup s = EmptySetup();
if(!InpEnTriangle) return s;
if(ArraySize(pivH)<2 || ArraySize(pivL)<2) return s;
Pivot h1=pivH[0], h2=pivH[1], l1=pivL[0], l2=pivL[1];
double uNow = Proj(h2.i,h2.p,h1.i,h1.p,curIdx);
double lNow = Proj(l2.i,l2.p,l1.i,l1.p,curIdx);
double base = MathAbs(Proj(h2.i,h2.p,h1.i,h1.p,l2.i) - Proj(l2.i,l2.p,l1.i,l1.p,l2.i));
bool conv = (uNow>lNow) && (base>atrVal);
if(!conv) return s;
double su = (h1.p-h2.p)/MathMax(1,h1.i-h2.i);
double slp = (l1.p-l2.p)/MathMax(1,l1.i-l2.i);
bool asc = MathAbs(su)<closeCur*0.0003 && slp>0;
bool desc = su<0 && MathAbs(slp)<closeCur*0.0003;
bool bullBreak = closeCur > uNow+atrVal*InpBrkAtr;
bool bearBreak = closeCur < lNow-atrVal*InpBrkAtr;
if(bullBreak || (!bearBreak && (asc || su<0)))
{
double comp = 60.0 + (base/atrVal>2 ? 15 : 5);
comp += (MathAbs(closeCur-uNow)<=atrVal*InpArmedAtr) ? 15.0 : 0.0;
string ph = bullBreak ? "FIRED" : (MathAbs(closeCur-uNow)<=atrVal*InpArmedAtr ? "ARMED" : "FORMING");
double ep=openCur, tp2=uNow+base, stp=lNow;
string nm = asc ? "Asc Triangle" : "Sym Triangle";
s.active=true; s.name=nm; s.phase=ph; s.isBull=true; s.completion=comp;
s.neck=uNow; s.height=base; s.entry=ep; s.stop=stp; s.tp2=tp2; s.startBar=l2.i; s.endBar=curIdx;
}
else if(bearBreak || desc)
{
double comp = 60.0 + (base/atrVal>2 ? 15 : 5);
comp += (MathAbs(closeCur-lNow)<=atrVal*InpArmedAtr) ? 15.0 : 0.0;
string ph = bearBreak ? "FIRED" : (MathAbs(closeCur-lNow)<=atrVal*InpArmedAtr ? "ARMED" : "FORMING");
double ep=openCur, tp2=lNow-base, stp=uNow;
string nm = desc ? "Desc Triangle" : "Sym Triangle";
s.active=true; s.name=nm; s.phase=ph; s.isBull=false; s.completion=comp;
s.neck=lNow; s.height=base; s.entry=ep; s.stop=stp; s.tp2=tp2; s.startBar=l2.i; s.endBar=curIdx;
}
return s;
}
RelaySetup DetectFlagForm(const Pivot &pivH[], const Pivot &pivL[], const double &high[], const double &low[],
double atrVal, double closeCur, double openCur, int curIdx)
{
RelaySetup s = EmptySetup();
if(!InpEnFlag) return s;
if(ArraySize(pivH)<2 || ArraySize(pivL)<2) return s;
Pivot h1=pivH[0], h2=pivH[1], l1=pivL[0], l2=pivL[1];
int sb = MathMin(h2.i,l2.i);
int span = curIdx-sb+1;
double pole=0.0;
if(span>5)
{
int win = MathMin(span,120);
int from = curIdx-win+1;
if(from<0) from=0;
pole = HighestRange(high,from,curIdx) - LowestRange(low,from,curIdx);
}
double su = (h1.p-h2.p)/MathMax(1,h1.i-h2.i);
double slo = (l1.p-l2.p)/MathMax(1,l1.i-l2.i);
if(pole<=atrVal*2.5) return s;
if(su<0 && slo<0)
{
double uB = Proj(h2.i,h2.p,h1.i,h1.p,curIdx);
double comp=62.0;
comp += (MathAbs(closeCur-uB)<=atrVal*InpArmedAtr) ? 20.0 : 0.0;
bool fired = closeCur > uB+atrVal*InpBrkAtr;
string ph = fired ? "FIRED" : (MathAbs(closeCur-uB)<=atrVal*InpArmedAtr ? "ARMED" : "FORMING");
double ep=openCur, tp2=uB+pole, stp=Proj(l2.i,l2.p,l1.i,l1.p,curIdx);
s.active=true; s.name="Bull Flag"; s.phase=ph; s.isBull=true; s.completion=comp;
s.neck=uB; s.height=pole; s.entry=ep; s.stop=stp; s.tp2=tp2; s.startBar=sb; s.endBar=curIdx;
}
else if(su>0 && slo>0)
{
double lB = Proj(l2.i,l2.p,l1.i,l1.p,curIdx);
double comp=62.0;
comp += (MathAbs(closeCur-lB)<=atrVal*InpArmedAtr) ? 20.0 : 0.0;
bool fired = closeCur < lB-atrVal*InpBrkAtr;
string ph = fired ? "FIRED" : (MathAbs(closeCur-lB)<=atrVal*InpArmedAtr ? "ARMED" : "FORMING");
double ep=openCur, tp2=lB-pole, stp=Proj(h2.i,h2.p,h1.i,h1.p,curIdx);
s.active=true; s.name="Bear Flag"; s.phase=ph; s.isBull=false; s.completion=comp;
s.neck=lB; s.height=pole; s.entry=ep; s.stop=stp; s.tp2=tp2; s.startBar=sb; s.endBar=curIdx;
}
return s;
}
RelaySetup DetectWedgeForm(const Pivot &pivH[], const Pivot &pivL[], double atrVal,
double closeCur, douПоказано первые 50% кода (символов: 23917)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.