Лажа какая-то получилась. @-)
Пришел к выводу что все надо переписывать.
Обучение языку MQL4 под MetaTrader 4📌
От xbms, 13 апреля, 2013 в Уголок Программиста
oleguitar, не совсем понятно что вы имеете ввиду, если нужно подсчитать ордера Sell и SellStop, то в последнем условии нужно вместо и - (&&), поставить или - (||).
Я тоже не совсем понял, отложники в сове вроде бы не предусмотрены.
Подскажите пожалуйста почему ордера не открываются?
oleguitar, не совсем понятно что вы имеете ввиду, если нужно подсчитать ордера Sell и SellStop, то в последнем условии нужно вместо и - (&&), поставить или - (||).
Я тоже не совсем понял, отложники в сове вроде бы не предусмотрены.
Подскажите пожалуйста почему ордера не открываются?
С помощью советника, можно устанавливать любой тип ордеров, ведь суть-то такая, что мы просто перекладываем рутину на бота, соответственно он должен уметь всё, что можно сделать вручную, единственная проблема только - как ему всё объяснить. По вашему сообщению что-то не понимаю, ссылаетесь на чужое сообщение и ещё пишите вопрос по работе чужого бота, не думаю что вы работаете совместно?
Ребят, прохожу 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);
}
}
//+------------------------------------------------------------------+
В чем проблема - понять не смог. Найдите ошибку, кто может, пожалуйста=)
Попробуй так, вместо:
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);
Подробнее здесь написано. Удачи!
Oll, спасибо, помогло. Если можешь, объясни, что ему не понравилось в прошлом варианте. Важно понять это.
chistaia-rodina, открывает ордер, модифицирует(Sl, Tp), закрывает, открывает новый - больше не модифицирует, остальные также. Надеюсь, понятно=)
Если не ошибаюсь, то функция указана правильно, и пересчет ордеров там не нужен потому, что мы ссылаемся к ордеру по тикету. Вызвав функцию в цикле она ссылается на Sl и Tp, характерные для этого цикла. Проблемы быть не должно. К тому же изначально модификация одера вызывалась не отдельной функцией, проблема была та же=)
Если не прав, поправьте. Только начал обучение, многого не понимаю.
Подумал еще, понял, что пересчет ордеров не помешал бы, если функция будет использоваться еще, в других обстоятельствах, а в данном случае и без него можно=)
Изменено 6 сентября, 2014 пользователем stainsgate
Функция OrderSend() возвращает число (int) - номер тикета (я ссылку давал).
Oll, спасибо, помогло. Если можешь, объясни, что ему не понравилось в прошлом варианте. Важно понять это.
А Вы присваивали в (bool) который может быть 0 или 1 - вот у Вас только 1-ый тикет и отрабатывал.
Т.к. (bool) это тоже целое и его длина совпадает с (int) - ошибки не возникло...
chistaia-rodina, если я вас правильно понял, для этого в функции нужно указать не void тип данных, а, например, int. Далее произвести поиск ордеров через цикл for и сделать выборку по параметрам. Если не прав, поправьте.
На счет Sl и Tp, в циклах для Buy и для Sell сделок они рассчитываются немного по разному, и, как по мне, разницы большой в количестве текста не будет, будем ли мы ее ставить в расчете функции (тогда понадобится 2 функции для каждого типа сделок) или в цикле старт.
Суть не в том, что размер кода в функции и старте будет равносилен, главное по возможности не нагружать старт, так легче будет ориентироваться, особенно в больших кодах. К тому же, выписанная функция универсальна и её можно будет использовать в других кодах, просто скопировав.
Перечитал еще раз ваше сообщение. Если мы сохраняем тип void, то нам эту функцию необходимо будет прописать не внутри цикла по открытию сделки, а вне оного. Я вас правильно понял?
Ну вот так:
_________________________________________________
void OrderModify()
{
for и так далее, вся обработка внутри скобок
}
_________________________________________________
Прописываем всё отдельно в виде пользовательской функции.
В основном коде, напишем просто:
if (CountBuy() > 0 || CountSell() > 0)
OrderModify();
Изменено 6 сентября, 2014 пользователем chistaia-rodina
Да, это я понял. Я имел ввиду, вызов функции мы делаем уже не из цикла с открытием ордера(как это было раньше), а просто из старта?! Ну, в общем, я понял. Спасибо!=)
Попробуй этот вариант, пошаманил маненько, авось поможет
огромное человеческое спасибо! с понедельника начну.
Добавлено: 08-09-2014 05:50:35
Попробуй этот вариант, пошаманил маненько, авось поможет
не помогло,все тоже-самое.пока бай не откроется селл не открывается
Изменено 8 сентября, 2014 пользователем beketv1
Советник открывает ордера при каждом тике, как запретить?
Советник открывает ордера при каждом тике, как запретить?
Проводить предварительную проверку на наличие открытого ордера.
Всем привет!
Есть такой вопрос:
Я хочу, чтобы при выполнении условия на покупку или продажу открывался не один ордер, а два. Мне продублировать условия с разными мэджиками или как-то по-другому сделать можно?
Всем привет!
Есть такой вопрос:
Я хочу, чтобы при выполнении условия на покупку или продажу открывался не один ордер, а два. Мне продублировать условия с разными мэджиками или как-то по-другому сделать можно?
Сам конечно так ещё не делал, но думаю можно просто после успешного выполнения операции установки первого ордера, прописать ещё одну. На счёт разных мейджиков, это смотря что вы будете дальше с ними делать и какие проверки идут до установки ордеров.
Сделал с разными мэджиками, работает как нужно
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
Для меня в целом код с этими булевыми переменными выглядит слишком заморочено. Ну а так, раз уж ввели два мейджика, то и в подсчёте ордеров в рынке, нужно внести поправку, что ордер принадлежит к первому или второму.
По условию для удаления отложек, по идее надо сравнивать с ценой Bid, потому что стоп по рыночному ордеру сработал бы так и лучше поставить (
По самому удалению, я бы запустил цикл for и нашёл все BuyStop ордера, а затем удалил.
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());
}
}
Для публикации сообщений создайте учётную запись или авторизуйтесь
Перейти к списку тем