Возвращает индекс (порядковый номер в общем списке установленных ордеров или открытых позиций) ордера или позиции по тикету. Если функция IndexByTicket() не сможет найти ордер или позицию с нужным тикетом, то она вернёт -1. Ограничить перечень проверяемых ордеров или позиций можно параметрами функции:
sy - Наименование инструмента. Если задать этот параметр, то функция проверит ордера и позиции только заданного инструмента. NULL означает текущий инструмент, а "" (по умолчанию) - любой инструмент.
op - Торговая операция, тип отложенного ордера или позиции. Допустимые значения: OP_BUY, OP_BUYLIMIT, OP_BUYSTOP, OP_SELL, OP_SELLLIMIT, OP_SELLSTOP или -1. Значение по умолчанию -1 - означает любой ордер или позицию.
mn - Идентификатор ордера или позиции (MagicNumber). Значение по умолчанию -1 - любой магик.
//+----------------------------------------------------------------------------+//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |//+----------------------------------------------------------------------------+//| Версия : 20.04.2007 |//| Описание : Возвращает индекс ордера или позиции по тикету |//+----------------------------------------------------------------------------+//| Параметры: |//| ti - тикет ордера, позиции |//| sy - наименование инструмента ("" - любой символ, |//| NULL - текущий символ) |//| op - операция (-1 - любая позиция) |//| mn - MagicNumber (-1 - любой магик) |//+----------------------------------------------------------------------------+intIndexByTicket(intti, stringsy="", intop=-1, intmn=-1){inti, k=OrdersTotal();
if(sy=="0")sy=Symbol();
for(i=0; i<k; i++){if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)){if((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)){if((mn<0 || OrderMagicNumber()==mn) && OrderTicket()==ti)return(i);
}}}return(-1);
}
Функцию IndexByTicket() я писал в заказном советнике. Помню, что без неё никак не обойтись было, а иначе зачем бы я стал её писать? Но вот как она там использовалась, и зачем я её писал в принципе, убей не помню :-) Искать исходник советника влом. Их сотни.
Вообщем, приводить примеры на подобие тех, что я уже наприводил, не вижу смысла. Сообразительные сами догадаются, куда какие параметры "сувать". А если у кого-то возникнет хорошая идея использования функции IndexByTicket(), пишите сюда. Попробую реализовать.
Короткое объявление.
Функции SelectByTicket() и SelectByTicketFromHistory() я упразднил. Сам я их использовать больше не буду, поэтому не вижу смысла опубликовывать. Желающим подискутировать на эту тему всегда рад. Покажу все свои заблуждения AS IS.
Эта функция возвращает количество ордеров и функционально полностью перекрывает ExistOrders(). Для того, чтобы заменить функцию ExistOrders() функцией NumberOfOrders(), необходимо и достаточно проверять возвращаемое значение на то, чтобы оно было больше нуля. Ограничить перечень проверяемых ордеров можно параметрами функции:
sy - Наименование инструмента. Если задать этот параметр, то функция проверит ордера только заданного инструмента. NULL означает текущий инструмент, а "" (по умолчанию) - любой инструмент.
op - Тип отложенного ордера. Допустимые значения: OP_BUYLIMIT, OP_BUYSTOP, OP_SELLLIMIT, OP_SELLSTOP или -1. Значение по умолчанию -1 - означает любой ордер.
mn - Идентификатор ордера (MagicNumber). Значение по умолчанию -1 - любой магик.
//+----------------------------------------------------------------------------+//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |//+----------------------------------------------------------------------------+//| Версия : 28.11.2006 |//| Описание : Возвращает количество ордеров. |//+----------------------------------------------------------------------------+//| Параметры: |//| sy - наименование инструмента ("" - любой символ, |//| NULL - текущий символ) |//| op - операция (-1 - любой ордер) |//| mn - MagicNumber (-1 - любой магик) |//+----------------------------------------------------------------------------+intNumberOfOrders(stringsy="", intop=-1, intmn=-1){inti, k=OrdersTotal(), ko=0, ot;
if(sy=="0")sy=Symbol();
for(i=0; i<k; i++){if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)){ot=OrderType();
if(ot>1 && ot<6){if((OrderSymbol()==sy || sy=="") && (op<0 || ot==op)){if(mn<0 || OrderMagicNumber()==mn)ko++;
}}}}return(ko);
}
Эта функция возвращает количество ордеров и функционально полностью перекрывает ExistOrders(). Для того, чтобы заменить функцию ExistOrders() функцией NumberOfOrders(), необходимо и достаточно проверять возвращаемое значение на то, чтобы оно было больше нуля. Ограничить перечень проверяемых ордеров можно параметрами функции:
sy - Наименование инструмента. Если задать этот параметр, то функция проверит ордера только заданного инструмента. NULL означает текущий инструмент, а "" (по умолчанию) - любой инструмент.
op - Тип отложенного ордера. Допустимые значения: OP_BUYLIMIT, OP_BUYSTOP, OP_SELLLIMIT, OP_SELLSTOP или -1. Значение по умолчанию -1 - означает любой ордер.
mn - Идентификатор ордера (MagicNumber). Значение по умолчанию -1 - любой магик. еСО
Запутался я немного. Почему-то, мне видится некоторое противоречие. Вот здесь:
"...необходимо и достаточно проверять возвращаемое значение на то, чтобы оно было больше нуля."
Если проверять "это и только это", то функция на количество ордеров теряет смысл!
Я вот почему стал вникать. Вставил эту фукнцию в свой эксперт. Задал в параметрах m=1, и условие на открытие позиций -
if(NumberOfOrders("", -1, MagicNumber)<m){//если открытых позиций МЕНЬШЕ m
Но эксперт, словно, не видит этого ограничения! И открывает ордера по каждому сигналу ещё и ещё...
rid писал (а): Запутался я немного. Почему-то, мне видится некоторое противоречие. Вот здесь: "...необходимо и достаточно проверять возвращаемое значение на то, чтобы оно было больше нуля." Если проверять "это и только это", то функция на количество ордеров теряет смысл!
хм... Похоже, что Вы не обратили внимание на объём возвращаемой информации каждой из функций ExistOrders() и NumberOfOrders(). Функция ExistOrders() возвращает лишь информацию о существовании ордеров, а функция NumberOfOrders() возвращает информацию о количестве ордеров. Информация о количестве ордеров содержит в себе информацию о существовании ордеров. Когда нужно ответить на вопрос, есть ордер или нет, то информация о их количестве является избыточной. Поэтому я и говорил, что для замены функции ExistOrders() функцией NumberOfOrders() необходимо и достаточно проверять значение, возвращаемое функцией NumberOfOrders() на то, чтобы оно было больше нуля. Ведь понятно, что если это значение равно нулю, то ордеров нет, а если оно больше нуля, то ордера есть. Функцию ExistOrders() можно применять тогда, когда не нужна информация о количестве ордеров, а функцию NumberOfOrders() можно применять тогда, когда информация о количестве ордеров НЕ нужна и тогда, когда она нужна. В этом смысле функция NumberOfOrders() полностью заменяет функцию ExistOrders().
rid:
Я вот почему стал вникать. Вставил эту фукнцию в свой эксперт. Задал в параметрах m=1, и условие на открытие позиций -
if(NumberOfOrders("", -1, MagicNumber)<m){//если открытых позиций МЕНЬШЕ m
Но эксперт, словно, не видит этого ограничения! И открывает ордера по каждому сигналу ещё и ещё...
В чём тут может быть дело?
Так... а здесь Вы, похоже путаете позиции с ордерами. Для меня это разные вещи. Что такое позиции? Это торговые операции OP_BUY и OP_SELL, а ордера в моём понимании - это торговые операции OP_BUYLIMIT, OP_BUYSTOP, OP_SELLLIMIT и OP_SELLSTOP. Позиции я открываю, а ордера я устанавливаю. А Вы что открывали? Функция NumberOfOrders() предназначена для работы с ордерами.
Уважаемый Игорь, прошу у вас помощи! Мне необходимо дописать советника так, что бы он мог брать позиции по нескольким инструментам. Работают 2 советника, стандартный MACD и Ema, каждый по 6 позициям, но поза только одна открывается... Я читал ваши комментарии относительно этого, но т.к. я плохо разбираюсь в языке, не могу понять куда что дописывать... Если вам не трудно, то помогите... скопировал советника Ema... Спасибо!
Функция IndexByTicket().
Возвращает индекс (порядковый номер в общем списке установленных ордеров или открытых позиций) ордера или позиции по тикету. Если функция IndexByTicket() не сможет найти ордер или позицию с нужным тикетом, то она вернёт -1. Ограничить перечень проверяемых ордеров или позиций можно параметрами функции:
Функцию IndexByTicket() я писал в заказном советнике. Помню, что без неё никак не обойтись было, а иначе зачем бы я стал её писать? Но вот как она там использовалась, и зачем я её писал в принципе, убей не помню :-) Искать исходник советника влом. Их сотни.
Вообщем, приводить примеры на подобие тех, что я уже наприводил, не вижу смысла. Сообразительные сами догадаются, куда какие параметры "сувать". А если у кого-то возникнет хорошая идея использования функции IndexByTicket(), пишите сюда. Попробую реализовать.
Короткое объявление.
Функции SelectByTicket() и SelectByTicketFromHistory() я упразднил. Сам я их использовать больше не буду, поэтому не вижу смысла опубликовывать. Желающим подискутировать на эту тему всегда рад. Покажу все свои заблуждения AS IS.
Функция NumberOfOrders().
Эта функция возвращает количество ордеров и функционально полностью перекрывает ExistOrders(). Для того, чтобы заменить функцию ExistOrders() функцией NumberOfOrders(), необходимо и достаточно проверять возвращаемое значение на то, чтобы оно было больше нуля. Ограничить перечень проверяемых ордеров можно параметрами функции:
Примеры использования функции NumberOfOrders().
В аттаче опять-таки рабочий скрипт с вышеуказанными примерами.
Функция NumberOfOrders().
Эта функция возвращает количество ордеров и функционально полностью перекрывает ExistOrders(). Для того, чтобы заменить функцию ExistOrders() функцией NumberOfOrders(), необходимо и достаточно проверять возвращаемое значение на то, чтобы оно было больше нуля. Ограничить перечень проверяемых ордеров можно параметрами функции:
Запутался я немного. Почему-то, мне видится некоторое противоречие. Вот здесь:
"...необходимо и достаточно проверять возвращаемое значение на то, чтобы оно было больше нуля."
Если проверять "это и только это", то функция на количество ордеров теряет смысл!
Я вот почему стал вникать. Вставил эту фукнцию в свой эксперт. Задал в параметрах m=1, и условие на открытие позиций -
Но эксперт, словно, не видит этого ограничения! И открывает ордера по каждому сигналу ещё и ещё...
В чём тут может быть дело?
Запутался я немного. Почему-то, мне видится некоторое противоречие. Вот здесь:
"...необходимо и достаточно проверять возвращаемое значение на то, чтобы оно было больше нуля."
Если проверять "это и только это", то функция на количество ордеров теряет смысл!
хм... Похоже, что Вы не обратили внимание на объём возвращаемой информации каждой из функций ExistOrders() и NumberOfOrders(). Функция ExistOrders() возвращает лишь информацию о существовании ордеров, а функция NumberOfOrders() возвращает информацию о количестве ордеров. Информация о количестве ордеров содержит в себе информацию о существовании ордеров. Когда нужно ответить на вопрос, есть ордер или нет, то информация о их количестве является избыточной. Поэтому я и говорил, что для замены функции ExistOrders() функцией NumberOfOrders() необходимо и достаточно проверять значение, возвращаемое функцией NumberOfOrders() на то, чтобы оно было больше нуля. Ведь понятно, что если это значение равно нулю, то ордеров нет, а если оно больше нуля, то ордера есть. Функцию ExistOrders() можно применять тогда, когда не нужна информация о количестве ордеров, а функцию NumberOfOrders() можно применять тогда, когда информация о количестве ордеров НЕ нужна и тогда, когда она нужна. В этом смысле функция NumberOfOrders() полностью заменяет функцию ExistOrders().
Я вот почему стал вникать. Вставил эту фукнцию в свой эксперт. Задал в параметрах m=1, и условие на открытие позиций -
Но эксперт, словно, не видит этого ограничения! И открывает ордера по каждому сигналу ещё и ещё...
В чём тут может быть дело?
Благодарю. Всё понял . И по первому вопросу, и по второму.
Иначе говоря "расширенная" функция NumberOfOrders() по сути, уже включает в себя функцию IndexByTicket()
Да, действительно. Я открывал OP_BUY и OP_SELL !
Осталось привести пример следующей вашей функции, кот. работает именно с позициями. (не с ордерами)
Помнится, где-то на форуме Вы уже её выкладывали. Не могу найти что-то.
Осталось привести пример следующей вашей функции, кот. работает именно с позициями. (не с ордерами)
С функциями для ордеров я закончил. Дальше будут функции для позиций. Около 30 шт.
Помнится где-то на форуме Вы уже её выкладывали. Не могу найти что-то.
поиск
Уважаемый Игорь, прошу у вас помощи! Мне необходимо дописать советника так, что бы он мог брать позиции по нескольким инструментам. Работают 2 советника, стандартный MACD и Ema, каждый по 6 позициям, но поза только одна открывается... Я читал ваши комментарии относительно этого, но т.к. я плохо разбираюсь в языке, не могу понять куда что дописывать... Если вам не трудно, то помогите... скопировал советника Ema... Спасибо!
//+------------------------------------------------------------------+//| Parabolic.mq4 |
//| Виталик |
//| wwwita@mail.ru |
//+------------------------------------------------------------------+
extern double Lots=0.1;
extern double Pip=5;
extern double MoveBack=3;
extern int chk=0;
extern double SL=20;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
double hi=High[1];
double lo=Low[1];
double EMA, EMA1, EMA2, EMA3;
int cnt=0, ticket, total;
EMA=iMA(0,0,5,0,MODE_EMA,PRICE_MEDIAN,1);
EMA1=iMA(0,0,10,0,MODE_EMA,PRICE_MEDIAN,1);
EMA2=iMA(0,0,5,0,MODE_EMA,PRICE_MEDIAN,0);
EMA3=iMA(0,0,10,0,MODE_EMA,PRICE_MEDIAN,0);
total=OrdersTotal();
if(total<1)
{
if(AccountFreeMargin()<(1000*Lots))
{
Print("У вас нет денег. Свободные средства = ", AccountFreeMargin());
return(0);
}
if(((EMA>EMA1) && (EMA2<EMA3)) || ((EMA<EMA1) && (EMA2>EMA3)))
{
chk=1;
Print("Позиция возможна!");
}
if(chk==1)
{
if(EMA3-EMA2>2*Point && Bid>=(lo+MoveBack*Point))
{
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,0,
"EMA position:",16385,0,Red);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Print("Открыт ордер SELL : ",OrderOpenPrice());
chk=0;
}
else
{
Print("Ошибка открытия SELL ордера : ",GetLastError());
return(0);
}
}
if(EMA2-EMA3>2*Point && Ask<=(hi-MoveBack*Point))
{
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,0,
"EMA position:",16385,0,Green);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Print("Открыт ордер BUY : ",OrderOpenPrice());
chk=0;
}
else
{
Print("Ошибка открытия BUY ордера : ",GetLastError());
return(0);
}
}
}
return(0);
}
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()<=OP_SELL && // это открытая позиция? OP_BUY или OP_SELL
OrderSymbol()==Symbol()) // инструмент совпадает?
{
if(OrderType()==OP_BUY) // открыта длинная позиция
{
// проверим, может уже пора закрываться?
if(Bid>=(OrderOpenPrice()+Pip*Point))
{
chk=0;
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // закрываем позицию
return(0); // выходим
}
if(Bid<=(OrderOpenPrice()-SL*Point))
{
chk=0;
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // закрываем позицию
return(0); // выходим
}
}
else // иначе это короткая позиция
{
// проверим, может уже пора закрываться?
if(Ask<=(OrderOpenPrice()-Pip*Point))
{
chk=0;
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // закрываем позицию
return(0); // выходим
}
if(Ask>=(OrderOpenPrice()+SL*Point))
{
chk=0;
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // закрываем позицию
return(0); // выходим
}
}
}
}
return(0);
}
//+------------------------------------------------------------------+
Игорь, я в 'Библиотека функций для работы с INI-файлами.' задавал Вам вопрос, но ответа так и не поступило :(