shk_ha_grid_ea.mq5
Похожие материалы по тегам
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «shk_ha_grid_ea.mq5» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
SHK HA Grid EA — это самодостаточный торговый советник для MetaTrader 5, в который встроен движок сигналов на основе свечей Хайлин Аши и дивергенции MACD. Советник не требует внешних индикаторных файлов: вся логика расчёта индикаторов Хайлин Аши и MACD реализована непосредственно в коде.
Сигналы формируются на закрытых барах, что обеспечивает режим без перерисовок. Доступны два режима генерации сигналов: торговля при подтверждённом изменении цвета HA-свечей и режим импульсов с ожиданием пробоя. Дополнительно доступна фильтрация сигналов по тренду через скользящую среднюю более высокого таймфрейма.
Советник поддерживает управление позицией фиксированным лотом или риском в процентах от баланса, стоп-лосс и тейк-профит в пунктах или через ATR, трейлинг-стоп, а также модуль сетки/усреднения с несколькими режимами закрытия корзины. Реализованы всплывающие, push-уведомления и звуковые оповещения.
Настройки программы
| Настройка | Описание |
|---|---|
| I1 | Заголовок раздела настроек движка сигналов (встроенный HA + MACD дивергенция). |
| InpMaxBarsToCalculate | Количество баров истории для пересчёта состояния сигнала при каждом новом баре. |
| InpUseClosedBarsOnly | Режим без перерисовок: сигналы формируются только на полностью закрытых барах. |
| InpConfirmationCandles | Количество последовательных одноцветных свечей Хайлин Аши, необходимых для подтверждения сигнала (от 1 до 10). |
| InpMinBodyPercent | Минимальный процент тела свечи Хайлин Аши для подтверждения сигнала. |
| InpSignalOnHAColorChange | true — торговля при подтверждённом изменении цвета HA-свечей; false — режим импульсов с ожиданием пробоя. |
| InpRequireMACDDivergence | Обязательное наличие дивергенции MACD для формирования сигнала. |
| InpMACDFastEMA | Период быстрой EMA для расчёта индикатора MACD. |
| InpMACDSlowEMA | Период медленной EMA для расчёта индикатора MACD. |
| InpMACDSignalEMA | Период сигнальной EMA для расчёта индикатора MACD. |
| InpDivergencePivotLookback | Глубина поиска пивотов для определения дивергенции MACD. |
| InpDivergenceSearchBars | Количество баров назад для поиска предыдущих пивотов при расчёте дивергенции MACD. |
| InpDivergenceConfirmWindow | Количество баров назад для проверки наличия подтверждённой дивергенции MACD. |
| InpRequireStrongCandleForCircle | Требование сильной свечи для инициации импульсного сигнала (используется только в режиме импульсов). |
| InpCancelSignalOnOppositeHA | Отмена ожидающегося сигнала при появлении свечи противоположного цвета HA (используется только в режиме импульсов). |
| InpConfirmByCloseBreak | Подтверждение сигнала импульса пробоем цены (true) или по закрытию бара (false), используется только в режиме импульсов. |
| I1b | Заголовок раздела настроек фильтра тренда. |
| InpUseTrendFilter | Включение фильтра тренда для подавления сигналов, противоречащих текущему тренду. |
| InpTrendMATimeframe | Таймфрейм для расчёта скользящей средней фильтра тренда (рекомендуется более высокий таймфрейм). |
| InpTrendMAPeriod | Период скользящей средней для фильтра тренда. |
| InpTrendMAMethod | Метод расчёта скользящей средней для фильтра тренда. |
| I2 | Заголовок раздела настроек торговли. |
| InpMagic | Магический номер для идентификации позиций, открытых советником. |
| InpTradeComment | Комментарий к торговым операциям, открытым советником. |
| InpTradeDirection | Направление торговли: обе стороны, только покупка или только продажа. |
| InpSlippagePoints | Допустимое проскальзывание в пунктах при исполнении торговых операций. |
| InpMaxSpreadPoints | Максимально допустимый спред в пунктах (0 — проверка спреда отключена). |
| InpCloseOnOppositeSignal | Закрытие текущих позиций при появлении сигнала противоположного направления. |
| I3 | Заголовок раздела настроек управления позицией. |
| InpFixedLots | Фиксированный объём позиции (используется при нулевом значении риска в процентах). |
| InpRiskPercent | Процент риска от баланса на одну сделку (0 — используется фиксированный лот). |
| I4 | Заголовок раздела настроек стоп-лосса и тейк-профита. |
| InpUseATRForSLTP | Использование ATR вместо фиксированных пунктов для расчёта стоп-лосса и тейк-профита. |
| InpATRPeriod | Период индикатора ATR для расчёта стоп-лосса и тейк-профита. |
| InpATRMultiplierSL | Множитель ATR для расчёта стоп-лосса (при использовании ATR вместо фиксированных пунктов). |
| InpATRMultiplierTP | Множитель ATR для расчёта тейк-профита (при использовании ATR вместо фиксированных пунктов). |
| InpStopLossPips | Стоп-лосс в пунктах (при использовании фиксированных значений). |
| InpTakeProfitPips | Тейк-профит в пунктах (при использовании фиксированных значений). |
| I5 | Заголовок раздела настроек трейлинг-стопа. |
| InpUseTrailingStop | Включение трейлинг-стопа для открытых позиций. |
| InpTrailingStartPips | Прибыль в пунктах, после которой активируется трейлинг-стоп. |
| InpTrailingStopPips | Расстояние трейлинг-стопа от текущей цены в пунктах. |
| InpTrailingStepPips | Шаг трейлинг-стопа в пунктах. |
| I6 | Заголовок раздела настроек сетки и усреднения. |
| InpGridEnabled | Включение модуля сетки/усреднения. |
| InpGridStepPips | Расстояние между уровнями сетки в пунктах. |
| InpGridMaxLevels | Максимальное количество уровней сетки, включая начальную позицию. |
| InpGridLotMultiplier | Множитель объёма для каждого дополнительного уровня сетки. |
| InpGridUseIndividualSL | Установка индивидуального широкого стоп-лосса на каждую сеточную позицию. |
| InpGridIndividualSLPips | Ширина индивидуального стоп-лосса для каждой сеточной позиции в пунктах. |
| InpGridTPMode | Режим закрытия корзины: по каждой позиции отдельно, по денежному итогу корзины или по пунктам от средней цены входа. |
| InpGridBasketTakeProfitMoney | Суммарный тейк-профит корзины в денежном эквиваленте аккаунтной валюты (используется при режиме BASKET_MONEY). |
| InpGridBasketStopLossMoney | Суммарный стоп-лосс корзины в денежном эквиваленте аккаунтной валюты (0 — отключено). |
| InpGridBasketTakeProfitPips | Тейк-профит корзины в пунктах от средней цены входа (используется при режиме BASKET_PIPS). |
| I7 | Заголовок раздела настроек оповещений. |
| InpEnablePopupAlert | Включение всплывающих оповещений при подтверждении сигнала. |
| InpEnablePushAlert | Включение push-уведомлений при подтверждении сигнала. |
| InpEnableSoundAlert | Включение звуковых оповещений при подтверждении сигнала. |
| InpBuySoundFile | Файл звукового оповещения для сигналов на покупку. |
| InpSellSoundFile | Файл звукового оповещения для сигналов на продажу. |
| InpAlertCooldownSeconds | Задержка в секундах между повторными оповещениями одного направления. |
Поиск по коду файла
#property version "2.00"
#property description "Self-contained EA: embedded SHK Heikin Ashi + MACD divergence signal engine, SL/TP, trailing stop and grid/averaging module."
#property strict
#include <Trade\Trade.mqh>
enum ENUM_TRADE_DIRECTION
{
DIR_BOTH = 0, // Buy and Sell
DIR_BUY_ONLY = 1, // Buy only
DIR_SELL_ONLY = 2 // Sell only
};
enum ENUM_GRID_TP_MODE
{
GRID_TP_PER_TRADE = 0, // Each grid trade has its own TP
GRID_TP_BASKET_MONEY = 1, // Close whole basket at target profit (account currency)
GRID_TP_BASKET_PIPS = 2 // Close whole basket when price reaches X pips from average entry
};
input string I1 = "====== Signal Engine (embedded HA + MACD divergence) ======"; // ---
input int InpMaxBarsToCalculate = 3000; // history window used to rebuild the signal state each bar
input bool InpUseClosedBarsOnly = true; // non-repaint: only ever act on a fully closed bar
input int InpConfirmationCandles = 1; // 1 to 10, consecutive same-color HA candles required
input double InpMinBodyPercent = 0.0;
input bool InpSignalOnHAColorChange = true; // true = trade on confirmed HA color flip; false = momentum/pending-breakout mode
input bool InpRequireMACDDivergence = true;
input int InpMACDFastEMA = 12;
input int InpMACDSlowEMA = 26;
input int InpMACDSignalEMA = 5;
input int InpDivergencePivotLookback = 2;
input int InpDivergenceSearchBars = 200;
input int InpDivergenceConfirmWindow = 30;
input bool InpRequireStrongCandleForCircle = false; // only used in momentum mode (InpSignalOnHAColorChange = false)
input bool InpCancelSignalOnOppositeHA = true; // only used in momentum mode
input bool InpConfirmByCloseBreak = true; // only used in momentum mode
input string I1b = "====== Trend Filter (recommended) ======"; // ---
input bool InpUseTrendFilter = true; // suppress signals that fight the prevailing trend
input ENUM_TIMEFRAMES InpTrendMATimeframe= PERIOD_CURRENT; // use a higher timeframe (e.g. H1) for a smoother read
input int InpTrendMAPeriod = 200;
input ENUM_MA_METHOD InpTrendMAMethod = MODE_EMA;
input string I2 = "====== Trading ======"; // ---
input ulong InpMagic = 20260815;
input string InpTradeComment = "SHK-HA-EA";
input ENUM_TRADE_DIRECTION InpTradeDirection = DIR_BOTH;
input int InpSlippagePoints = 30;
input double InpMaxSpreadPoints = 0; // 0 = disabled
input bool InpCloseOnOppositeSignal = true;
input string I3 = "====== Position Sizing ======"; // ---
input double InpFixedLots = 0.01; // used when InpRiskPercent = 0
input double InpRiskPercent = 0.0; // 0 = use fixed lots, otherwise % balance risk per trade based on SL distance
input string I4 = "====== Stop Loss / Take Profit ======"; // ---
input bool InpUseATRForSLTP = false;
input int InpATRPeriod = 14;
input double InpATRMultiplierSL = 2.0;
input double InpATRMultiplierTP = 3.0;
input double InpStopLossPips = 50;
input double InpTakeProfitPips = 100;
input string I5 = "====== Trailing Stop ======"; // ---
input bool InpUseTrailingStop = false;
input double InpTrailingStartPips = 30;
input double InpTrailingStopPips = 20;
input double InpTrailingStepPips = 5;
input string I6 = "====== Grid / Averaging ======"; // ---
input bool InpGridEnabled = false;
input double InpGridStepPips = 200; // distance between grid levels
input int InpGridMaxLevels = 5; // includes the initial trade
input double InpGridLotMultiplier = 1.5; // lot multiplier per additional level
input bool InpGridUseIndividualSL = true; // safety SL on every grid trade (wide)
input double InpGridIndividualSLPips = 300;
input ENUM_GRID_TP_MODE InpGridTPMode = GRID_TP_BASKET_MONEY;
input double InpGridBasketTakeProfitMoney= 10.0; // account currency, used if mode = BASKET_MONEY
input double InpGridBasketStopLossMoney = 0.0; // 0 = disabled, account currency
input double InpGridBasketTakeProfitPips = 50; // pips from average entry, used if mode = BASKET_PIPS
input string I7 = "====== Alerts ======"; // ---
input bool InpEnablePopupAlert = true;
input bool InpEnablePushAlert = false;
input bool InpEnableSoundAlert = false;
input string InpBuySoundFile = "alert.wav";
input string InpSellSoundFile = "alert2.wav";
input int InpAlertCooldownSeconds = 120;
#define MOM_BODY_WINDOW 14
#define CIRCLE_WICK_FRAC 0.15
CTrade trade;
int g_atrHandle = INVALID_HANDLE;
int g_trendMAHandle = INVALID_HANDLE;
double g_point = 0.0;
double g_pip = 0.0; // pip size (10 * point on 3/5-digit symbols)
datetime g_lastBarTime = 0;
int g_confCandles = 1;
int g_basketDir = 0; // 0 = none, 1 = buy, -1 = sell
double g_basketEntryPx = 0.0; // price of the very first grid entry
int g_basketLevels = 0; // number of grid levels filled so far
datetime g_lastAlertBarTime = 0;
int g_lastAlertDir = 0;
datetime g_lastAlertWall = 0;
double eHAOpen[];
double eHAHigh[];
double eHALow[];
double eHAClose[];
double eMacdFast[];
double eMacdSlow[];
double eMacdSignal[];
double eMacdHist[];
bool eBullDiv[];
bool eBearDiv[];
int eFirstBar = 1;
bool eBuyPending = false;
double eBuyRefHigh = 0.0;
int eBuyBarsLeft = 0;
bool eSellPending = false;
double eSellRefLow = 0.0;
int eSellBarsLeft= 0;
string GV_Dir() { return StringFormat("SHK_HA_EA_%s_%I64u_Dir", _Symbol, InpMagic); }
string GV_Entry() { return StringFormat("SHK_HA_EA_%s_%I64u_Entry", _Symbol, InpMagic); }
string GV_Levels() { return StringFormat("SHK_HA_EA_%s_%I64u_Levels", _Symbol, InpMagic); }
void SaveBasketState()
{
GlobalVariableSet(GV_Dir(), (double)g_basketDir);
GlobalVariableSet(GV_Entry(), g_basketEntryPx);
GlobalVariableSet(GV_Levels(), (double)g_basketLevels);
}
void LoadBasketState()
{
g_basketDir = GlobalVariableCheck(GV_Dir()) ? (int)GlobalVariableGet(GV_Dir()) : 0;
g_basketEntryPx = GlobalVariableCheck(GV_Entry()) ? GlobalVariableGet(GV_Entry()) : 0.0;
g_basketLevels = GlobalVariableCheck(GV_Levels()) ? (int)GlobalVariableGet(GV_Levels()) : 0;
}
void ClearBasketState()
{
g_basketDir = 0;
g_basketEntryPx = 0.0;
g_basketLevels = 0;
if(GlobalVariableCheck(GV_Dir())) GlobalVariableDel(GV_Dir());
if(GlobalVariableCheck(GV_Entry())) GlobalVariableDel(GV_Entry());
if(GlobalVariableCheck(GV_Levels())) GlobalVariableDel(GV_Levels());
}
bool EIsBullishHA(const int i) { return(eHAClose[i] > eHAOpen[i]); }
bool EIsBearishHA(const int i) { return(eHAClose[i] < eHAOpen[i]); }
double EGetBodyPercent(const int i)
{
double range = eHAHigh[i] - eHALow[i];
if(range <= 0.0) return(0.0);
return(MathAbs(eHAClose[i] - eHAOpen[i]) / range * 100.0);
}
double EAvgHABody(const int i, const int win, const int firstBar)
{
int st = i - win;
if(st < firstBar) return(0.0);
double s = 0.0; int c = 0;
for(int k = st; k < i; k++) { s += MathAbs(eHAClose[k] - eHAOpen[k]); c++; }
return(c > 0 ? s / c : 0.0);
}
void EComputeHABar(const int i, const MqlRates &r[])
{
double haClose = (r[i].open + r[i].high + r[i].low + r[i].close) / 4.0;
double haOpen = (eHAOpen[i - 1] + eHAClose[i - 1]) / 2.0;
double haHigh = MathMax(r[i].high, MathMax(haOpen, haClose));
double haLow = MathMin(r[i].low, MathMin(haOpen, haClose));
eHAOpen[i] = haOpen; eHAClose[i] = haClose; eHAHigh[i] = haHigh; eHALow[i] = haLow;
}
void EInitHASeed(const int firstBar, const MqlRates &r[])
{
double haClose = (r[firstBar].open + r[firstBar].high + r[firstBar].low + r[firstBar].close) / 4.0;
double haOpen = (r[firstBar].open + r[firstBar].close) / 2.0;
eHAClose[firstBar] = haClose;
eHAOpen[firstBar] = haOpen;
eHAHigh[firstBar] = MathMax(r[firstBar].high, MathMax(haOpen, haClose));
eHALow[firstBar] = MathMin(r[firstBar].low, MathMin(haOpen, haClose));
}
bool EIsMacdPeak(const int i, const int lookback, const int firstBar, const int lastBar)
{
if(i - lookback < firstBar || i + lookback > lastBar) return(false);
for(int k = 1; k <= lookback; k++)
if(eMacdHist[i] <= eMacdHist[i - k] || eMacdHist[i] <= eMacdHist[i + k]) return(false);
return(true);
}
bool EIsMacdTrough(const int i, const int lookback, const int firstBar, const int lastBar)
{
if(i - lookback < firstBar || i + lookback > lastBar) return(false);
for(int k = 1; k <= lookback; k++)
if(eMacdHist[i] >= eMacdHist[i - k] || eMacdHist[i] >= eMacdHist[i + k]) return(false);
return(true);
}
void EComputeMACDDivergence(const int rates_total, const int firstBar, const int lastClosed, const MqlRates &r[])
{
ArrayResize(eMacdFast, rates_total);
ArrayResize(eMacdSlow, rates_total);
ArrayResize(eMacdSignal, rates_total);
ArrayResize(eMacdHist, rates_total);
ArrayResize(eBullDiv, rates_total);
ArrayResize(eBearDiv, rates_total);
for(int i = 0; i < rates_total; i++)
{
eMacdFast[i] = 0.0; eMacdSlow[i] = 0.0; eMacdSignal[i] = 0.0; eMacdHist[i] = 0.0;
eBullDiv[i] = false; eBearDiv[i] = false;
}
if(!InpRequireMACDDivergence) return;
int fast = InpMACDFastEMA, slow = InpMACDSlowEMA, signal = InpMACDSignalEMA;
int pivotLookback = InpDivergencePivotLookback, searchBars = InpDivergenceSearchBars;
if(fast < 1) fast = 1;
if(slow < 1) slow = 1;
if(signal < 1) signal = 1;
if(pivotLookback < 1) pivotLookback = 1;
if(searchBars < 1) searchBars = 1;
if(lastClosed < firstBar + pivotLookback * 2 + 2) return;
double fastAlpha = 2.0 / ((double)fast + 1.0);
double slowAlpha = 2.0 / ((double)slow + 1.0);
double signalAlpha = 2.0 / ((double)signal + 1.0);
for(int i = firstBar; i <= lastClosed; i++)
{
double price = r[i].close;
if(i == firstBar)
{
eMacdFast[i] = price; eMacdSlow[i] = price; eMacdSignal[i] = 0.0; eMacdHist[i] = 0.0;
continue;
}
eMacdFast[i] = fastAlpha * price + (1.0 - fastAlpha) * eMacdFast[i - 1];
eMacdSlow[i] = slowAlpha * price + (1.0 - slowAlpha) * eMacdSlow[i - 1];
double macdMain = eMacdFast[i] - eMacdSlow[i];
eMacdSignal[i] = signalAlpha * macdMain + (1.0 - signalAlpha) * eMacdSignal[i - 1];
eMacdHist[i] = macdMain - eMacdSignal[i];
}
int lastPivot = lastClosed - pivotLookback;
for(int i = firstBar + pivotLookback; i <= lastPivot; i++)
{
if(EIsMacdTrough(i, pivotLookback, firstBar, lastClosed))
{
int prevTrough = -1;
int oldest = i - searchBars;
if(oldest < firstBar + pivotLookback) oldest = firstBar + pivotLookback;
for(int j = i - 1; j >= oldest; j--)
if(EIsMacdTrough(j, pivotLookback, firstBar, lastClosed)) { prevTrough = j; break; }
if(prevTrough >= 0 && r[i].low < r[prevTrough].low && eMacdHist[i] > eMacdHist[prevTrough])
eBullDiv[i + pivotLookback] = true;
}
if(EIsMacdPeak(i, pivotLookback, firstBar, lastClosed))
{
int prevPeak = -1;
int oldest = i - searchBars;
if(oldest < firstBar + pivotLookback) oldest = firstBar + pivotLookback;
for(int j = i - 1; j >= oldest; j--)
if(EIsMacdPeak(j, pivotLookback, firstBar, lastClosed)) { prevPeak = j; break; }
if(prevPeak >= 0 && r[i].high > r[prevPeak].high && eMacdHist[i] < eMacdHist[prevPeak])
eBearDiv[i + pivotLookback] = true;
}
}
}
bool ERecentMACDDivergenceConfirmed(const int i, const bool bullish)
{
if(!InpRequireMACDDivergence) return(true);
int window = InpDivergenceConfirmWindow;
if(window < 0) window = 0;
int first = i - window;
if(first < eFirstBar) first = eFirstBar;
for(int k = i; k >= first; k--)
{
if(bullish && eBullDiv[k]) return(true);
if(!bullish && eBearDiv[k]) return(true);
}
return(false);
}
bool EHasConfirmedHAColorChange(const int i, const bool bullish)
{
int candles = g_confCandles;
if(candles < 1) candles = 1;
int runStart = i - candles + 1;
int previous = runStart - 1;
if(runStart < eFirstBar + 1 || previous < eFirstBar) return(false);
for(int k = runStart; k <= i; k++)
{
if(bullish && !EIsBullishHA(k)) return(false);
if(!bullish && !EIsBearishHA(k)) return(false);
if(EGetBodyPercent(k) < InpMinBodyPercent) return(false);
}
if(bullish) return(EIsBearishHA(previous));
return(EIsBullishHA(previous));
}
int EProcessColorChangeArrow(const int i)
{
if(EHasConfirmedHAColorChange(i, true) && ERecentMACDDivergenceConfirmed(i, true))
return(+1);
if(EHasConfirmedHAColorChange(i, false) && ERecentMACDDivergenceConfirmed(i, false))
return(-1);
return(0);
}
int EProcessMomentumBranch(const int i)
{
bool curBull = EIsBullishHA(i);
bool curBear = EIsBearishHA(i);
bool prevBull = EIsBullishHA(i - 1);
bool prevBear = EIsBearishHA(i - 1);
bool placedBuyArrow = false, placedSellArrow = false;
int fired = 0;
if(eBuyPending)
{
if(InpCancelSignalOnOppositeHA && curBear)
{
eBuyPending = false;
}
else
{
bool brk = InpConfirmByCloseBreak ? (eHAClose[i] > eBuyRefHigh) : (eHAHigh[i] > eBuyRefHigh);
if(brk)
{
placedBuyArrow = true;
eBuyPending = false;
fired = +1;
}
else
{
eBuyBarsLeft--;
if(eBuyBarsLeft <= 0) eBuyPending = false;
}
}
}
if(eSellPending)
{
if(InpCancelSignalOnOppositeHA && curBull)
{
eSellPending = false;
}
else
{
bool brk = InpConfirmByCloseBreak ? (eHAClose[i] < eSellRefLow) : (eHALow[i] < eSellRefLow);
if(brk && !placedBuyArrow)
{
placedSellArrow = true;
eSellPending = false;
fired = -1;
}
else
{
eSellBarsLeft--;
if(eSellBarsLeft <= 0) eSellPending = false;
}
}
}
double bodyPct = EGetBodyPercent(i);
double avgBody = EAvgHABody(i, MOM_BODY_WINDOW, eFirstBar);
double range = eHAHigh[i] - eHALow[i];
double body = MathAbs(eHAClose[i] - eHAOpen[i]);
if(prevBear && curBull && !placedSellArrow)
{
bool ok = (bodyPct >= InpMinBodyPercent);
if(ok && InpRequireStrongCandleForCircle)
{
double lowerWick = MathMin(eHAOpen[i], eHAClose[i]) - eHALow[i];
bool strong = (range > 0.0 && lowerWick <= CIRCLE_WICK_FRAC * range) ||
(avgBody > 0.0 && body >= avgBody);
ok = strong;
}
if(ok)
{
eBuyPending = true;
eBuyRefHigh = eHAHigh[i];
eBuyBarsLeft = g_confCandles;
}
}
else if(prevBull && curBear && !placedBuyArrow)
{
bool ok = (bodyPct >= InpMinBodyPercent);
if(ok && InpRequireStrongCandleForCircle)
Показано первые 50% кода (символов: 23519)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.