Привет всем :-H
Пишу советник, столкнулся с проблемой... ~x(
Мне нужно добавить условие для открытия сделки. Необходимо, чтобы предыдущий бар был закрыт внутри канала, или же, чтобы и Open и Close были внутри канала.
Наверное, для этого можно задать какую-нибудь функцию, например, PriceInChannel(), которая бы возвращала true or false, и проверять эту функцию в условии открытия ордера.
Но я не знаю, как сделать проверку предыдущего бара на предмет его нахождения в канале...
Подскажите пожалуйста, я знаю, здесь много программистов, кто бы эту задачу за две минуты решил :)
Обучение языку MQL4 под MetaTrader 4📌
От xbms, 13 апреля, 2013 в Уголок Программиста
Индюк оповещает Алертом - сова его не увидит. Нужно в индюке создать ещё 1 буфер и писать в него циферки (любые). Например:
Скажите пожалуйста. Если в индюке выполняется условие...
Возможно ли по этим условиям открыть ордера
Если (условие_Бай) { Алерт("бай"); буф5[nBar] = 33; }
Для Селла аналогично, а в сове вызвать этот буф5 и если там 33 - покупать.
Все бары пронумерованы. Вот как Вы определяете, что цена вышла из канала? Например:
Необходимо, чтобы предыдущий бар был закрыт внутри канала, или же, чтобы и Open и Close были внутри канала.... я не знаю, как сделать проверку предыдущего бара на предмет его нахождения в канале...
if (Close[1] > МойКанал_Хай && Close[2]
На одном тике будет открываться много ордеров Бай не сразу, а немного погодя, когда история забьётся сделками...
У Вас очень странный торговый алгоритм (имхо)
- Сова торгует только Бай (в Селл только если есть закрытые Селл - а откуда им взяться?)
- Количество открываемых ордеров будет расти в прогрессии от количества закрываемых ордеров.
Я Вам советую торговать не на выход из канала, а на обратный вход - рисков меньше.
в другой ветке уже писал как примерно описать условия
Разработка программ включает постановку задачи, написание техзадания, алгоритмирование, кодирование (что новички часто и считают программированием), отладку и комплексное (финальное) тестирование.
Все это делается письменно, начиная с составления плана всех этапов работ и завершая разработкой набора тестов для проверки ПО и сдачи ПО заказчику и/или вводу в эксплуатацию.
В серьезных проектах (типа космоса), да и в серьезных программистских фирмах каждый этап работ может выполняться разными группами спецов.
Попробуйте понять что именно вы не сделали как надо и что надо сделать для достижения поставленных вами целей.
Ага, спасибо большое) просто не знал, как называется функция такая...
Еще вопрос небольшой...
Допустим, я хочу, чтобы мой советник работал с 8 до 12 и с 16 до 20, в остальное время позиции открывать запрещено.
Можно ли сделать так:
int tradehours = false;
int Hour();
if (Hour() == 8 || Hour() == 9 || Hour() == 10 || Hour() == 11)
{
tradehours=true
Return (tradehours);
}
А потом в условие открытия ордера добавить, чтобы tradehours == true
правда так оптимизировать не совсем удобно, хоть и tradehours можно вынести extern-ом
да и думаю, что сделать это можно гораздо проще
Куча сов с открытым кодом (в том числе здесь) - смотрите.
Имхо проверку времени надо делать на входе (по приходу тика), а не в блоке условий открытия ордера.
напишите хотя-бы так:
if ((Hour() >= 8 && Hour() = 16 && Hour()
Изменено 9 августа, 2014 пользователем 0ll
ЦитатаВсе бары пронумерованы. Вот как Вы определяете, что цена вышла из канала? Например:
if (Close[1] > МойКанал_Хай && Close[2]
Попробовал так сделать, получилось вот что :
Я не понимаю, как он закрывает ордер с убытком 15 пунктов, если цена до туда даже не дошла...
_http://uploads.ru/onOGl.jpg
Может в спреде - Селл закрывают по Аску, а свеча рисуется по Биду.
Я не понимаю, как он закрывает ордер с убытком 15 пунктов, если цена до туда даже не дошла..
Мониторинг по системе _http://www.myfxbook.com/members/mexicanoeso/tradefort/904097
Все сделки на мониторинге открывал вручную. 9-го мая получил убыток, потому что не успел выставить отложку на продажу по EURUSD.
Прошу программистов написать простой советник сопровождения ордеров, открытых вручную.
Первое колено открывается вручную, советник выставляет для первого колена тейк-профит х-пунктов и стоп-лосс y-пунктов.
Если первое колено на покупку, то выставляется отложенный ордер селл-стоп ниже открытия первого колена. Расстояние между первым коленом и отложенным селл-стоп ордером z-пунктов. Выставляются для отложенного селл-стоп ордера тейк-профит х-пунктов и стоп-лосс y-пунктов.
Когда сработает селл-стоп ордер, то выставляется отложенный ордер бай-стоп выше открытия второго колена. Расстояние между вторым коленом и отложенным бай-стоп ордером z-пунктов. Выставляются для отложенного бай-стоп ордера тейк-профит х-пунктов и стоп-лосс y-пунктов.
Когда сработает бай-стоп ордер, то выставляется отложенный ордер селл-стоп ниже открытия третьего колена. Расстояние между третьим коленом и отложенным селл-стоп ордером z-пунктов. Выставляются для отложенного селл-стоп ордера тейк-профит х-пунктов и стоп-лосс y-пунктов.
После срабатывания отложенного селл-стоп ордера, новые отложенные ордера не выставляются, т.е. ждем закрытия всех четырех колен.
------------------------------------------------------------------
Если открывается вручную первое колено на продажу, то все зеркально. Советник выставляет для первого колена тейк-профит х-пунктов и стоп-лосс y-пунктов.
Если первое колено на продажу, то выставляется отложенный ордер бай-стоп выше открытия первого колена. Расстояние между первым коленом и отложенным бай-стоп ордером z-пунктов. Выставляются для отложенного бай-стоп ордера тейк-профит х-пунктов и стоп-лосс y-пунктов.
Когда сработает бай-стоп ордер, то выставляется отложенный ордер селл-стоп ниже открытия второго колена. Расстояние между вторым коленом и отложенным селл-стоп ордером z-пунктов. Выставляются для отложенного селл-стоп ордера тейк-профит х-пунктов и стоп-лосс y-пунктов.
Когда сработает селл-стоп ордер, то выставляется отложенный ордер бай-стоп выше открытия третьего колена. Расстояние между третьим коленом и отложенным бай-стоп ордером z-пунктов. Выставляются для отложенного бай-стоп ордера тейк-профит х-пунктов и стоп-лосс y-пунктов.
После срабатывания отложенного бай-стоп ордера, новые отложенные ордера не выставляются, т.е. ждем закрытия всех четырех колен.
---------------------------------------------------------------------
Если первое колено на покупку закрылось по тейк-профиту, то удаляется отложка селл-стоп.
Если пирамида из двух колен и первое колено закрылось по стоп-лоссу, а второе колено закрылось по тейк-профиту(имеем прибыль пирамиды, состоящей из двух колен), то удаляется отложка бай-стоп.
Если пирамида из трех колен и первое колено закрылось по тейк-профиту, второе колено закрылось по стоп-лоссу, третье колено закрылось по тейк-профиту(имеем прибыль пирамиды, состоящей из трёх колен), то удаляется отложка селл-стоп.
Если пирамида из четырех колен и первое колено закрылось по стоп-лоссу, второе колено закрылось по тейк-профиту, третье колено закрылось по стоп-лоссу, четвертое колено закрылось по тейк-профиту - то получаем прибыль.
Если первое колено на продажу закрылось по тейк-профиту, то удаляется отложка бай-стоп. Далее зеркально.
-----------------------------------------------------------------------
Входные параметры:
(Значения ТП и СЛ в старых пунктах)
Первое колено - тейк-профит х-пунктов
стоп-лосс y-пунктов
Размер лота для первого колена: лотов
Второе колено - тейк-профит х-пунктов
стоп-лосс y-пунктов
Размер лота для второго колена: лотов
Третье колено - тейк-профит х-пунктов
стоп-лосс y-пунктов
Размер лота для третьего колена: лотов
Четвертое колено - тейк-профит х-пунктов
стоп-лосс y-пунктов
Размер лота для четвертого колена: лотов
Расстояние между ордерами: z-пунктов
Магический номер:
Перевод в безубыток пирамиды, состоящей из трёх колен: включено/выключено
Тейк-профит в пунктах пирамиды, состоящей из трёх колен при включенном безубытке: n-пунктов
(Например, первое колено на покупку ТП=40 пп, СЛ=200 пп, второе колено на продажу ТП=100 пп, СЛ=140 пп, третье колено на покупку ТП=40, СЛ=200 - значения ТП и СЛ ордеров при переводе в безубыток)
Перевод в безубыток пирамиды, состоящей из четырёх колен: включено/выключено
Тейк-профит в пунктах пирамиды, состоящей из четырёх колен при включенном безубытке: n-пунктов
(Например, первое колено на покупку ТП=100 пп, СЛ=140 пп, второе колено на продажу ТП=40 пп, СЛ=200 пп, третье колено на покупку ТП=100, СЛ=140, четвёртое колено на продажу ТП=40 пп, СЛ=200 пп - значения ТП и СЛ ордеров при переводе в безубыток)
--------------------------------------------------------------------------
Советник должен работать на 4-х и 5-ти значных котировках. Возможность строить пирамиды на многих валютных парах. Работать на счетах с исполнением Instant Execution и Market Execution.
Изменено 11 августа, 2014 пользователем mexicanoeso
Ага, да, спред текущий в субботу стоял, не учел...
Но Правда, это мало чем помогло :(
При срабатывании профита, открывает кучу разнонаправленных ордеров и тут же закрывает их...
Да и Close[1] не работает почему-то...
http://uploads.ru/xEC6Q.jpg
http://uploads.ru/BbgYA.jpg
http://uploads.ru/ObHB7.jpg
http://uploads.ru/lp5nH.jpg
Не знаю, где я накосячил...
//Parameters of expert
extern int TakeProfit = 20;
extern int StopLoss = 15;
extern double Lot = 0.1;
extern int Slippage = 5;
extern int Magic = 123;
extern string indi = "Parameters of expert";
extern int HalfLength = 48;
extern int PRICE_MODE = 0;
extern int ATR_PERIOD = 100;
extern double K = 2.0;
double PH, PL, SL, TP;
int ticket;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int init()
{
if (Digits == 3 || Digits == 5)
{
TakeProfit *= 10;
StopLoss *= 10;
Slippage *= 10;
}
return(0);
}
//------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Expert start function |
//+------------------------------------------------------------------+
int start()
{
PH = iCustom (Symbol(), 0, "KC", HalfLength, PRICE_MODE, ATR_PERIOD, K, 0, 0);
PL = iCustom (Symbol(), 0, "KC", HalfLength, PRICE_MODE, ATR_PERIOD, K, 2, 0);
if (Bid >= PH && Close[1] = PL && CountSell() == 0)
{
SL = NormalizeDouble(Bid + StopLoss*Point, Digits);
TP = NormalizeDouble(Bid - TakeProfit*Point, Digits);
ticket = OrderSend(Symbol(), OP_SELL, Lot, Bid, Slippage, 0, 0, "", Magic, 0, Red);
if (ticket > 0)
{
if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES) == true)
bool modify1 = OrderModify(ticket, OrderOpenPrice(), SL, TP, 0);
}
}
if (Ask = PL && Close[1] {
SL = NormalizeDouble(Ask - SL*Point, Digits);
TP = NormalizeDouble(Ask + TP*Point, Digits);
ticket = OrderSend(Symbol(), OP_BUY, Lot, Ask, Slippage, 0, 0, "", Magic, 0, Green);
if (ticket > 0)
{
if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)== true)
bool modify2 =OrderModify(ticket, OrderOpenPrice(), SL, TP, 0);
}
}
return(0);
}
//-----------------------------------------------
int CountSell()
{
int count = 0;
for (int trade = OrdersTotal()-1; trade>=0; trade--)
{
bool select1 = OrderSelect(trade, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if (OrderType() == OP_SELL)
count++;
}
}
return(count);
}
int CountBuy()
{
int count = 0;
for (int trade = OrdersTotal()-1; trade>=0; trade--)
{
bool select2 = OrderSelect(trade, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if (OrderType() == OP_BUY)
count++;
}
}
return(count);
}
Имхо - лишний параметр. ;)
Первое колено открывается вручную...
-----------------------------------------------------------------------
Входные параметры:
Первое колено - тейк-профит х-пунктов
стоп-лосс y-пунктов
Размер лота для первого колена: лотов
индикаторы КС бывают разные. У меня 2 шт. и номера буферов не совпадают...
номер буфера Хай бывает и 0, и 1... - разберитесь
Я бы всё-таки брал значение индикатора с 1 бара:
вместо PH = iCustom (..., 0); - ..., 1); (может тогда и Close[1] заработает)
Из этого условия:
if (Bid >= PH && Close[1] = PL && CountSell() == 0)
Сделайте два (так будет правильно):
if (CountSell() == 0) {
if (Bid >= PH && Close[1] = PL) {
...
Перенесите Ваш код в шаблон эксперта под 670 билд, функции должны называться: OnInit() вместо init() и OnTick() вместо start(). (может тогда СЛ будет не 15 пипс)
Отбой, в этом курсе это есть.
Изменено 10 августа, 2014 пользователем Salov Nikolay
Судя по всему, индекс верный
SetIndexBuffer(0,upper);
SetIndexBuffer(2,lower);
http://uploads.ru/8VTcl.jpg
На новый шаблон перенес, но снова эти дерганья на месте, где должен открыться бай... около 300 позиций открываются и закрываются на одной свече после него...
//+------------------------------------------------------------------+
//| #TMA+CHANNEL_END_POINT.mq4 |
//| by Sohocool |
////////////////////// April 2012
//| Copyright © 2012, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2012, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net"
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Blue
#property indicator_color2 Blue
#property indicator_color3 Blue
double upper[], middle[], lower[];
extern int HalfLength = 48;
//extern int MA_MODE = 0;
extern int PRICE_MODE = 0;
extern int ATR_PERIOD = 100;
extern double K = 2.0;
//extern bool ATR_MODE = false;
int init()
{
SetIndexStyle(0,DRAW_LINE);
SetIndexShift(0,0);
SetIndexDrawBegin(0,0);
SetIndexBuffer(0,upper);
SetIndexStyle(1,DRAW_LINE,STYLE_DOT);
SetIndexShift(1,0);
SetIndexDrawBegin(1,0);
SetIndexBuffer(1,middle);
SetIndexStyle(2,DRAW_LINE);
SetIndexShift(2,0);
SetIndexDrawBegin(2,0);
SetIndexBuffer(2,lower);
//---- indicators
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//---- TODO: add your code here
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start() {
int limit;
int counted_bars=IndicatorCounted();
if(counted_bars if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
double avg;
for(int x=0; x
middle[x] = iMA(NULL, 0, HalfLength+1 , 0, 3, PRICE_MODE, x);
// if (ATR_MODE)
avg = iATR(NULL,0,ATR_PERIOD, x+10);
// else
// avg = findAvg(ATR_PERIOD, x);
upper[x] = middle[x] + K*avg;
lower[x] = middle[x] - K*avg;
}
return(0);
}
Ощущение, что что-то не так с функцией CountBuy()
Просто сначала метаэдитор требовал вернуть значение, ну я и поставил bool, чтобы возвращал обратно, но может из за этого что-то не так...
//+------------------------------------------------------------------+
//| KCexpert1 3.mq4 |
//| Copyright 2014, Oleg Novinsky. |
//| |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, Oleg Novinsky."
#property link ""
#property version "1.00"
#property strict
//Parameters of expert
extern int TakeProfit = 20;
extern int StopLoss = 15;
extern double Lot = 0.1;
extern int Slippage = 5;
extern int Magic = 123;
extern string indi = "Parameters of expert";
extern int HalfLength = 48;
extern int PRICE_MODE = 0;
extern int ATR_PERIOD = 100;
extern double K = 2.0;
double PH, PL, SL, TP;
int ticket;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if (Digits == 3 || Digits == 5)
{
TakeProfit *= 10;
StopLoss *= 10;
Slippage *= 10;
}
return(0);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
PH = iCustom (Symbol(), 0, "KC", HalfLength, PRICE_MODE, ATR_PERIOD, K, 0, 1);
PL = iCustom (Symbol(), 0, "KC", HalfLength, PRICE_MODE, ATR_PERIOD, K, 2, 1);
if (Bid >= PH && Close[1] = PL && CountSell() == 0)
{
SL = NormalizeDouble(Bid + StopLoss*Point, Digits);
TP = NormalizeDouble(Bid - TakeProfit*Point, Digits);
ticket = OrderSend(Symbol(), OP_SELL, Lot, Bid, Slippage, 0, 0, "", Magic, 0, Red);
if (ticket > 0)
{
if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES) == true)
bool modify1 = OrderModify(ticket, OrderOpenPrice(), SL, TP, 0);
}
}
if (Ask = PL && Close[1] {
SL = NormalizeDouble(Ask - SL*Point, Digits);
TP = NormalizeDouble(Ask + TP*Point, Digits);
ticket = OrderSend(Symbol(), OP_BUY, Lot, Ask, Slippage, 0, 0, "", Magic, 0, Green);
if (ticket > 0)
{
if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)== true)
bool modify2 =OrderModify(ticket, OrderOpenPrice(), SL, TP, 0);
}
}
}
//-----------------------------------------------
int CountSell()
{
int count = 0;
for (int trade = OrdersTotal()-1; trade>=0; trade--)
{
bool select1 = OrderSelect(trade, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if (OrderType() == OP_SELL)
count++;
}
}
return(count);
}
int CountBuy()
{
int count = 0;
for (int trade = OrdersTotal()-1; trade>=0; trade--)
{
bool select2 = OrderSelect(trade, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if (OrderType() == OP_BUY)
count++;
}
}
return(count);
}
//+------------------------------------------------------------------+
с функцией CountBuy() всё нормально - ведь новый ордер открывается после закрытия предыдущего.
Ордера открываются строго по системе, а причина закрытия этих ордеров какая?, в журнале смотрели?
Глянул в журнал - еще непонятнее стало...
Селл-ордера он модифицирует нормально, стоп - 15 пунктов, тейк - 20
А вот бай-ордера он модифицирует криво, ставит стопы и тейки на 2 пункта выше и ниже текущей цены.
Не может же он для цены бид расчитывать эти 15 и 20 пунктов нормально, а для аск как по пятизнаку - 1,5 и 2 пункта...
Но ради интереса поставил 150 и 200 пунктов в настройках - у селла 150 и 200 пунктов как положено стало, с баем то же самое - +/- 2 пункта
http://uploads.ru/tXkAl.jpg
http://uploads.ru/7cxeT.jpg
Глянул в журнал - еще непонятнее стало...
Найдите 2 отличия и станет понятно...
SL = NormalizeDouble(Bid + StopLoss*Point, Digits);
TP = NormalizeDouble(Bid - TakeProfit*Point, Digits);
SL = NormalizeDouble(Ask - SL*Point, Digits);
TP = NormalizeDouble(Ask + TP*Point, Digits);
Сам тоже не досмотрел
Точно)))
Вот что бывает, когда сначала называешь переменную одним именем, а потом передумываешь)
Спасибо) Пойду доделывать все остальное \M/
Разработка программ включает постановку задачи, написание техзадания, алгоритмирование, кодирование (что новички часто и считают программированием), отладку и комплексное (финальное) тестирование.
Все это делается письменно, начиная с составления плана всех этапов работ и завершая разработкой набора тестов для проверки ПО и сдачи ПО заказчику и/или вводу в эксплуатацию.
В серьезных проектах (типа космоса), да и в серьезных программистских фирмах каждый этап работ может выполняться разными группами спецов.
Я же не советник заказываю.
Поставленная цель - это научится писать программу.
А вот почему счетчик не считает, не понятно,потому как логически все правильно.
Вы какой счётчик имеете в виду? Напишите толком - что наблюдаете, как по Вашему должно быть, что в журнале сов пишет.
А вот почему счетчик не считает, не понятно,потому как логически все правильно.
Вы какой счётчик имеете в виду? Напишите толком - что наблюдаете, как по Вашему должно быть, что в журнале сов пишет.
Советник работает так: открывает ордер на покупку, если ордер закрывается по тайк профиту, то следующую позицию открывает в ту же сторону, но если ордер закрывается по стопу, то он открывает следующий ордер в противоположную сторону.
Хочу добавить мартина, но чтоб он открывал ордер не только с увеличенным объемом, но и увеличивал тайк профит и стоп лосс.
Коэффициенты увеличения вынести во внешнии параметры, коэф. объема, коэф. тайк профита и коэф. стоп лосса.
Счетчик необходим для того чтобы он определял не благоприятный для торговли день и ограничивал потери т.к. есть мартин. Т.е. в случае достижения определенного количества ордеров закрытых по стоп лоссу, он прекращает работу до начала следующего дня.
Счетчик должен считать количество подряд закрытых ордеров по стоп лоссу (количество ордеров тоже определяется во внешних параметрах) т.е. при достижении этого количества он прекращает работу на сегодня. Счетчик должен сбрасываться в начале каждого
дня, либо при положительно закрытым ордером (т.к. мартин тоже начнет работу сначала)
Пример. выставляем ограничение в три отрицательно закрытых ордера. Два ордера подряд закрылись по стопу, но третий закрывается по тайк профиту и счетчик сбрасывается, если же и третий ордер закрывается по стопу, то счетчик останавливает работу советника до наступления следующего дня и при наступлении нового дня он сбрасывается, тем самым разрешая сове работать.
Вот вроде как то так он должен работать.
Т.е. закрытые ордера надо ещё и по времени закрытия отсортировать? - хорошая задача для начинающих программистов!
Счетчик должен считать количество подряд закрытых ордеров по стоп лоссу
Чтобы у Вас не было неоправданных ожиданий - советник, описанный Вами, никому не интересен, нужен он Вам для расширения познаний в MQL, поэтому многого от меня не ждите - пробуйте, пишите сами, а мы будем подсказывать и поправлять (по мере возможности).
Удачи!
А как можно сделать, чтобы за один день не открывалось больше одного бая и одного селла?
Нужны 2 переменных - флага bool StopBuy = false, StopSell = false;
А как можно сделать, чтобы за один день не открывалось больше одного бая и одного селла?
В цикле перебора закрытых ордеров (истории), если сегодня есть сделка Бай, то СтопБай = труе.
Для публикации сообщений создайте учётную запись или авторизуйтесь
Перейти к списку тем