Обучение языку MQL4 под MetaTrader 4📌

От xbms, 13 апреля, 2013 в Уголок Программиста

#1276

Лажа какая-то получилась. @-)
Пришел к выводу что все надо переписывать.

#1277
oleguitar, не совсем понятно что вы имеете ввиду, если нужно подсчитать ордера Sell и SellStop, то в последнем условии нужно вместо и - (&&), поставить или - (||).
#1278


oleguitar, не совсем понятно что вы имеете ввиду, если нужно подсчитать ордера Sell и SellStop, то в последнем условии нужно вместо и - (&&), поставить или - (||).



Я тоже не совсем понял, отложники в сове вроде бы не предусмотрены.
Подскажите пожалуйста почему ордера не открываются?
#1279
Спойлер



oleguitar, не совсем понятно что вы имеете ввиду, если нужно подсчитать ордера Sell и SellStop, то в последнем условии нужно вместо и - (&&), поставить или - (||).



Я тоже не совсем понял, отложники в сове вроде бы не предусмотрены.
Подскажите пожалуйста почему ордера не открываются?


С помощью советника, можно устанавливать любой тип ордеров, ведь суть-то такая, что мы просто перекладываем рутину на бота, соответственно он должен уметь всё, что можно сделать вручную, единственная проблема только - как ему всё объяснить. По вашему сообщению что-то не понимаю, ссылаетесь на чужое сообщение и ещё пишите вопрос по работе чужого бота, не думаю что вы работаете совместно?
#1280

Ребят, прохожу 3й урок Сергея из курса и на данный момент столкнулся с проблемой:
Советник должен модифицировать открытые ордера после их заключения, но он модифицирует только первый ордер. В чем проблема - понять не смог. Найдите ошибку, кто может, пожалуйста=)

Вот код:

extern double Vol = 0.1;
extern int SL = 50;
extern int TP = 300;
extern int Slip = 5;
extern int Magic = 12345;
extern bool KanalClose = true;

extern string Par = "Параметры TMA";
extern string TimeFrame = "current time frame";
extern int HalfLength = 56;
extern int Price = PRICE_CLOSE;
extern double ATRMultiplier = 2.0;
extern int ATRPeriod = 100;
extern bool Interpolate = true;

double PriceHigh, PriceLow, Sl, Tp;
int ticket;

//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if (Digits == 3 || Digits == 5)
{
SL *= 10;
TP *= 10;
Slip *= 10;
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{


}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{

PriceHigh = iCustom (Symbol(), 0, "TMA with Distances", TimeFrame, HalfLength, Price, ATRMultiplier, ATRPeriod, Interpolate, 1, 0);
PriceLow = iCustom (Symbol(), 0, "TMA with Distances", TimeFrame, HalfLength, Price, ATRMultiplier, ATRPeriod, Interpolate, 2, 0);


if (Bid >= PriceHigh && CountOrder() == 0)
{
Sl = NormalizeDouble(Bid + SL*Point, Digits);
Tp = NormalizeDouble(Bid - TP*Point, Digits);
bool Send1 = OrderSend (Symbol(), OP_SELL, Vol, Bid, Slip, 0, 0, "", Magic, 0, clrDarkBlue);
ticket = Send1;
if (ticket > 0)
{
ModOrder();
}
}

if (Bid {
Sl = NormalizeDouble(Ask - SL*Point, Digits);
Tp = NormalizeDouble(Ask + TP*Point, Digits);
bool Send2 = OrderSend (Symbol(), OP_BUY, Vol, Ask, Slip, 0, 0, "", Magic, 0, clrRed);
ticket = Send2;
if (ticket > 0)
{
ModOrder();
}
}
if (KanalClose == true)
{
if (Bid 0)
{
CloseOrderSell();
}
if (Bid >= PriceHigh && CountBuy()>0)
{
CloseOrderBuy();
}
}
}
//+------------------------------------------------------------------+
int CountBuy()
{
int count = 0;
for (int trade = OrdersTotal()-1; trade>=0; trade --)
{
bool Select3 = OrderSelect (trade, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if (OrderType() == OP_BUY)
count++;
}
}
return(count);

}


//+------------------------------------------------------------------+
int CountSell()
{
int count = 0;
for(int trade = OrdersTotal() - 1; trade >=0; trade--)
{
bool Select4 = OrderSelect (trade, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if (OrderType() == OP_SELL)
count++;
}

}

return(count);
}
//+------------------------------------------------------------------+
void CloseOrderSell()
{
for (int trade = OrdersTotal() - 1; trade >=0; trade--)
{
bool Select5 = OrderSelect(trade, SELECT_BY_POS, MODE_TRADES);
if (Select5 == true)
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == OP_SELL)
{
bool Close1 = OrderClose (OrderTicket(), OrderLots(), Ask, Slip, clrDarkMagenta);
}
}
}
}
//+------------------------------------------------------------------+
void CloseOrderBuy()
{
for (int trade = OrdersTotal() - 1; trade >=0; trade--)
{
bool Select6 = OrderSelect(trade, SELECT_BY_POS, MODE_TRADES);
if (Select6 == true)
{
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic && OrderType() == OP_BUY)
{
bool Close2 = OrderClose (OrderTicket(), OrderLots(), Bid, Slip, clrDarkMagenta);
}
}
}
}
//+------------------------------------------------------------------+
int CountOrder()
{
int count = 0;
for(int trade = OrdersTotal() - 1; trade >=0; trade--)
{
bool Select7 = OrderSelect (trade, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
count++;
}

}

return(count);
}
//+------------------------------------------------------------------+
void ModOrder()
{
bool Select8 = OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES);
if(Select8 == true)
{
bool Modify = OrderModify (ticket, OrderOpenPrice(), Sl, Tp, 0, clrAqua);
}
}
//+------------------------------------------------------------------+

#1281
stainsgate, если уж вы решили сделать отдельную функцию по модификации, то нужно в ней же сделать цикл перебора ордеров и выбора по условиям. Там же разместить расчёт TP и SL по условиям. Вообще, что значит модифицирует только один, вроде же по условиям не предусмотрено усреднение?
#1282


В чем проблема - понять не смог. Найдите ошибку, кто может, пожалуйста=)


Попробуй так, вместо:
bool Send1 = OrderSend (Symbol(), OP_SELL, Vol, Bid, Slip, 0, 0, "", Magic, 0, clrDarkBlue);
ticket = Send1;
сделай:
ticket = OrderSend (Symbol(), OP_SELL, Vol, Bid, Slip, 0, 0, "", Magic, 0, clrDarkBlue);

Подробнее здесь написано. Удачи!
#1283

Oll, спасибо, помогло. Если можешь, объясни, что ему не понравилось в прошлом варианте. Важно понять это.

chistaia-rodina, открывает ордер, модифицирует(Sl, Tp), закрывает, открывает новый - больше не модифицирует, остальные также. Надеюсь, понятно=)
Если не ошибаюсь, то функция указана правильно, и пересчет ордеров там не нужен потому, что мы ссылаемся к ордеру по тикету. Вызвав функцию в цикле она ссылается на Sl и Tp, характерные для этого цикла. Проблемы быть не должно. К тому же изначально модификация одера вызывалась не отдельной функцией, проблема была та же=)
Если не прав, поправьте. Только начал обучение, многого не понимаю.

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

Изменено 6 сентября, 2014 пользователем stainsgate

#1284


Oll, спасибо, помогло. Если можешь, объясни, что ему не понравилось в прошлом варианте. Важно понять это.

Функция OrderSend() возвращает число (int) - номер тикета (я ссылку давал).
А Вы присваивали в (bool) который может быть 0 или 1 - вот у Вас только 1-ый тикет и отрабатывал.
Т.к. (bool) это тоже целое и его длина совпадает с (int) - ошибки не возникло...
#1285

Ясно. Спасибо. Это я понял.

Изменено 6 сентября, 2014 пользователем stainsgate

#1286
stainsgate, ну да правильно 0ll говорит, а то я что-то сразу и не присмотрелся к этому. По отдельной функции модификации, я бы наверное сделал так, прописал бы в старте ссылку к ней при наличии покупки или продажи и уже в ней перебор, потом проверка на тип и проверка наличия SL и TP, ну и потом если не установлены, то модификация. Функция будет проверяться на каждом тике при наличии ордеров и если по каким-то причинам не произойдёт установки сразу, то на следующем тике выставит. Также из основного кода будут убраны расчёты SL и TP.
#1287

chistaia-rodina, если я вас правильно понял, для этого в функции нужно указать не void тип данных, а, например, int. Далее произвести поиск ордеров через цикл for и сделать выборку по параметрам. Если не прав, поправьте.
На счет Sl и Tp, в циклах для Buy и для Sell сделок они рассчитываются немного по разному, и, как по мне, разницы большой в количестве текста не будет, будем ли мы ее ставить в расчете функции (тогда понадобится 2 функции для каждого типа сделок) или в цикле старт.

#1288
stainsgate, нет почему, как раз void и будет, нам же не надо из неё что-то получать, мы просто отсылаем к ней ордер на обработку. Ну да перебор через for, а далее можно сделать разветвление, если Buy одно, а если Sell то другое. Так же для расчёта TP и SL, будем отталкиваться от OrderOpenPrice, что в данном случае будет более правильно. Если что-то не получится, то в крайнем случае, можно в функции сделать цикл для каждого типа.

Суть не в том, что размер кода в функции и старте будет равносилен, главное по возможности не нагружать старт, так легче будет ориентироваться, особенно в больших кодах. К тому же, выписанная функция универсальна и её можно будет использовать в других кодах, просто скопировав.
#1289

Перечитал еще раз ваше сообщение. Если мы сохраняем тип void, то нам эту функцию необходимо будет прописать не внутри цикла по открытию сделки, а вне оного. Я вас правильно понял?

#1290

Ну вот так:
_________________________________________________
void OrderModify()
{
for и так далее, вся обработка внутри скобок

}
_________________________________________________

Прописываем всё отдельно в виде пользовательской функции.
В основном коде, напишем просто:

if (CountBuy() > 0 || CountSell() > 0)
OrderModify();

Изменено 6 сентября, 2014 пользователем chistaia-rodina

#1291

Да, это я понял. Я имел ввиду, вызов функции мы делаем уже не из цикла с открытием ордера(как это было раньше), а просто из старта?! Ну, в общем, я понял. Спасибо!=)

#1293

огромное человеческое спасибо! с понедельника начну.


Добавлено: 08-09-2014 05:50:35


Попробуй этот вариант, пошаманил маненько, авось поможет


не помогло,все тоже-самое.пока бай не откроется селл не открывается

Изменено 8 сентября, 2014 пользователем beketv1

#1294

Советник открывает ордера при каждом тике, как запретить?

#1295


Советник открывает ордера при каждом тике, как запретить?



Проводить предварительную проверку на наличие открытого ордера.
#1296

Всем привет!

Есть такой вопрос:
Я хочу, чтобы при выполнении условия на покупку или продажу открывался не один ордер, а два. Мне продублировать условия с разными мэджиками или как-то по-другому сделать можно?

#1297


Всем привет!

Есть такой вопрос:
Я хочу, чтобы при выполнении условия на покупку или продажу открывался не один ордер, а два. Мне продублировать условия с разными мэджиками или как-то по-другому сделать можно?



Сам конечно так ещё не делал, но думаю можно просто после успешного выполнения операции установки первого ордера, прописать ещё одну. На счёт разных мейджиков, это смотря что вы будете дальше с ними делать и какие проверки идут до установки ордеров.
#1298

Сделал с разными мэджиками, работает как нужно

Спойлер



if (мое условие)

{
SL = NormalizeDouble(low1 - StopLoss*Point, Digits);

openprice = NormalizeDouble(high1 + Indent*Point, Digits);
TP = NormalizeDouble(openprice + TakeProfit*Point, Digits);
TP1 = NormalizeDouble(openprice + TakeProfit1*Point, Digits);

ticket = OrderSend(Symbol(),OP_BUYSTOP, Lot, openprice, Slippage, 0, 0, "", Magic, 0, Red);

if (ticket > 0)
{
if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES) == true)
bool om1 = OrderModify(ticket, OrderOpenPrice(), SL, TP, 0);
}



ticket = OrderSend(Symbol(),OP_BUYSTOP, Lot, openprice, Slippage, 0, 0, "", Magic1, 0, Red);

if (ticket > 0)
{
if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES) == true)
bool om1 = OrderModify(ticket, OrderOpenPrice(), SL, TP1, 0);
}

}
//+------------------------------------------------------------------+


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 || OrderType() == OP_BUYSTOP)
count++;
}
}
return(count);
}



Но теперь наткнулся на другую проблему:
Мне нужно удалять отложки, если цена прошла уровень предполагаемого стоп-лосса, для этого написал вот такую функцию:

Спойлер


void CloseBuyStop()
{
if (CountBuy() != 0)
{
bool os = OrderSelect(ticket,SELECT_BY_TICKET);
bool od = OrderDelete(ticket, Red);
}
}



И перед основным условием торговли я написал вот такое:

Спойлер


if (Ask {
CloseBuyStop();
}



Первый ордер удаляется, а второй - нет
Решение пока что в голову не приходит

Изменено 12 сентября, 2014 пользователем oleguitar

#1299
oleguitar:

Для меня в целом код с этими булевыми переменными выглядит слишком заморочено. Ну а так, раз уж ввели два мейджика, то и в подсчёте ордеров в рынке, нужно внести поправку, что ордер принадлежит к первому или второму.

По условию для удаления отложек, по идее надо сравнивать с ценой Bid, потому что стоп по рыночному ордеру сработал бы так и лучше поставить (
По самому удалению, я бы запустил цикл for и нашёл все BuyStop ордера, а затем удалил.
#1300
oleguitar:
Спойлер


void CloseBuyStop() {
for (int i = OrdersTotal()-1; i >= 0; i--) {
if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if (!(OrderSymbol() == Symbol() && (OrderMagicNumber() == MAGIC1 || OrderMagicNumber() == MAGIC2))) continue;
if (OrderType() == OP_BUYSTOP) OrderDelete(OrderTicket());
}
}

Для публикации сообщений создайте учётную запись или авторизуйтесь

Перейти к списку тем
Форум · 2.0.20260627.0025