Полезные функции от KimIV - страница 49

 
KimIV писал (а) >>

Примеры использования функции ExistOrders().

5. Проверить наличие любого ордера с временем установки не ранее 2-х часов назад

ExistOrders("", -1, -1, TimeCurrent()-2*60*60);

Добрый вечер! Я немного запутался в этом комментарии. Сижу соображаю ! Никак не могу сообразить как правильно сформулировать свое условие - "не ранее 5 мин" или " не позднее 5 мин" ! (Пока не задумался, - всё было ясно!)

Мне надо удалить отложенный ордер, если он не сработал в течении заданного времени. Например, в течении 5 минут после установки !

Я сделал так:

if (ExistOrders(NULL, OP_BUYSTOP, Magic,TimeCurrent()-5*60) >0) //ЕСЛИ ЕСТЬ ОРДЕР BUYSTOP > 5 min 
                 DeleteOrders(NULL, OP_BUYSTOP, Magic);
if (ExistOrders(NULL, OP_SELLSTOP, Magic,TimeCurrent()-5*60) >0) //ЕСЛИ ЕСТЬ ОРДЕР SELLSTOP > 5 min  
                 DeleteOrders(NULL, OP_SELLSTOP, Magic);

Это правильно? Но в тестере это не работает. Ордера ставятся и тут же удаляются.

Пож. подскажите, как надо правильно написать функцию ExistOrders() ?

 
rid писал (а) >>
Я немного запутался...

Похоже, что я тоже запутался. Давайте будем вместе распутываться... :-)

Параметр ot (время установки ордера) был введён в функцию ExistOrders для правильной обработки ошибок 128, 142 и 143. Цель обработки этих ошибок - исключить двойную (а были практические случаи даже тройную) установку одного и того же ордера. Для этого запоминается время отправки торгового приказа и делается пауза в торговых попытках. После паузы проверяется наличие ордера со временем установки после запомненного. Если ордер есть, то делается вывод, что цель достигнута (ордер установлен) и торговые попытки прекращаются. То есть в параметр ot передаётся время, позже которого проверяется установленность ордеров. Позже = не ранее.

rid писал (а) >>
Мне надо удалить отложенный ордер, если он не сработал в течении заданного времени. Например, в течении 5 минут после установки !

Параметр ot функции ExistOrders Вам тут не помощник. Он работает в другую сторону. В сторону приближения к настоящему. А Вам нужно использовать удаление в прошлое. Для этого отлично подходит экспирация (истечение срока жизни), параметр expiration функции OrderSend (или параметр ex моей функции SetOrder).

 

Функция ClosePosBySelect() для тестера.

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

//+----------------------------------------------------------------------------+
//|  Автор   : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                    |
//+----------------------------------------------------------------------------+
//|  Версия  : 13.06.2007                                                      |
//|  Описание: Закрытие одной предварительно выбранной позиции                 |
//+----------------------------------------------------------------------------+
void ClosePosBySelect() {
  double pp;

  if (OrderType()==OP_BUY) {
    pp=MarketInfo(OrderSymbol(), MODE_BID);
    OrderClose(OrderTicket(), OrderLots(), pp, Slippage, clCloseBuy);
  }
  if (OrderType()==OP_SELL) {
    pp=MarketInfo(OrderSymbol(), MODE_ASK);
    OrderClose(OrderTicket(), OrderLots(), pp, Slippage, clCloseSell);
  }
}

ЗЫ. Пример использования функции ClosePosBySelect() я приведу позже, вместе с функцией OpenPosition() для тестера.

 

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

Кое где обьединил функции по сходной тематике. Содержание с 1 по 40 стр.

Желающие могут продолжить и добавить др. странички и выложить тож сюда.

Файлы:
 

Здравствуйте Игорь! Нужна ваша помощь. Решилв вести функцию закрытия терминала в советник e-CloseByProfit по аналогии с e-CloseByPercentProfit.

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

Помогите изменить код так, чтобы устранить этот недостаток.

//+----------------------------------------------------------------------------+
//| e-CloseByProfit.mq4 |
//| Ким Игорь В. aka KimIV |
//| http://www.kimiv.ru |
//| |
//| 22.10.2006 Советник закрывает все позиции при достижении заданного |
//| уровня профита пунктах. |
//| 20.06.2008 Исправлена ошибка расчёта профита в пунктах. |
//+----------------------------------------------------------------------------+
#property copyright "Ким Игорь В. aka KimIV"
#property link "http://www.kimiv.ru"
#define MAGIC 20061022

//------- Внешние параметры советника ------------------------------------------
extern string _P_Expert = "---------- Параметры советника";
extern bool CurSymbolOnly = false; // Только текущий символ
extern int TakeProfit = 100; // Тейк
extern bool CloseTerminal = False; // Закрывать терминал
extern bool ShowComment = True; // Показывать комментарий
extern int NumberAccount = 0; // Номер торгового счёта
extern bool UseSound = True; // Использовать звуковой сигнал
extern string NameFileSound = "manycoin.wav"; // Наименование звукового файла
extern int Slippage = 3; // Проскальзывание цены
extern int NumberOfTry = 5; // Количество попыток

//------- Глобальные переменные советника --------------------------------------
color clCloseBuy = Blue; // Цвет значка закрытия покупки
color clCloseSell = Red; // Цвет значка закрытия продажи
int CurProfit;

//------- Поключение внешних модулей -------------------------------------------
#include <stdlib.mqh>
#include <WinUser32.mqh>

//+----------------------------------------------------------------------------+
//| expert initialization function |
//+----------------------------------------------------------------------------+
void init() { if (!IsTesting()) Comment(""); }

//+----------------------------------------------------------------------------+
//| expert deinitialization function |
//+----------------------------------------------------------------------------+
void deinit() { if (!IsTesting()) Comment(""); }

//+----------------------------------------------------------------------------+
//| expert start function |
//+----------------------------------------------------------------------------+
void start() {
if (!IsTesting()) {
if (NumberAccount>0 && NumberAccount!=AccountNumber()) {
Message("ЗАПРЕЩЕНА торговля на счёте "+AccountNumber());
return;
} else Comment("");
}

CloseByProfit();
if (ShowComment) {
Comment(IIFs(CurSymbolOnly, "CurSymbolOnly ",""),
"Текущий профит=",CurProfit," п.",
" Профит закрытия=",TakeProfit," п."
);
}
}


//+----------------------------------------------------------------------------+
//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Версия : 19.02.2008 |
//| Описание: Закрытие одной предварительно выбранной позиции |
//+----------------------------------------------------------------------------+
void ClosePosBySelect() {
bool fc;
color clClose;
double ll, pa, pb, pp;
int err, it;

if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
for (it=1; it<=NumberOfTry; it++) {
if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) break;
while (!IsTradeAllowed()) Sleep(5000);
RefreshRates();
pa=MarketInfo(OrderSymbol(), MODE_ASK);
pb=MarketInfo(OrderSymbol(), MODE_BID);
if (OrderType()==OP_BUY) {
pp=pb; clClose=clCloseBuy;
} else {
pp=pa; clClose=clCloseSell;
}
ll=OrderLots();
fc=OrderClose(OrderTicket(), ll, pp, Slippage, clClose);
if (fc) {
if (UseSound) PlaySound(NameFileSound); break;
} else {
err=GetLastError();
if (err==146) while (IsTradeContextBusy()) Sleep(1000*11);
Print("Error(",err,") Close ",GetNameOP(OrderType())," ",
ErrorDescription(err),", try ",it);
Print(OrderTicket()," Ask=",pa," Bid=",pb," pp=",pp);
Print("sy=",OrderSymbol()," ll=",ll," sl=",OrderStopLoss(),
" tp=",OrderTakeProfit()," mn=",OrderMagicNumber());
Sleep(1000*5);
}
}
} else Print("Некорректная торговая операция. Close ",GetNameOP(OrderType()));
}

//+----------------------------------------------------------------------------+
//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Версия : 19.02.2008 |
//| Описание : Закрытие позиций по рыночной цене сначала прибыльных |
//+----------------------------------------------------------------------------+
//| Параметры: |
//| sy - наименование инструмента ("" - любой символ, |
//| NULL - текущий символ) |
//| op - операция (-1 - любая позиция) |
//| mn - MagicNumber (-1 - любой магик) |
//+----------------------------------------------------------------------------+
void ClosePosFirstProfit(string sy="", int op=-1, int mn=-1) {
int i, k=OrdersTotal();
if (sy=="0") sy=Symbol();

// Сначала закрываем прибыльные позиции
for (i=k-1; i>=0; i--) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if ((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)) {
if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
if (mn<0 || OrderMagicNumber()==mn) {
if (OrderProfit()+OrderSwap()>0) ClosePosBySelect();
}
}
}
}
}
// Потом все остальные
k=OrdersTotal();
for (i=k-1; i>=0; i--) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if ((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)) {
if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
if (mn<0 || OrderMagicNumber()==mn) ClosePosBySelect();
}
}
}
}
}

//+----------------------------------------------------------------------------+
//| Закрытие всех позиций по профиту. |
//+----------------------------------------------------------------------------+
void CloseByProfit() {
double pa, pb, pp;
int i, k=OrdersTotal(), pr=0;

for (i=0; i<k; i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if (!CurSymbolOnly || OrderSymbol()==Symbol()) {
pa=MarketInfo(OrderSymbol(), MODE_ASK);
pb=MarketInfo(OrderSymbol(), MODE_BID);
pp=MarketInfo(OrderSymbol(), MODE_POINT);
if (pp==0) if (StringFind(OrderSymbol(), "JPY")<0) pp=0.0001; else pp=0.01;
if (OrderType()==OP_BUY) {
pr+=NormalizeDouble((pb-OrderOpenPrice())/pp, 0);
}
if (OrderType()==OP_SELL) {
pr+=NormalizeDouble((OrderOpenPrice()-pa)/pp, 0);
}
}
}
}
CurProfit=pr;
if (CurProfit>=TakeProfit) ClosePosFirstProfit();
if (CloseTerminal && !ExistPositions()) CloseTerminal();
}
//+----------------------------------------------------------------------------+
//| Закрывает торговый терминал. |
//+----------------------------------------------------------------------------+
void CloseTerminal() {
Print("Сработала функция CloseTerminal()");
int hwnd=WindowHandle(Symbol(), Period());
int hwnd_parent=0;

while(!IsStopped()) {
hwnd=GetParent(hwnd);
if (hwnd==0) break;
hwnd_parent=hwnd;
}
if (hwnd_parent!=0) PostMessageA(hwnd_parent, WM_CLOSE, 0, 0);
}

//+----------------------------------------------------------------------------+
//| Возвращает флаг существования позиций |
//| Параметры: |
//| sy - наименование инструмента ("" - любой символ, |
//| NULL - текущий символ) |
//| op - операция (-1 - любая позиция) |
//| mn - MagicNumber (-1 - любой магик) |
//+----------------------------------------------------------------------------+
bool ExistPositions(string sy="", int op=-1, int mn=-1) {
int i, k=OrdersTotal();

if (StringLen(sy)==1 && StringGetChar(sy, 0)==48) sy=Symbol();
for (i=0; i<k; i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if (OrderSymbol()==sy || sy=="") {
if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
if (op<0 || OrderType()==op) {
if (mn<0 || OrderMagicNumber()==mn) return(True);
}
}
}
}
}
return(False);
}
//+----------------------------------------------------------------------------+
//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Версия : 01.09.2005 |
//| Описание : Возвращает наименование торговой операции |
//+----------------------------------------------------------------------------+
//| Параметры: |
//| op - идентификатор торговой операции |
//+----------------------------------------------------------------------------+
string GetNameOP(int op) {
switch (op) {
case OP_BUY : return("Buy");
case OP_SELL : return("Sell");
case OP_BUYLIMIT : return("BuyLimit");
case OP_SELLLIMIT: return("SellLimit");
case OP_BUYSTOP : return("BuyStop");
case OP_SELLSTOP : return("SellStop");
default : return("Unknown Operation");
}
}

//+----------------------------------------------------------------------------+
//| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Версия : 01.02.2008 |
//| Описание : Возвращает одно из двух значений взависимости от условия. |
//+----------------------------------------------------------------------------+
string IIFs(bool condition, string ifTrue, string ifFalse) {
if (condition) return(ifTrue); else return(ifFalse);
}

//+----------------------------------------------------------------------------+
//| Вывод сообщения в коммент и в журнал |
//+----------------------------------------------------------------------------+
void Message(string m) {
Comment(m);
if (StringLen(m)>0) Print(m);
}
//+----------------------------------------------------------------------------+

 
Vkorch писал (а) >>
Здравствуйте Игорь! Нужна ваша помощь. Решилв вести функцию закрытия терминала в советник e-CloseByProfit по аналогии с e-CloseByPercentProfit.

Все получилось нормально,советник отрабатывает, терминал закрывается. Но при повторном открытии терминала советник его тут же закрывает.
Помогите изменить код так, чтобы устранить этот недостаток.

Сделайте вот так:

CurProfit=pr;
if (CurProfit>=TakeProfit) {
  ClosePosFirstProfit();
  if (CloseTerminal && !ExistPositions()) CloseTerminal();
}
 
KimIV писал(а) >>

Сделайте вот так:

Спасибо, Игорь. Исправил. Но при компиляции имею ошибку

'(' - function definition unexpected C:\Program Files\MetaTrader - Alpari\experts\e-CloseByProfit.mq4 (180, 19)

Как быть?

 

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

По поводу

OpenPosition("GBPJPY", OP_SELL, 0.1, pb+23*po, pb-44*po);

Может лучше вызывать вот так OpenPosition("GBPJPY", OP_SELL, 0.1, 23, 44);

а

double pa=MarketInfo("USDCAD", MODE_ASK);
double pb=MarketInfo("USDCAD", MODE_BID);
double po=MarketInfo("USDCAD", MODE_POINT);
и вот это вставить 
   double lot_min =MarketInfo(Symbol(),MODE_MINLOT);
   if(Lots<lot_min) return;

вычислять в нутри функции, т.е. передавать величину sl и tp, а внутри уже корректно все рассчитывать и нормализовывать.


	          
Файлы:
 

Здравствуйте Игорь!

Н е могу разобраться с дроблением позиций.Если открыта позиция 0.3 лотта,мне надо:

1.Закрыть часть позиции 0.1 лотта.

Модифицировать(перенести стоп лос на другой уровень)

2.Ещё закрыть часть позиции 0.1 лотта .

Модифицировать(перенести стоп лос на другой уровень)

3.Закрыть позицию.

И ещё один вопрос ? При закрыт ии част и позиции

OrderClose(OrderTicket(),NormalizeDouble(OrderLots()/3,2),Ask,3,Violet);

возникает ошибка 131(неправильный объём).Как её исправить ?

Ответьте пожалуйста новичку.Можно на словах.

.

 
Prival писал (а) >>
Игорь не затруднит ли оформить в виде библиотеки - функции работы с ордерами и позициями.

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

А над остальным подумаю...

Причина обращения: