VP-Range
Сообщите нам, если считаете, что материал размещён без разрешения.
Сообщить о материале
Обращение по товару «vp range v6 source code.mq5» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
О программе
VP-Range — индикатор MetaTrader 5 для построения профиля объёмов на заданном временном интервале. Он рассчитывает распределение объёмов по ценовым уровням и отображает результат в виде настраиваемых гистограмм на графике. Индикатор поддерживает несколько источников данных, режимов определения диапазона и стилей отображения, а также выделяет ключевые уровни: моды, максимум, медиану и VWAP.
Настройки программы
| Настройка | Описание |
|---|---|
| Range mode (RangeMode) | Режим диапазона — Определяет способ задания временного диапазона анализа: между двумя линиями, последние N минут или минуты до указанной линии. |
| Range minutes (RangeMinutes) | Длительность диапазона — Продолжительность анализируемого диапазона в минутах, используется в режимах "Последние минуты" и "Минуты до линии". |
| Mode step (points) (ModeStep) | Шаг моды — Размер шага в точках для поиска ценовых уровней с максимальным объёмом (мод). |
| Point scale (HgPointScale) | Масштаб точки — Множитель для цены одной единицы гистограммы, задаёт шаг ценового разрешения профиля. |
| Volume type (VolumeType) | Тип объёма — Выбор типа объёма для расчёта: тиковый или реальный. |
| Data source (DataSource) | Источник данных — Тип данных для построения профиля: тики или бары определённого таймфрейма (M1, M5, M15, M30). |
| Bar style (HgBarStyle) | Стиль столбцов — Визуальный стиль отображения столбцов гистограммы профиля объёмов. |
| Histogram position (HgPosition) | Позиция гистограммы — Размещение гистограммы на графике: слева, справа, внутри или снаружи видимой области. |
| Color 1 (HgColor) | Цвет столбцов 1 — Основной цвет столбцов гистограммы профиля. |
| Color 2 (HgColor2) | Цвет столбцов 2 — Дополнительный цвет для градиентного заполнения столбцов гистограммы. |
| Line width (HgLineWidth) | Толщина линии гистограммы — Толщина линий столбцов гистограммы. |
| Mode color (ModeColor) | Цвет мод — Цвет линий уровней мод (ценовых уровней с наибольшим объёмом). |
| Maximum color (MaxColor) | Цвет максимума — Цвет выделения уровня с максимальным объёмом. |
| Median color (MedianColor) | Цвет медианы — Цвет линии уровня медианы объёма. |
| VWAP color (VwapColor) | Цвет VWAP — Цвет линии уровня взвешенного по объёму среднего цены. |
| Mode line width (ModeLineWidth) | Толщина линий уровней — Толщина линий ключевых уровней (моды, максимум, медиана, VWAP). |
| Median & VWAP line style (StatLineStyle) | Стиль линий статистики — Стиль отображения линий медианы и VWAP. |
| Mode level line color (None=disable) (ModeLevelColor) | Цвет уровня моды — Цвет горизонтальной линии уровня моды; если цвет отключён, линия не отрисовывается. |
| Mode level line style (ModeLevelStyle) | Стиль уровня моды — Стиль линии горизонтального уровня моды. |
| Identifier (Id) | Идентификатор — Префикс идентификатора для имён графических объектов индикатора на графике. |
Поиск по коду файла
#property strict
#property indicator_chart_window
#property indicator_plots 0
#define PUT_IN_RANGE(A, L, H) ((H) < (L) ? (A) : ((A) < (L) ? (L) : ((A) > (H) ? (H) : (A))))
#define COLOR_IS_NONE(C) (((C) >> 24) != 0)
#define RGB_TO_COLOR(R, G, B) ((color)((((B) & 0x0000FF) << 16) + (((G) & 0x0000FF) << 8) + ((R) & 0x0000FF)))
#define ROUND_PRICE(A, P) ((int)((A) / P + 0.5))
#define NORM_PRICE(A, P) (((int)((A) / P + 0.5)) * P)
enum ENUM_POINT_SCALE
{
POINT_SCALE_1 = 1, // *1
POINT_SCALE_10 = 10, // *10
POINT_SCALE_100 = 100, // *100
};
enum ENUM_VP_BAR_STYLE
{
VP_BAR_STYLE_LINE, // Line
VP_BAR_STYLE_BAR, // Empty bar
VP_BAR_STYLE_FILLED, // Filled bar
VP_BAR_STYLE_OUTLINE, // Outline
VP_BAR_STYLE_COLOR // Color
};
enum ENUM_VP_SOURCE
{
VP_SOURCE_TICKS = 0, // Ticks
VP_SOURCE_M1 = 1, // M1 bars
VP_SOURCE_M5 = 5, // M5 bars
VP_SOURCE_M15 = 15, // M15 bars
VP_SOURCE_M30 = 30, // M30 bars
};
enum ENUM_VP_RANGE_MODE
{
VP_RANGE_MODE_BETWEEN_LINES = 0, // Between lines
VP_RANGE_MODE_LAST_MINUTES = 1, // Last minutes
VP_RANGE_MODE_MINUTES_TO_LINE = 2 // Minitues to line
};
enum ENUM_VP_HG_POSITION
{
VP_HG_POSITION_WINDOW_LEFT = 0, // Window left
VP_HG_POSITION_WINDOW_RIGHT = 1, // Window right
VP_HG_POSITION_LEFT_OUTSIDE = 2, // Left outside
VP_HG_POSITION_RIGHT_OUTSIDE = 3, // Right outside
VP_HG_POSITION_LEFT_INSIDE = 4, // Left inside
VP_HG_POSITION_RIGHT_INSIDE = 5 // Right inside
};
/* Calculation */
input ENUM_VP_RANGE_MODE RangeMode = VP_RANGE_MODE_BETWEEN_LINES; // Range mode
input int RangeMinutes = 1440; // Range minutes
input int ModeStep = 100; // Mode step (points)
input ENUM_POINT_SCALE HgPointScale = POINT_SCALE_10; // Point scale
input ENUM_APPLIED_VOLUME VolumeType = VOLUME_TICK; // Volume type
input ENUM_VP_SOURCE DataSource = VP_SOURCE_M1; // Data source
/* Histogram */
input ENUM_VP_BAR_STYLE HgBarStyle = VP_BAR_STYLE_LINE; // Bar style
input ENUM_VP_HG_POSITION HgPosition = VP_HG_POSITION_WINDOW_RIGHT; // Histogram position
input color HgColor = C'128,160,128'; // Color 1
input color HgColor2 = C'128,160,128'; // Color 2
input int HgLineWidth = 1; // Line width
/* Levels */
input color ModeColor = clrBlue; // Mode color
input color MaxColor = clrNONE; // Maximum color
input color MedianColor = clrNONE; // Median color
input color VwapColor = clrNONE; // VWAP color
input int ModeLineWidth = 1; // Mode line width
input ENUM_LINE_STYLE StatLineStyle = STYLE_DOT; // Median & VWAP line style
input color ModeLevelColor = Green; // Mode level line color (None=disable)
int ModeLevelWidth = 1; // Mode level line width
input ENUM_LINE_STYLE ModeLevelStyle = STYLE_SOLID; // Mode level line style
/* Service */
input string Id = "+vpr"; // Identifier
bool ShowHorizon = true; // Show data horizon
double Zoom = 0; // Zoom (0=auto)
int WaitMilliseconds = 500; // Wait milliseconds
color TimeFromColor = Blue; // Left border line color
ENUM_LINE_STYLE TimeFromStyle = STYLE_DASH; // Left border line style
color TimeToColor = Red; // Right border line color
ENUM_LINE_STYLE TimeToStyle = STYLE_DASH; // Right border line style
double HgWidthPercent = 15; // Histogram width, % of chart
void OnInit()
{
// код доступен только после оплаты
}
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
if (id == CHARTEVENT_OBJECT_DRAG)
{
if ((sparam == _tfn) || (sparam == _ttn))
CheckTimer();
}
if (id == CHARTEVENT_CHART_CHANGE)
{
int firstVisibleBar = WindowFirstVisibleBar();
int lastVisibleBar = firstVisibleBar - WindowBarsPerChart();
bool update =
(_firstVisibleBar == _lastVisibleBar) ||
(
((firstVisibleBar != _firstVisibleBar) || (lastVisibleBar != _lastVisibleBar)) &&
((HgPosition == VP_HG_POSITION_WINDOW_LEFT) || (HgPosition == VP_HG_POSITION_WINDOW_RIGHT))
);
_firstVisibleBar = firstVisibleBar;
_lastVisibleBar = lastVisibleBar;
if (UpdateAutoColors())
{
_lastOK = false;
CheckTimer();
}
else if (update)
{
CheckTimer();
}
}
}
int OnCalculate(const int ratesTotal, const int prevCalculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tickVolume[], const long &volume[], const int &spread[])
{
// код доступен только после оплаты
}
void OnTimer()
{
CheckTimer();
}
void OnDeinit(const int reason)
{
ObjectsDeleteAll(0, _prefix);
if (UninitializeReason() == REASON_REMOVE)
{
ObjectDelete(0, _tfn);
ObjectDelete(0, _ttn);
}
delete(_updateTimer);
}
void CheckTimer()
{
EventKillTimer();
if (_updateTimer.Check() || !_lastOK)
{
_lastOK = Update();
if (!_lastOK)
EventSetTimer(3);
ChartRedraw();
_updateTimer.Reset();
}
else
{
EventSetTimer(1);
}
}
bool Update()
{
ObjectsDeleteAll(0, _prefix);
datetime timeFrom, timeTo;
if (RangeMode == VP_RANGE_MODE_BETWEEN_LINES) // ����� ���� �����
{
timeFrom = GetObjectTime1(_tfn);
timeTo = GetObjectTime1(_ttn);
if ((timeFrom == 0) || (timeTo == 0))
{
datetime timeLeft = GetBarTime(WindowFirstVisibleBar());
datetime timeRight = GetBarTime(WindowFirstVisibleBar() - WindowBarsPerChart());
ulong timeRange = timeRight - timeLeft;
timeFrom = (datetime)(timeLeft + timeRange / 3);
timeTo = (datetime)(timeLeft + timeRange * 2 / 3);
DrawVLine(_tfn, timeFrom, TimeFromColor, 1, TimeFromStyle, false);
DrawVLine(_ttn, timeTo, Crimson, 1, TimeToStyle, false);
}
ObjectEnable(0, _tfn);
ObjectEnable(0, _ttn);
if (timeFrom > timeTo)
Swap(timeFrom, timeTo);
}
else if (RangeMode == VP_RANGE_MODE_MINUTES_TO_LINE) // �� ������ ����� RangeMinutes �����
{
timeTo = GetObjectTime1(_ttn);
int bar;
if (timeTo == 0)
{
int leftBar = WindowFirstVisibleBar();
int rightBar = WindowFirstVisibleBar() - WindowBarsPerChart();
int barRange = leftBar - rightBar;
bar = MathMax(0, leftBar - barRange / 3);
timeTo = GetBarTime(bar);
}
else
{
bar = _iBarShift(_Symbol, _Period, timeTo);
}
bar += RangeMinutes / (PeriodSeconds(_Period) / 60);
timeFrom = GetBarTime(bar);
DrawVLine(_tfn, timeFrom, TimeFromColor, 1, TimeFromStyle, false);
if (ObjectFind(0, _ttn) == -1)
{
DrawVLine(_ttn, timeTo, TimeToColor, 1, TimeToStyle, false);
}
ObjectDisable(0, _tfn);
ObjectEnable(0, _ttn);
}
else if (RangeMode == VP_RANGE_MODE_LAST_MINUTES)
{
timeFrom = GetBarTime(RangeMinutes - 1, PERIOD_M1);
timeTo = GetBarTime(-1, PERIOD_M1);
ObjectDelete(0, _tfn);
ObjectDelete(0, _ttn);
}
else
{
return(false);
}
if (ShowHorizon)
{
datetime horizon = GetHorizon(DataSource, _dataPeriod);
DrawHorizon(_prefix + "hz", horizon);
}
int barFrom, barTo;
if (!GetRangeBars(timeFrom, timeTo, barFrom, barTo))
return(false);
_updateOnTick = barTo < 0;
int modes[];
double volumes[];
double lowPrice;
int count;
if (DataSource == VP_SOURCE_TICKS)
count = GetHgByTicks(timeFrom, timeTo - 1, _hgPoint, _dataPeriod, VolumeType, lowPrice, volumes);
else
count = GetHg(timeFrom, timeTo - 1, _hgPoint, _dataPeriod, VolumeType, lowPrice, volumes);
if (count <= 0)
return(false);
int modeCount = _showModes ? HgModes(volumes, _modeStep, modes) : -1;
int maxPos = _showMax ? ArrayMax(volumes) : -1;
int medianPos = _showMedian ? ArrayMedian(volumes) : -1;
int vwapPos = _showVwap ? HgVwap(volumes, lowPrice, _hgPoint) : -1;
string prefix = _prefix + (string)((int)RangeMode) + " ";
double hgWidthBars = ((HgPosition == VP_HG_POSITION_LEFT_INSIDE) || (HgPosition == VP_HG_POSITION_RIGHT_INSIDE))
? (barFrom - barTo)
: WindowBarsPerChart() * (HgWidthPercent / 100.0);
double maxVolume = volumes[ArrayMaximum(volumes)];
if (maxVolume == 0)
maxVolume = 1;
double zoom = _zoom > 0 ? _zoom : hgWidthBars / maxVolume;
int drawBarFrom, drawBarTo;
if (HgPosition == VP_HG_POSITION_WINDOW_LEFT)
{
drawBarFrom = WindowFirstVisibleBar();
drawBarTo = (int)(drawBarFrom - zoom * maxVolume);
}
else if (HgPosition == VP_HG_POSITION_WINDOW_RIGHT)
{
drawBarFrom = WindowFirstVisibleBar() - WindowBarsPerChart();
drawBarTo = (int)(drawBarFrom + zoom * maxVolume);
}
else if (HgPosition == VP_HG_POSITION_LEFT_OUTSIDE)
{
drawBarFrom = barFrom;
drawBarTo = (int)(drawBarFrom + zoom * maxVolume);
}
else if (HgPosition == VP_HG_POSITION_RIGHT_OUTSIDE)
{
drawBarFrom = barTo;
drawBarTo = (int)(drawBarFrom - zoom * maxVolume);
}
else if (HgPosition == VP_HG_POSITION_LEFT_INSIDE)
{
drawBarFrom = barFrom;
drawBarTo = barTo;
}
else //if (HgPosition == VP_HG_POSITION_RIGHT_INSIDE)
{
drawBarFrom = barTo;
drawBarTo = barFrom;
}
DrawHg(prefix, lowPrice, volumes, drawBarFrom, drawBarTo, zoom, modes, maxPos, medianPos, vwapPos);
return(true);
}
datetime GetObjectTime1(const string name)
{
datetime time;
if (!ObjectGetInteger(0, name, OBJPROP_TIME, 0, time))
return(0);
return(time);
}
template <typename T>
int ArrayIndexOf(const T &arr[], const T value, const int startingFrom = 0)
{
int size = ArraySize(arr);
for (int i = startingFrom; i < size; i++)
{
if (arr[i] == value)
return(i);
}
return(-1);
}
template <typename T>
bool ArrayCheckRange(const T &arr[], int &start, int &count)
{
int size = ArraySize(arr);
if (size <= 0)
return(false);
if (count == 0)
return(false);
if ((start > size - 1) || (start < 0))
return(false);
if (count < 0)
{
count = size - start;
}
else if (count > size - start)
{
count = size - start;
}
return(true);
}
int ArrayMedian(const double &values[])
{
int size = ArraySize(values);
double halfVolume = Sum(values) / 2.0;
double v = 0;
for (int i = 0; i < size; i++)
{
v += values[i];
if (v >= halfVolume)
return(i);
}
return(-1);
}
string TrimRight(string s, const ushort ch)
{
int len = StringLen(s);
int cut = len;
for (int i = len - 1; i >= 0; i--)
{
if (StringGetCharacter(s, i) == ch)
cut--;
else
break;
}
if (cut != len)
{
if (cut == 0)
s = "";
else
s = StringSubstr(s, 0, cut);
}
return(s);
}
string DoubleToString(const double d, const uint digits, const uchar separator)
{
string s = DoubleToString(d, digits) + ""; //HACK: ��� +"" ������� ����� ������� ������ �������� (���� 697)
if (separator != '.')
{
int p = StringFind(s, ".");
if (p != -1)
StringSetCharacter(s, p, separator);
}
return(s);
}
string DoubleToCompactString(const double d, const uint digits = 8, const uchar separator = '.')
{
string s = DoubleToString(d, digits, separator);
if (StringFind(s, CharToString(separator)) != -1)
{
s = TrimRight(s, '0');
s = TrimRight(s, '.');
}
return(s);
}
double MathRound(const double value, const double error)
{
return(error == 0 ? value : MathRound(value / error) * error);
}
template <typename T>
void Swap(T &value1, T &value2)
{
T tmp = value1;
value1 = value2;
value2 = tmp;
}
template <typename T>
T Sum(const T &arr[], int start = 0, int count = -1)
{
if (!ArrayCheckRange(arr, start, count))
return((T)NULL);
T sum = (T)NULL;
for (int i = start, end = start + count; i < end; i++)
sum += arr[i];
return(sum);
}
int GetPointDigits(const double point)
{
if (point == 0)
return(_Digits);
return(GetPointDigits(point, _Digits));
}
int GetPointDigits(const double point, const int maxDigits)
{
if (point == 0)
return(maxDigits);
string pointString = DoubleToCompactString(point, maxDigits);
int pointStringLen = StringLen(pointString);
int dotPos = StringFind(pointString, ".");
return(dotPos < 0
? StringLen(TrimRight(pointString, '0')) - pointStringLen
: pointStringLen - dotPos - 1);
}
template <typename T>
int ArrayMax(const T &array[], const int start = 0, const int count = WHOLE_ARRAY)
{
return(ArrayMaximum(array, start, count));
}
int HgModes(const double &values[], const int modeStep, int &modes[])
{
int modeCount = 0;
ArrayFree(modes);
for (int i = modeStep, count = ArraySize(values) - modeStep; i < count; i++)
{
int maxFrom = i - modeStep;
int maxRange = 2 * modeStep + 1;
int maxTo = maxFrom + maxRange - 1;
int k = ArrayMax(values, maxFrom, maxRange);
if (k != i)
continue;
for (int j = i - modeStep; j <= i + modeStep; j++)
{
if (values[j] != values[k])
continue;
modeCount++;
ArrayResize(modes, modeCount, count);
modes[modeCount - 1] = j;
}
}
return(modeCount);
}
int HgVwap(const double &volumes[], const double low, const double step)
{
if (step == 0)
return(-1);
double vwap = 0;
double totalVolume = 0;
int size = ArraySize(volumes);
for (int i = 0; i < size; i++)
{
double price = low + i * step;
double volume = volumes[i];
vwap += price * volume;
totalVolume += volume;
}
if (totalVolume == 0)
return(-1);
vwap /= totalVolume;
return((int)((vwap - low) / step + 0.5));
}
int _iBarShift(string symbol, ENUM_TIMEFRAMES timeframe, datetime time, bool exact = false)
{
if (time < 0)
return(-1);
datetime arr[];
datetime time1;
CopyTime(symbol, timeframe, 0, 1, arr);
time1 = arr[0];
if (CopyTime(symbol, timeframe, time, time1, arr) <= 0)
return(-1);
if (ArraySize(arr) > 2)
return(ArraySize(arr) - 1);
return(time < time1 ? 1 : 0);
}
datetime _iTime(string symbol, ENUM_TIMEFRAMES timeframe, int index)
{
if (index < 0)
return(-1);
datetime arr[];
if (CopyTime(symbol, timeframe, index, 1, arr)<= 0)
return(-1);
return(arr[0]);
}
int WindowBarsPerChart()
{
return((int)ChartGetInteger(0, CHART_WIDTH_IN_BARS));
}
int WindowFirstVisibleBar()
{
return((int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR));
}
int GetHgByTicks(const datetime timeFrom, const datetime timeTo, const double point, const ENUM_TIMEFRAMES dataPeriod, const ENUM_APPLIED_VOLUME appliedVolume, double &low, double &volumes[])
{
long tickVolumes[];
int tickVolumeCount = CopyTickVolume(_Symbol, dataPeriod, timeFrom, timeTo, tickVolumes);
if (tickVolumeCount <= 0)
return(0);
long tickVolumesTotal = Sum(tickVolumes);
MqlTick ticks[];
int tickCount = CopyTicks(_Symbol, ticks, COPY_TICKS_TRADE, timeFrom * 1000, (uint)tickVolumesTotal);
if (tickCount <= 0)
{
return(0);
}
MqlTick tick = ticks[0];
low = NORM_PRICE(tick.last, point);
double high = low;
long timeToMs = timeTo * 1000;
for (int i = 1; i < tickCount; i++)
{
tick = ticks[i];
if (tick.time_msc > timeToMs)
{
tickCount = i;
break;
}
double tickLast = NORM_PRICE(tick.last, point);
if (tickLast < low)
low = tickLast;
if (tickLast > high)
high = tickLast;
}
int lowIndex = ROUND_PRICE(low, point);
int highIndex = ROUND_PRICE(high, point);
int hgSize = highIndex - lowIndex + 1; // ���������� ��� � �����������
ArrayResize(volumes, hgSize);
ArrayInitialize(volumes, 0);
int pri;
for (int j = 0; j < tickCount; j++)
{
tick = ticks[j];
pri = ROUND_PRICE(tick.last, point) - lowIndex;
volumes[pri] += (appliedVolume == VOLUME_REAL) ? (double)tick.volume : 1;
}
return(hgSize);
}
int GetHg(const datetime timeFrom, const datetime timeTo, const double point, const ENUM_TIMEFRAMES dataPeriod, const ENUM_APPLIED_VOLUME appliedVolume, double &low, double &volumes[])
{
MqlRates rates[];
int rateCount = CopyRates(_Symbol, dataPeriod, timeFrom, timeTo, rates);
if (rateCount <= 0)
return(0);
MqlRates rate = rates[0];
low = NORM_PRICE(rate.low, point);
double high = NORM_PRICE(rate.high, point);
for (int i = 1; i < rateCount; i++)
{
rate = rates[i];
double rateHigh = NORM_PRICE(rate.high, point);
double rateLow = NORM_PRICE(rate.low, point);
if (rateLow < low)
low = rateLow;
if (rateHigh > high)
high = rateHigh;
}
int lowIndex = ROUND_PRICE(low, point);
int highIndex = ROUND_PRICE(high, point);
int hgSize = highIndex - lowIndex + 1; // ���������� ��� � �����������
ArrayResize(volumes, hgSize);
ArrayInitialize(volumes, 0);
int pri, oi, hi, li, ci;
double dv, v;
for (int j = 0; j < rateCount; j++)
{
rate = rates[j];
oi = ROUND_PRICE(rate.open, point) - lowIndex;
hi = ROUND_PRICE(rate.high, point) - lowIndex;
li = ROUND_PRICE(rate.low, point) - lowIndex;
ci = ROUND_PRICE(rate.close, point) - lowIndex;
v = (appliedVolume == VOLUME_REAL) ? (double)rate.real_volume : (double)rate.tick_volume;
if (ci >= oi)
{
/* ����� ����� */
dv = v / (oi - li + hi - li + hi - ci + 1.0);
for (pri = oi; pri >= li; pri--)
volumes[pri] += dv;
for (pri = li + 1; pri <= hi; pri++)
volumes[pri] += dv;
for (pri = hi - 1; pri >= ci; pri--)
volumes[pri] += dv;
}
else
{
/* �������� ����� */
dv = v / (hi - oi + hi - li + ci - li + 1.0);
for (pri = oi; pri <= hi; pri++)
volumes[pri] += dv;
for (pri = hi - 1; pri >= li; pri--)
volumes[pri] += dv;
for (pri = li + 1; pri <= ci; pri++)
volumes[pri] += dv;
}
}
return(hgSize);
}
datetime GetHorizon(ENUM_VP_SOURCE dataSource, ENUM_TIMEFRAMES daПоказано первые 50% кода (символов: 30517)
Открыть по тарифу
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
Разовая покупка файла
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.