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

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

#401

Добрый день, Сергей!
У меня к вам прозьба посмотреть мое творение, что-то не получается. Хотел бы создать советник по Мартину. В 01:00 должен отрыться на Бай. Если Стоп Лосс то удваеваем ставку в 2 раза в том же направлении (открываем при косании стопа), если опять СЛ то в обратном направлении. Алгоритм таков - бай-бай-селл-селл-селл-бай-бай, затем повторяем. Я тут попробовал и у меня ставка в час ночи отрывается, но вот второй ордер нет... 100% что-то не связываю...
Заранее благодарю!

extern double Lots = 0.01;
extern int TakeProfit = 13;
extern int StopLoss = 13;
extern int Multipler = 2;
extern int Magic = 123;
extern int HourStart = 01;
extern int Step = 0;
extern int Slipage = 0;
extern string Coment = "Martin";

int ticket;
double price, TP, SL,TP1, SL1, pret1;

//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
if (Digits == 3 || Digits == 5)
{
TakeProfit *= 10;
StopLoss *= 10;
Step *= 10;
Slipage *= 10;
}

return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{

return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int CountBay()
{
int count = 0;
for(int trade = OrdersTotal() - 1; trade >= 0; trade--)
{
OrderSelect(trade, SELECT_BY_POS, MODE_TRADES);
if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
{
if(OrderType() == OP_BUY)
count++;
}
}
return(count);
}
//+------------------------------------------------------------------+
int start()
{
if (HourStart == TimeHour(TimeCurrent()) && CountBay() == 0)
{
SL = NormalizeDouble(Ask - StopLoss*Point, Digits);
TP = NormalizeDouble(Ask + StopLoss*Point, Digits);
OrderSend(Symbol(), OP_BUY, Lots, Ask, Slipage, SL, TP, Coment, Magic, 0, Blue);
if (pret1 == SL)
{
SL1 = NormalizeDouble(pret1 - StopLoss*Point, Digits);
TP1 = NormalizeDouble(pret1 + StopLoss*Point, Digits);
OrderSend(Symbol(), OP_BUY, Lots*2, pret1, Slipage, SL1, TP1, Coment, Magic, 0, Blue);
}
}
return(0);
}
//+------------------------------------------------------------------+

Автор#402

День добрый, Vladimir1_83!

Я что-то не уловил что это: :)

           if (pret1 == SL)
{
SL1 = NormalizeDouble(pret1 - StopLoss*Point, Digits);
TP1 = NormalizeDouble(pret1 + StopLoss*Point, Digits);
OrderSend(Symbol(), OP_BUY, Lots*2, pret1, Slipage, SL1, TP1, Coment, Magic, 0, Blue);
}


Тут Вам немного не так нужно делать...

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

Рекомендую написать алгоритм на бумаге или в блокноте, и как только почувствуете, что логика есть, то можно приступать, собственно, к написанию кода.
#403

решил свою проблему:


{
bool a = false;
bool b = false;

while(a != true)
{
a = OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(OrderOpenPrice() + first_level_BE*Point,Digits), OrderTakeProfit(), 0, CLR_NONE);
Sleep(2000);
}

if(first_close_part_of_lot>0)
{
while(b != true)
{
b = OrderClose(OrderTicket(), NormalizeDouble(OrderLots()*first_close_part_of_lot/100,2), Bid, slippage, Black);
Sleep(2000);
}
}
}

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

Изменено 16 октября, 2013 пользователем mzk_3om6u

#404

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

Вот, вот... имено это я и пытаюсь - проверить как был закрыт ордер. Я там подумал если pret1 (цена)= стоп лосу по предедущему ордеру то автоматом открываем второй по этой цене... но похоже что моя логига отличается немного от нормальной...

Поскажите каким инструментом можно проверять закрытия ордеров. Может пример есть от других скринов...
Спасибо!

#405


Поскажите каким инструментом можно проверять закрытия ордеров. Может пример есть от других скринов...
Спасибо!


OrderCloseTime();
OrderClosePrice();
OrderStopLoss();

Выбираешь ордер по закрытому времени > 0, и сравниваемый цену закрытия и стоплосс у ордера.( == )

Вперед к свершениям!)
#406


Я там подумал если pret1 (цена)= стоп лосу по предедущему ордеру то автоматом открываем второй по этой цене... но похоже что моя логига отличается немного от нормальной...


Переменной pret1 не присвоено значение.
Например, если написать:
 pret1 = Ask;
if (pret1 {
SL1 = NormalizeDouble(pret1 - StopLoss*Point, Digits);
TP1 = NormalizeDouble(pret1 + StopLoss*Point, Digits);
OrderSend(Symbol(), OP_BUY, Lots*2, pret1, Slipage, SL1, TP1, Coment, Magic, 0, Blue);
}

оно может быть и заработало бы, но не заработает..., потому что не пустят предыдущие условия.


Добавлено: 16-10-2013 08:17:34

mzk_3om6u

Можно поставить счетчик торговых попыток закрытия.
Или так:
Спойлер

double lots_close = NormalizeDouble(OrderLots()/(1-first_close_part_of_lot/100)*second_close_part_of_lot/100, 2);

if (lots_close >= MarketInfo(Symbol(), MODE_MINLOT))
{
if (OrderClose(OrderTicket(),lots_close, Bid, slippage, Black))
continue;

else
Print(....................)
Sleep(2*1000);
OrderClose(OrderTicket(), lots_close, Bid, slippage, Black);
}



Две попытки + проверка на минимальный лот.
И использовать Print(код ошибки, символ, тип, тикет, аск, бид, лот...)

Изменено 16 октября, 2013 пользователем Vorchunozavr

#407

HELP коллеги!
Я вот настрочил такое, но блин второй ордер не открывается (компиляция ошибок не выдает):
int start()
{
if (HourStart == TimeHour(TimeCurrent()) && CountBay() == 0)
{
SL1 = NormalizeDouble(Ask - StopLoss*Point, Digits);
TP1 = NormalizeDouble(Ask + StopLoss*Point, Digits);
ticket1 = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slipage, SL1, TP1, Coment, Magic, 0, Blue);
if (OrderSelect(ticket1, SELECT_BY_POS, MODE_TRADES) == true)
{
SL1=OrderClosePrice();

if (pret2 == SL1)
{
SL2 = NormalizeDouble(pret2 - StopLoss*Point, Digits);
TP2 = NormalizeDouble(pret2 + StopLoss*Point, Digits);
ticket2 = OrderSend(Symbol(), OP_BUY, Lots*2, pret2, Slipage, SL2, TP2, Coment, Magic, 0, Blue);
}

}
}
return(0);
}

Автор#408

Vladimir1_83, у меня всё-таки складывается ощущение, что Вы не совсем понимаете что пишете...

Давайте мы начнём с того, что Вы прокомментируете каждую строчку своего кода, а мы всем миром попробуем понять идею и поправить где и что не так...

#409

:d У меня складывается похожее мнение... Давайте попробуем:
{
if (HourStart == TimeHour(TimeCurrent()) && CountBay() == 0) - тут условия по открытию сделки в определенное время.
{
SL1 = NormalizeDouble(Ask - StopLoss*Point, Digits); - условия стоп лосса
TP1 = NormalizeDouble(Ask + StopLoss*Point, Digits); - условия тэйк профита
ticket1 = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slipage, SL1, TP1, Coment, Magic, 0, Blue); - открытия ордера (до этого момента все работает :) )
И начинается головоломка
if (OrderSelect(ticket1, SELECT_BY_POS, MODE_TRADES) == true) - выбираю ордер который отрылся.
{
SL1=OrderClosePrice(); И если у этого ордера цена закрытия равна стоп лосу

if (pret2 == SL1) И новая цена = стоп лосу, тогда задаю новые параметры для СЛ и ТП для нового ордера который должен открыться по цене pret2 тоесть по цене первого стоп лоса
{
SL2 = NormalizeDouble(pret2 - StopLoss*Point, Digits);
TP2 = NormalizeDouble(pret2 + StopLoss*Point, Digits);
ticket2 = OrderSend(Symbol(), OP_BUY, Lots*2, pret2, Slipage, SL2, TP2, Coment, Magic, 0, Blue);
}

}
}
return(0);
}

Реально я чего-то недапонимаю, и просмотрел все видео несколько раз... И уверен что это вообще не сложно... Вот так-то как-то...

Автор#410

Все верно, это не так сложно :)
Главное понять что и как.

Итак, прокомментирую я теперь что Вы тут написали...

Цитата

if (OrderSelect(ticket1, SELECT_BY_POS, MODE_TRADES) == true) - выбираю ордер который отрылся.


тут всё верно!

Цитата

SL1=OrderClosePrice(); И если у этого ордера цена закрытия равна стоп лосу


Присвоим SL1 цену, по которой ордер закрылся!
Однако, учитывая, что Вы его только что открыли, то вполне разумно предположить, что цена закрытия равна нулю.

Итак, как Вы понимаете, дальнейшие комментарии уже излишни по той простой причине, что код уже не рабочий.

Думаем дальше! ;)
#411


:d У меня складывается похожее мнение... Давайте попробуем:
{
if (HourStart == TimeHour(TimeCurrent()) && CountBay() == 0) - тут условия по открытию сделки в определенное время.
{
SL1 = NormalizeDouble(Ask - StopLoss*Point, Digits); - условия стоп лосса
TP1 = NormalizeDouble(Ask + StopLoss*Point, Digits); - условия тэйк профита
ticket1 = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slipage, SL1, TP1, Coment, Magic, 0, Blue); - открытия ордера (до этого момента все работает :) )
И начинается головоломка
if (OrderSelect(ticket1, SELECT_BY_POS, MODE_TRADES) == true) - выбираю ордер который отрылся.
{
SL1=OrderClosePrice(); И если у этого ордера цена закрытия равна стоп лосу

if (pret2 == SL1) И новая цена = стоп лосу, тогда задаю новые параметры для СЛ и ТП для нового ордера который должен открыться по цене pret2 тоесть по цене первого стоп лоса
{
SL2 = NormalizeDouble(pret2 - StopLoss*Point, Digits);
TP2 = NormalizeDouble(pret2 + StopLoss*Point, Digits);
ticket2 = OrderSend(Symbol(), OP_BUY, Lots*2, pret2, Slipage, SL2, TP2, Coment, Magic, 0, Blue);
}

}
}
return(0);
}

Реально я чего-то недапонимаю, и просмотрел все видео несколько раз... И уверен что это вообще не сложно... Вот так-то как-то...



Да если тебе надо цена закрытия то надо лесть в историю
if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
#412

Доброго времени суток,помогите с делом,надо дописать в функцию удаления ордеров что бы виртуальные то же обнулялись какой не сработал,а то у меня получается что,если в переменную передается цена и она там сохраняется до тех пор пока не откроет ордер по той цене,потом только обнулится.Мне нужно что бы когда удаляюся ордера и сразу обнулялось все.код прикладываю.

Test_21.mq414 скач.

Автор#413


Доброго времени суток,помогите с делом,надо дописать в функцию удаления ордеров что бы виртуальные то же обнулялись какой не сработал,а то у меня получается что,если в переменную передается цена и она там сохраняется до тех пор пока не откроет ордер по той цене,потом только обнулится.Мне нужно что бы когда удаляюся ордера и сразу обнулялось все.код прикладываю.



Привет!
для этого вполне достаточно написать код подсчёта кол-ва открытых ордеров... И если кол-во равно нулю, то... :)

P.S.: это ветка для обучения, а не для правок Вашего кода ;)
#414

не то

Изменено 19 октября, 2013 пользователем denis77515

Автор#415

Денис, а зачем что-то "корябать" без понимания?

ошибок тут и не может быть, в принципе...
код выдран с одного из моих уроков...
ну а то, что вы его дополнили бредом, то... ну даже не знаю что сказать :)

Денис, для начала напишите функцию подсчета количества ордеров... именно функцию, которая возвращает кол-во открытых ордеров.

#416

Сергей я сам вижу что последние это бред :d! Потому как нет условия и цикла.Не понимаю я, потому как набегами дома бываю.Ваши уроки пересматриваю,не было бы желания давно бы бросил это занятие.Можно и по другому поступить,заплатить деньги,и напишут какой надо код.Надеюсь вы согласны с этим. А по тому как интерес есть,вот и пишу всякий бред не ошибается тот кто не чего не делает !!! ~x( Вы бы создали урок или ли тему какую,где какой оператор применять например ( OrdersTotal , где и в каких случаях нужно его применять ) У вас есть if , for а об остальном не слова.Вот сижу и голаву ломаю что и как написать как посчитать и создать условие чего от куда взять ,и что с чем сравнить или сложить.Извените если грубавато написал,не в обиду.С уважением к вам !!!

Автор#417

Денис, вообще, предполагается, что ученики будут всё-таки пользоваться справочными материалами.
Стандартная справка в Метаедиторе вызывается по F1. Там всё и описано какая функция за что отвечает и что делает...

Я и сам постоянно пользуюсь справкой, ведь невозможно наизусть запомнить параметры всех функций...
А в справке всё чётко структурировано, загляните.


#418

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

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

Автор#419

ок, в одном из уроков мы писали функции: CountBuy(), CountSell(), CountTrades()...
Код можно взять из уроков.

После этого достаточно сделать так:


// если нет открытых ордеров
if (CountTrades() == 0)
{
//... то обнуляем тут переменные, и будет что-то типа:
sell_price = 0;
buy_price = 0;
}

ну вот как-то так :)
#420

Спасибо Сергей за наводку,хоть буду представлять от чего отталкиваться. Сегодня я однако этим заниматься не буду,так как (и правду мозги кипят) А завтра в командировку,и когда вернусь не известно.Вот так и получается обучение ,что не какое. Пока там торчишь забудешь что узнал сегодня.Вы уж простите меня чайника :d :d :d

#421


Денис, вообще, предполагается, что ученики будут всё-таки пользоваться справочными материалами.
Стандартная справка в Метаедиторе вызывается по F1. Там всё и описано какая функция за что отвечает и что делает...

Я и сам постоянно пользуюсь справкой, ведь невозможно наизусть запомнить параметры всех функций...
А в справке всё чётко структурировано, загляните.





Да документация это клёвое дело я только там и сижу!!! Я прочитал её как книгу несколько раз!!!
#422

Подскажите такую фишку в тестере, например у нас есть

void Sell_stop()
{
if(iClose(Symbol(), timeframe, shift) iRSI(Symbol(), timeframe, period_rsi, apply_rsi, shift) RSI_and_SMA(period_rsi, apply_rsi, period_sma, shift, timeframe) > iRSI(Symbol(), timeframe, period_rsi, apply_rsi, shift))
{
if(CountSellStop() == 0 && CountSell() ==0)
OrderSend(Symbol(), OP_SELLSTOP, lots, NormalizeDouble(iLow(Symbol(), timeframe, shift) - alpha*Point, Digits), slippage, 0, 0, NULL, Magic, 0, Red);
Sleep(1000);
}
}


есть timeframe = 0, то в тестере проходит как изначально поставленный график, а если ставить в тестере М1 и timeframe = 60, то получается не тест для часа а фигня какаято...Как сделать чтобы всё нормально было?)))
#423

Всем привет!


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



Если виртуальные ордера используются только потому, что не выставляется отложенный (от того, что цена стопового ордера слишком близко к рыночной), почему бы не открыться сразу по рынку. Зачем усложнять код? Тут можно напроситься на дополнительные ошибки:

Допустим, у нас БайСтоп не установился. Ставим виртуальный Бай. Цена погуляв вверх пунктов 100, возвращается, активирует наш Бай и благополучно уходит вниз...

Виртуальные, используют для того, чтобы прятать их от брокера, если существует уровень заморозки, или бороться с проскальзываниями.

#424

Ребята, в чем может быть проблема если при компиляции ошибок нет , а в тестере не открывает ордеров. В журнале пишет
TestGenerator: unmatched data error (low value 1.59356 at 2013.10.09 20:00 and price 1.59290 mismatched)

martin_1.mq414 скач.

#425


Ребята, в чем может быть проблема если при компиляции ошибок нет , а в тестере не открывает ордеров. В журнале пишет
TestGenerator: unmatched data error (low value 1.59356 at 2013.10.09 20:00 and price 1.59290 mismatched)



Проверь ещё раз глазом я сразу увидел ошибку в функции ModifyOrders(int otype)

double avgprice = 0,


Добавлено: 18-10-2013 20:23:26



Ребята, в чем может быть проблема если при компиляции ошибок нет , а в тестере не открывает ордеров. В журнале пишет
TestGenerator: unmatched data error (low value 1.59356 at 2013.10.09 20:00 and price 1.59290 mismatched)



Проверь ещё раз глазом я сразу увидел ошибку в функции ModifyOrders(int otype)

double avgprice = 0,



Логику не смотрел!!!

Изменено 19 октября, 2013 пользователем elruso

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

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