Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Просто гениально! ;o)
Потестите, потестите её... Это все тестируют.
Знаете, ломать - не строить. Можете предолжить лучше что н-ть взамен?
Знаете, ломать - не строить. Можете предолжить лучше что н-ть взамен?
Да в общем то открою секрет, что сам примерно так и вхожу в рынок. Это просто стандартное свойство пробойных систем. То есть вход при пробитии стопа противоположной позиции. Весь вопрос заключается в подборе условий, когда этот пробой окажется не ложным. А уж вариантов расчёта этого стопа огромнейшее многообразие. Я к примеру этот стоп беру либо по экстремуму предыдущего дня, либо по пробитию границы 99,9% доверительного интервала канала линейной регрессии. Мне кажется что важнее это не выбор стопа а определение условий, при которых может начаться сильное пробойное движение. Вот тут то всё и заключается. Будет это работать или не будет.
Знаете, ломать - не строить. Можете предолжить лучше что н-ть взамен?
Да в общем то открою секрет, что сам примерно так и вхожу в рынок. Это просто стандартное свойство пробойных систем. То есть вход при пробитии стопа противоположной позиции. Весь вопрос заключается в подборе условий, когда этот пробой окажется не ложным. А уж вариантов расчёта этого стопа огромнейшее многообразие. Я к примеру этот стоп беру либо по экстремуму предыдущего дня, либо по пробитию границы 99,9% доверительного интервала канала линейной регрессии. Мне кажется что самое главное это не выбор стопа а определение условий, при которых может начаться сильное пробойное движение.
Я недавно сделал советника. Вот алгоритм его работы:
// Трейлинг позиций в этом советнике обязателен!!!!
// Советник анализирует состояние торгов и в зависимости от состояния, в котором он
// находится, выполняет те или иные действия.
// Управление лотом здесь происходит по методу Мартингейла. Но это можно отключить.
// Состояния советника:
// Sost==1 - ордеров в рынке нет.
// В этом состоянии советник выставляет на 2 стоповых ордера с равным лотом
// на расстоянии LockLevel от текущей цены и прерходит в Sost==2.
// Лот определяется автоматически в зависимости от процента риска, который юзер задал вручную. Стоп-лосс обоих ордеров равен LockStopLoss.
// Sost==2 В рынке 2 отложенных ордера с равным лотом
// Как только 1 из ордеров сработает и станет рыночным,
// советник удаляет оставшийся отложенный ордер и прерходит в Sost==3.
// Sost==3 В рынке один рыночный (не отложенный ордер).
// Выставляем противоположно направленный отложенный ордер (если автоматика включена то лот будет другой; Поэтому предыдущую отложку приходится удалять) в точку Стоп-лосса
// рыночного ордера и переходим в состояние 4.
// Sost==4 В рынке 2 ордера. Один отложенный и один рыночный. Если рыночный ордер вдруг закрывается принудительно, например, по пипс-профиту, или его
// закрыл пользователь, то советник переходит в состояние 1, где он начинает всё сначала. Если сработал стоп-лосс или тейк-профит
// у этого ордера, то советник принимает решение, что ему делать. При срабатывании тейк-профита он открывает рыночный ордер
// в том же направлении, что и у сработавшего и с тем же лотом.
// При срабатывании стоп-лосса 2 ситуации:
// - Стоп-Лосс в зоне положительного профита:
// советник считает, что ситуация неопределённая, удаляет отложенный ордер и переходит в состояние 1, где начинает всё сначала.
// - Если стоп лосс сработал в зоне отрицательного профита или в точке нуля, то советник удаляет отложенный ордер, потом открывает
// рыночный ордер того же направления, что только что удалённый отложенный, но с удвоенным лотом если мартингейл включен, или с лотом,
// определяемым автоматически, если автолот включен, или с тем лотом, что выставил пользователь вручную, если автолот отключен. Далее он
// переходит в состояние № 3. Тут надо заметить, что если автолот отключен а мартингейл включен, то советник удвоит тот лот, который был установлен
// пользователем вручную в настройках в переменной Lots.
2 недели убил на то, чтоб нормально сделать код.
Начал тестировать - уходит в минуса даже при отключении всяких там мартингейлов и автоматов лота. Пробовал даже пипсовать на тестере. Всёравно сливает. Ну чтож, отрицательный результат сужает круг поиска. Словом, запустил на демо - пока торгует в плюс. Пожалуй самый трудный вопрос на форексе - это не столько момент входа в рынок, сколько что делать с образовавшимся вдруг профитом? Перебираю варианты. Словом, работа идёт :) ...
Только лазейку мне оставь малюсенькую, чтоб я мог тут код универсального трейлинга выложить, как и обещал людям ;)
Ну это ничего, всё ещё только начинается ;o) Я вот уже больше года программирую советники, при этом никаких трудностей при программировании не испытываю, а результат пока не слишком впечатляет.
Ну это ничего, всё ещё только начинается ;o) Я вот уже больше года программирую советники, при этом никаких трудностей при программировании не испытываю, а результат пока не слишком впечатляет.
Трудность была не код набрать, а алгоритм досконально продумать. Хотя, могу сказать, что знание MQL4 - довольно хороший инструмент. Вот кажется систему торговли разработал или отыскал хорошую. Кодишь её, тестишь и радости у тя поубавилось. Одно утешение остаётся, что не зарядил денег и не начал торговать по этой псевдосуперской системе. :))
Его возможности описаны в начале кода.
//+------------------------------------------------------------------+ //| Универсал_1.4.mq4 | //| Drknn | //| 10.02.2007 drknn@mail.ru | //+------------------------------------------------------------------+ #property copyright "Drknn" #property link "drknn@mail.ru" /* !!!!!!!!!!!!!! Внимание!!!!!!!!!!!!! В режиме отлова процента депозита советник закрывает все сделки по всем валютным парам, что может негативно повлиять на работу других советников, параллельно запущенных в терминале. Если советник будет настроен на отлов процента, и при этом ему будет разрешено как устанавливать отложенные ордера, так и при отлове удалять отложенные, то это может вызвать програмный конфликт. Вполне возможно, что на текущем тике советник не успеет закрыть все ордера а на следующем начнёт их ставить и тут же удалять, так как приказ на удаление ещё жив. Советник умеет: - тралить ордера любого типа (как рыночные, так и отложенные) - пипсовать - Ловить увеличение депозита на нужное количество процентов и, поймав закрыть сделки по всем валютным парам и, если нужно, удалить и отложенные ордера. - Устанавливать те отложенные ордера, которые разрешил пользователь, если советник вдруг обнаружит, что ордера такого в рынке нет (например, ордер сработал - стал рыночным - или были удалены ордера после отлова процента) - показывает на экране что и как у него настрено, чтоб каждый раз не лазить в настройки Советник задумывался как универсальный трейлинг, а всё остальное добавлено лишь для удобства. Ненужные функции можно легко отключить в окне свойств советника. Если пользователь разрешил советнику устанавливать отложенный ордер какого либо типа, то этот ордер будет установлен от текущей цены на расстоянии трейлингстопа для ордеров данного типа. */ // ================ Параметры, настраиваимые пользователем =========================== // ----- Параметры трала рыночных ордеров --------------------------------------------- extern int ryn_TrStop=15; //Трейлинг-Стоп рыночного ордера. Если = 0 то тарла нет extern int ryn_TrStep=3; //Шаг трала рыночного ордера extern bool WaitProfit = false; // Если true, то ждать профит = значению TrailingStop и только потом начинать тралить //Иначе, трейлинговать не дожидаясь положительного профита // ----- Параметры трала лимитных ордеров --------------------------------------------- extern int lim_TakeProfit=30; //Тейк-Профит лимитных ордеров extern int lim_StopLoss=15; //Стоп-Лосс лимитных ордеров extern int lim_TrStop=0; //Трейлинг-Стоп лимитных ордеров Если = 0 то тарла нет extern int lim_TrStep=3; //Шаг трейлинга лимитных ордеров // ----- Параметры трала стоповых ордеров --------------------------------------------- extern int st_TakeProfit=30; //Тейк-Профит стоповых ордеров extern int st_StopLoss=15; //Стоп-Лосс стоповых ордеров extern int st_TrStop=0; //Трейлинг-Стоп стоповых ордеров. Если = 0 то тарла нет extern int st_TrStep=3; //Шаг трала стоповых ордеров // ----- Разрешение установить тот или иной ордер ------------------------------------- extern double Lot=0.1;//Лот для установки отложенного ордера extern int st_Step=15;//Расстояние в пунктах от уровня текущей цены до уорвня установки стопового ордера extern int lim_Step=15;//Расстояние в пунктах от уровня текущей цены до уорвня установки лимитного ордера extern bool Ustan_BuyStop=true; //можно ли ставиь БайCтоп если в рынке такого у нас нет extern bool Ustan_SellLimit=false; //можно ли ставиь CеллЛимит если в рынке такого у нас нет extern bool Ustan_SellStop=true; //можно ли ставиь CеллCстоп если в рынке такого у нас нет extern bool Ustan_BuyLimit=false; //можно ли ставиь БайЛимит если в рынке такого у нас нет // ----- Параметры пипсовки ---------------------------------------------------- extern int PipsProfit=0; //профит при пипсовке можно ставить 1, 2, 3, ... extern int Proskalz = 3; //Проскальзывание в пунктах (нужно только когда PipsProfit>0) // ----------- Отлавливаем увеличение депозита -------------------------- extern bool Otlov=true;//отловить увеличение депозита на Pojmat процентов и закрыть все ордера //если Otlov=false, то значениt Pojmat не важно. extern double Pojmat=2.0;//процент желаемого увеличения депозита extern bool DelOtlozh=false;//Удалять ли при этом и отложенные ордера. //если Otlov=false, то значениt DelOtlozh не важно. // ----- Прочие установки ------------------------------------------------------ extern bool UseOrderSound = true; // Использовать звуковой сигнал для установки ордеров extern bool UseTrailingSound = true; // Использовать звуковой сигнал для трейлинга string NameOrderSound = "alert.wav"; // Наименование звукового файла для ордеров extern string NameTrallingSound = "expert.wav";// Наименование звукового файла для трейлинга // ======================================================================================= // ================== Глобальные переменные =============================================================== string Comm1,Comm2,Comm3,Comm4,Comm5,Comm6,Comm7,Comm8,Comm9,ED; double PNT,NewPrice,SL,TP,Balans,Free; int MinLevel,i,SchBuyStop,SchSellStop,SchBuyLimit,SchSellLimit,SchSell,SchBuy,SBid,SAsk,BBid,BAsk,Ts,GLE,total; bool fm,Rezult,TrailBuyStop,TrailSellStop,TrailBuyLimit,TrailSellLimit; // ======================================================================================================== //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- if(!IsExpertEnabled())//если ложь {Alert("Ошибка! Не нажата кнопка *Советники*"); Comment("Ошибка! Не нажата кнопка *Советники*"); return(0);} else {Comment("Как только цена изменится, Советник начнёт работу."); Print("Как только цена изменится, Советник начнёт работу.");} PNT=MarketInfo(Symbol(),MODE_POINT);//Размер пункта в валюте котировки. Для текущего инструмента хранится в предопределенной переменной Point MinLevel=MarketInfo(Symbol(),MODE_STOPLEVEL);//Минимально допустимый уровень стоп-лосса/тейк-профита в пунктах if(st_TrStop<MinLevel && st_TrStop!=0) {Comment("Ошибка! ТрейлингСтоп стоповых ордеров не может быть менее ",MinLevel); Print("Ошибка! ТрейлингСтоп стоповых ордеров не может быть менее ",MinLevel); Alert("Ошибка! ТрейлингСтоп стоповых ордеров не может быть менее ",MinLevel); return(0);} if(ryn_TrStop<MinLevel && ryn_TrStop!=0) {Comment("Ошибка! ТрейлингСтоп рыночных ордеров не может быть менее ",MinLevel); Print("Ошибка! ТрейлингСтоп рыночных ордеров не может быть менее ",MinLevel); Alert("Ошибка! ТрейлингСтоп рыночных ордеров не может быть менее ",MinLevel); return(0);} if(lim_TrStop<MinLevel && lim_TrStop!=0) {Comment("Ошибка! ТрейлингСтоп лимитных ордеров не может быть менее ",MinLevel); Print("Ошибка! ТрейлингСтоп лимитных ордеров не может быть менее ",MinLevel); Alert("Ошибка! ТрейлингСтоп лимитных ордеров не может быть менее ",MinLevel); return(0);} if(st_TrStop>=MinLevel && st_TrStep==0) {Comment("Ошибка! шаг тарала стоповых ордеров не может быть менее 1"); Print("Ошибка! ТрейлингСтоп стоповых ордеров не может быть менее 1"); Alert("Ошибка! ТрейлингСтоп стоповых ордеров не может быть менее 1"); return(0);} if(ryn_TrStop>=MinLevel && ryn_TrStep==0) {Comment("Ошибка! Шаг тарала рыночных ордеров не может быть менее 1"); Print("Ошибка! Шаг тарала рыночных ордеров не может быть менее 1"); Alert("Ошибка! Шаг тарала рыночных ордеров не может быть менее 1"); return(0);} if(lim_TrStop>=MinLevel && lim_TrStep==0) {Comment("Ошибка! Шаг тарала лимитных ордеров не может быть менее 1"); Print("Ошибка! Шаг тарала лимитных ордеров не может быть менее 1"); Alert("Ошибка! Шаг тарала лимитных ордеров не может быть менее 1"); return(0);} if(st_Step<MinLevel) {Comment("Ошибка! переменная st_Step не может быть менее ",MinLevel); Print("Ошибка! переменная st_Step не может быть менее ",MinLevel); Alert("Ошибка! переменная st_Step не может быть менее ",MinLevel); return(0);} if(lim_Step<MinLevel) {Comment("Ошибка! переменная lim_Step не может быть менее ",MinLevel); Print("Ошибка! переменная lim_Step не может быть менее ",MinLevel); Alert("Ошибка! переменная lim_Step не может быть менее ",MinLevel); return(0);} //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---- RefreshRates(); //----Первичные проверки данных if(!IsTradeAllowed()) {Comment("Торговля запрещена в настройках терминала, либо торговый поток занят"); return(0);} //----Конец первичных проверок данных if(st_TrStop<MinLevel && st_TrStop!=0) {Comment("Ошибка! ТрейлингСтоп стоповых ордеров не может быть менее ",MinLevel); Print("Ошибка! ТрейлингСтоп стоповых ордеров не может быть менее ",MinLevel); Alert("Ошибка! ТрейлингСтоп стоповых ордеров не может быть менее ",MinLevel); return(0);} if(ryn_TrStop<MinLevel && ryn_TrStop!=0) {Comment("Ошибка! ТрейлингСтоп рыночных ордеров не может быть менее ",MinLevel); Print("Ошибка! ТрейлингСтоп рыночных ордеров не может быть менее ",MinLevel); Alert("Ошибка! ТрейлингСтоп рыночных ордеров не может быть менее ",MinLevel); return(0);} if(lim_TrStop<MinLevel && lim_TrStop!=0) {Comment("Ошибка! ТрейлингСтоп лимитных ордеров не может быть менее ",MinLevel); Print("Ошибка! ТрейлингСтоп лимитных ордеров не может быть менее ",MinLevel); Alert("Ошибка! ТрейлингСтоп лимитных ордеров не может быть менее ",MinLevel); return(0);} if(st_TrStop>=MinLevel && st_TrStep==0) {Comment("Ошибка! шаг тарала стоповых ордеров не может быть менее 1"); Print("Ошибка! ТрейлингСтоп стоповых ордеров не может быть менее 1"); Alert("Ошибка! ТрейлингСтоп стоповых ордеров не может быть менее 1"); return(0);} if(ryn_TrStop>=MinLevel && ryn_TrStep==0) {Comment("Ошибка! Шаг тарала рыночных ордеров не может быть менее 1"); Print("Ошибка! Шаг тарала рыночных ордеров не может быть менее 1"); Alert("Ошибка! Шаг тарала рыночных ордеров не может быть менее 1"); return(0);} if(lim_TrStop>=MinLevel && lim_TrStep==0) {Comment("Ошибка! Шаг тарала лимитных ордеров не может быть менее 1"); Print("Ошибка! Шаг тарала лимитных ордеров не может быть менее 1"); Alert("Ошибка! Шаг тарала лимитных ордеров не может быть менее 1"); return(0);} if(st_Step<MinLevel) {Comment("Ошибка! переменная st_Step не может быть менее ",MinLevel); Print("Ошибка! переменная st_Step не может быть менее ",MinLevel); Alert("Ошибка! переменная st_Step не может быть менее ",MinLevel); return(0);} if(lim_Step<MinLevel) {Comment("Ошибка! переменная lim_Step не может быть менее ",MinLevel); Print("Ошибка! переменная lim_Step не может быть менее ",MinLevel); Alert("Ошибка! переменная lim_Step не может быть менее ",MinLevel); return(0);} if(ryn_TrStop>0 && ryn_TrStop>=MinLevel) Comm1="Трал рыночных - Вкл."; else Comm1="Трал рыночных - Откл."; if (lim_TrStop>0 && lim_TrStop>=MinLevel) Comm2="Трал лимитных - Вкл."; else Comm2="Трал лимитных - Откл."; if (st_TrStop>0 && st_TrStop>=MinLevel) Comm3="Трал стоповых - Вкл."; else Comm3="Трал стоповых - Откл."; if (PipsProfit>0) Comm4="Пипсовка - Вкл"; else Comm4="Пипсовка - Откл"; double Otl=(Balans/100*Pojmat+Balans); Otl=NormalizeDouble(Otl, 2); Ts=MathCeil(Otl); if (Otlov) {Comm5="Отлов процента - Вкл"; Comm6="Ловим сумму = "+Ts+" $";} else {Comm5="Отлов процента - Откл";Comm6="";} SchOrders(); Comment("Ордеров сейчас для ",Symbol()," :","\n","Buy = ",SchBuy," Sell = ",SchSell,"\n","BuyStop = ",SchBuyStop, " SellLimit = ",SchSellLimit,"\n","SellStop = ",SchSellStop," BuyLimit = ",SchBuyLimit,"\n",Comm1, "\n",Comm2,"\n",Comm3,"\n",Comm4,"\n",Comm5,"\n",Comm6); //-------------- Отлавливаем увеличение депозита на Pojmat процентов ------------------------ if(Otlov)//Если разрешено отловить процент увеличения депозита { Balans=AccountBalance();//Баланс счёта Free=AccountEquity();//Текущее количество денег в статье "Средства" if ((Free-Balans)>=(Balans/100*Pojmat))//Если денег стало достаточно { Print("Депозит увеличен на ",Pojmat," процентов.","\n","Закрываем позиции."); Comment("Депозит увеличен на ",Pojmat," процентов.","\n","Закрываем позиции."); if (DelOtlozh) { DeleteAllOrders();//удаляем из рынка все ордера Sleep(5000); RefreshRates(); } else { DelRynochn(); Sleep(5000); RefreshRates(); } SchOrders(); } } //-------------------------------------------------------------------------------------------- //=================Начало пипсовки========================== if (PipsProfit>0) { int total = OrdersTotal(); for (int i = 0; i<total; i++ )//Цикл. Проходим по всем ордерам от 0 до total {//Начало цикла if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { GLE=GetLastError(); ED=ErrorDescription(GLE); Print("Ошибка ", GLE, " при выборе ордера номер ",i); Print ("Описание ошибки - ",ED); } if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true)// выбрали очередной ордер {//начало работы с выбранным ордером if(OrderSymbol()!=Symbol()) continue; // Если не наш - смотрим следующий if(OrderType()==OP_BUY) // если он открытый в покупку, то... { if(Bid>=(OrderOpenPrice()+PipsProfit*Point)) {OrderClose(OrderTicket(),OrderLots(),Bid,Proskalz);} } if(OrderType()==OP_SELL)// если он открытый в продажу, то... { if(Ask<=(OrderOpenPrice() - PipsProfit*Point)) OrderClose(OrderTicket(),OrderLots(),Ask,Proskalz); } } // конец работы с выбранным ордером }// Конец цикла, мы просмотрели все ордера. ---------------------------------------------------------- } //================Конец пипсовки ====================================== //===================== Установка отложенных ордеров =========================================================================== RefreshRates(); SchOrders(); if(SchSellStop==0 && Ustan_SellStop && st_Step>=MinLevel) { NewPrice=Bid-st_Step*Point; if(st_StopLoss==0) SL=0.0000; else SL=NewPrice+st_StopLoss*Point; if(st_TakeProfit==0) TP=0.0000; else TP=NewPrice-st_TakeProfit*Point; fm=OrderSend(Symbol(),OP_SELLSTOP,Lot,NewPrice,3,SL,TP,NULL,0,0,CLR_NONE); /*Сигналим*/ if(fm!=0 && fm!=-1 && UseOrderSound) PlaySound(NameOrderSound); /*Комментируем*/ if(fm!=0 && fm!=-1) {Print("Ордер SellStop установлен"); Comment("Ордер SellStop установлен"); Sleep(5000); RefreshRates();} if(fm==0 || fm==-1)//Если установить не удалось { GLE=GetLastError(); ED=ErrorDescription(GLE); Print("Ошибка № ",GLE," установки SellStop-ордера"); Print ("Описание ошибки - ",ED); } } if(SchBuyStop==0 && Ustan_BuyStop && st_Step>=MinLevel) { NewPrice=Ask+st_Step*Point; if(st_StopLoss==0) SL=0.0000; else SL=NewPrice-st_StopLoss*Point; if(st_TakeProfit==0) TP=0.0000; else TP=NewPrice+st_TakeProfit*Point; fm=OrderSend(Symbol(),OP_BUYSTOP,Lot,NewPrice,3,SL,TP,NULL,0,0,CLR_NONE); /*Сигналим*/ if(fm!=0 && fm!=-1 && UseOrderSound) PlaySound(NameOrderSound); /*Комментируем*/ if(fm!=0 && fm!=-1) {Print("Ордер BuyStop установлен"); Comment("Ордер BuyStop установлен"); Sleep(5000); RefreshRates();} if(fm==0 || fm==-1)//Если установить не удалось { GLE=GetLastError(); ED=ErrorDescription(GLE); Print("Ошибка № ",GetLastError()," установки BuyStop-ордера"); Print ("Описание ошибки - ",ED); } } if(SchBuyLimit==0 && Ustan_BuyLimit && lim_Step>=MinLevel) { NewPrice=Ask-lim_Step*Point; if(st_StopLoss==0) SL=0.0000; else SL=NewPrice-st_StopLoss*Point; if(st_TakeProfit==0) TP=0.0000; else TP=NewPrice+st_TakeProfit*Point; fm=OrderSend(Symbol(),OP_BUYLIMIT,Lot,NewPrice,3,SL,TP,NULL,0,0,CLR_NONE); /*Сигналим*/ if(fm!=0 && fm!=-1 && UseOrderSound) PlaySound(NameOrderSound); /*Комментируем*/ if(fm!=0 && fm!=-1) {Print("Ордер BuyLimit установлен"); Comment("Ордер BuyLimit установлен"); Sleep(5000); RefreshRates();} if(fm==0 || fm==-1)//Если установить не удалось { GLE=GetLastError(); ED=ErrorDescription(GLE); Print("Ошибка № ",GetLastError()," установки BuyLimit-ордера"); Print ("Описание ошибки - ",ED); } } if(SchSellLimit==0 && Ustan_SellLimit && lim_Step>=MinLevel) { NewPrice=Bid+lim_Step*Point; if(st_StopLoss==0) SL=0.0000; else SL=NewPrice+st_StopLoss*Point; if(st_TakeProfit==0) TP=0.0000; else TP=NewPrice-st_TakeProfit*Point; fm=OrderSend(Symbol(),OP_SELLLIMIT,Lot,NewPrice,3,SL,TP,NULL,0,0,CLR_NONE); /*Сигналим*/ if(fm!=0 && fm!=-1 && UseOrderSound) PlaySound(NameOrderSound); /*Комментируем*/ if(fm!=0 && fm!=-1) {Print("Ордер SellLimit установлен"); Comment("Ордер SellLimit установлен"); Sleep(5000); RefreshRates();} if(fm==0 || fm==-1)//Если установить не удалось { GLE=GetLastError(); ED=ErrorDescription(GLE); Print("Ошибка № ",GetLastError()," установки SellLimit-ордера"); Print ("Описание ошибки - ",ED); } } //============================================================================================================================== // ================= Трейлинг Рыночных ордеров ================================================================================== RefreshRates(); SchOrders(); if(ryn_TrStop>=MinLevel && ryn_TrStep>0 && (SchBuy>0 || SchSell>0)) { for (i=0; i<OrdersTotal(); i++)//Проходим по всем ордерам { if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { GLE=GetLastError(); ED=ErrorDescription(GLE); Print("Ошибка ", GLE, " при выборе ордера номер ",i); Print ("Описание ошибки - ",ED); } if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol()==Symbol()) { TrailingPositions(); } } } } if(ryn_TrStop>=MinLevel && ryn_TrStep==0) Alert("Трейлинг невозможен - ноль в настройках советника"); // =============================================================================================================================== //============ Трейлинг отложенных ордеров ============================================================= RefreshRates(); SchOrders();//Обновляем счётчики количества ордеров if((st_TrStop>0 && SchBuyStop+SchSellStop>0) || (SchBuyLimit+SchSellLimit>0 && lim_TrStop>0)) { TrailBuyStop=false; TrailSellStop=false; TrailBuyLimit=false; TrailSellLimit=false; for (i=OrdersTotal()-1;i>=0;i--)//Цикл. Проходим по всем ордерам от 0 до total {//Начало цикла if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { GLE=GetLastError(); ED=ErrorDescription(GLE); Print("Ошибка ", GLE, " при выборе ордера номер ",i); Print ("Описание ошибки - ",ED); } if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true)// выбрали очередной ордер {//начало работы с выбранным ордером if(OrderSymbol()!=Symbol() || OrderType()==OP_BUY || OrderType()==OP_SELL) continue; // Если не наш - смотрим следующий if(OrderType()==OP_BUYSTOP) // Он наверху и едет вниз { if(Ask<OrderOpenPrice()-(st_TrStop+st_TrStep)*Point) TrailBuyStop=true; } if(OrderType()==OP_SELLLIMIT) // Он наверху и едет вниз { if(Bid<OrderOpenPrice()-(st_TrStop+st_TrStep)*Point) TrailSellLimit=true; } if(OrderType()==OP_SELLSTOP) // Он внизу и едет вверх { if(Bid>OrderOpenPrice()+(st_TrStop+st_TrStep)*Point) TrailSellStop=true; } if(OrderType()==OP_BUYLIMIT) // Он внизу и едет вверх { if(Ask>OrderOpenPrice()+(st_TrStop+st_TrStep)*Point) TrailBuyLimit=true; } }//конец работы с выбранным ордером }//Конец цикла if (TrailSellLimit || TrailBuyLimit || TrailSellStop || TrailBuyStop) TrailingOtlozh(); } //==================================================================================================== //---- return(0); } //+ ========================== Конец работы советника ========================================================================== + // ___________________________________________________________________________________________ //| | //| | //| Далее идут подпрограммы (функции), | //| которые в случае надобности вызываются из тела советника | //| | //|___________________________________________________________________________________________| //=========== Счётчики количества ордеров ================================================================= // Функция SchOrders() проходит по всем ордерам и подсчитывает, сколько сейчас имеется ордеров каждого типа. // Как только понадобятся значение того или иного счётчика, нужно сначала вызвать функцию SchOrders() // Она обновит данные и потом можно смело вызывать тот или иной счётчик. // SchBuyStop - счётчик ордеров BuyStop // SchSellStop - счётчик ордеров SellStop // // SchBuyLimit - счётчик ордеров BuyLimit // SchSellLimit счётчик ордеров SellLimit // SchBuy - счётчик Buy ордеров // SchSell - счётчик Sell ордеров //---------------------------------------------------------------------------------------------------------- void SchOrders() { // для начала работы счётчиков мы их обнуляем SchBuyStop=0; SchSellStop=0; SchBuyLimit=0; SchBuy=0; SchSell=0; SchSellLimit=0; for (i=OrdersTotal()-1;i>=0;i--)//Цикл. Проходим по всем ордерам от 0 до total {//Начало цикла if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { GLE=GetLastError(); ED=ErrorDescription(GLE); Print("Ошибка ", GLE, " при выборе ордера номер ",i); Print ("Описание ошибки: ",ED); } if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))// выбрали очередной ордер {//начало работы с выбранным ордером if(OrderSymbol()!=Symbol()) continue; // Если не наш - смотрим следующий if(OrderType()==OP_BUYSTOP) // если он BUYSTOP, то... SchBuyStop++;//увеличиваем значение счётчиков на 1 if(OrderType()==OP_SELLSTOP) // если он SELLSTOP, то... SchSellStop++; //увеличиваем значение счётчиков на 1 if(OrderType()==OP_SELLLIMIT) SchSellLimit++; if(OrderType()==OP_BUYLIMIT) SchBuyLimit++; if(OrderType()==OP_BUY) // если он открытый в покупку, то... SchBuy++;//увеличиваем значение счётчиков на 1 if(OrderType()==OP_SELL)// если он открытый в продажу, то... SchSell++;//увеличиваем значение счётчиков на 1 }//конец работы с выбранным ордером }//Конец цикла } //========================================================================================================== //+------------------------------------------------------------------+ //| Сопровождение позиции простым тралом | //+------------------------------------------------------------------+ void TrailingPositions()//Описание (объявление) пользовательской функции { if(OrderType()==OP_BUY)//Если выбранный в цикле ордер в покупку { if(!WaitProfit || (Bid-OrderOpenPrice())>ryn_TrStop*Point) { if (OrderStopLoss()<Bid-(ryn_TrStop+ryn_TrStep-1)*Point) {ModifyStopLoss(Bid-ryn_TrStop*Point);} } } if(OrderType()==OP_SELL) { if(!WaitProfit || OrderOpenPrice()-Ask>ryn_TrStop*Point) { if(OrderStopLoss()>Ask+(ryn_TrStop+ryn_TrStep-1)*Point || OrderStopLoss()==0) {ModifyStopLoss(Ask+ryn_TrStop*Point);} } } } //+------------------------------------------------------------------+ //| Перенос уровня StopLoss | //| Параметры: | //| ldStopLoss - уровень StopLoss | //+------------------------------------------------------------------+ void ModifyStopLoss(double ldStopLoss) { fm=OrderModify(OrderTicket(),OrderOpenPrice(),ldStopLoss,OrderTakeProfit(),0,CLR_NONE); if(fm!=0 && fm!=-1 && UseTrailingSound) PlaySound(NameTrallingSound); if(fm==0 || fm==-1) { GLE=GetLastError(); ED=ErrorDescription(GLE); Print("Модификация ",Symbol(),"-ордера № ",OrderTicket()," вызвала ошибку № ",GLE); Print ("Описание ошибки: ",ED); } } //+------------------------------------------------------------------+ //======== Подтягивание отложенного ордера вслед ценой ============================================ // Функция TrailingOtlozh() подтягивает отложенный ордер вслед за ценой //-------------------------------------------------------------------------------------------------- void TrailingOtlozh() { RefreshRates(); for (i=OrdersTotal()-1;i>=0;i--)//Цикл. Проходим по всем ордерам {//Начало цикла if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { GLE=GetLastError(); ED=ErrorDescription(GLE); Print("Ошибка ", GLE, " при выборе ордера номер ",i); Print ("Описание ошибки: ",ED); } if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))// выбрали очередной ордер {//начало работы с выбранным ордером if(OrderSymbol()!=Symbol()) {} // Если не наш - смотрим следующий if(OrderType()==OP_BUYSTOP)//находится вверху, едет вниз { if(TrailBuyStop) { NewPrice=Ask+st_TrStop*Point; if(st_StopLoss==0) SL=0.0000; else SL=NewPrice-st_StopLoss*Point; if(st_TakeProfit==0) TP=0.0000; else TP=NewPrice+st_TakeProfit*Point; Rezult=false; Rezult=OrderModify(OrderTicket(),NewPrice,SL,TP,0,CLR_NONE); if(fm!=0 && fm!=-1 && UseTrailingSound) PlaySound(NameTrallingSound); if(Rezult!=0 && Rezult!=-1) Sleep(5000); if(Rezult==0 || Rezult==-1) { Print("Корректировка BUYSTOP-ордера № ",OrderTicket(), " вернула ошибку № ",GetLastError()); Print("NewPrice BUYSTOP-ордера = ",NewPrice); //Print("StopLoss BUYSTOP-ордера = ",SL); //Print("TakeProfit BUYSTOP-ордера = ",TP); } } } if(OrderType()==OP_SELLSTOP) // Находится внизу, едет вверх { if(TrailSellStop) { NewPrice=Bid-st_TrStop*Point; if(st_StopLoss==0) SL=0.0000; else SL=NewPrice+st_StopLoss*Point; if(st_TakeProfit==0) TP=0.0000; else TP=NewPrice-st_TakeProfit*Point; Rezult=false; Rezult=OrderModify(OrderTicket(),NewPrice,SL,TP,0,CLR_NONE); if(fm!=0 && fm!=-1 && UseTrailingSound) PlaySound(NameTrallingSound); if(Rezult!=0 && Rezult!=-1) Sleep(5000); if(Rezult==0 || Rezult==-1) { Print("Корректировка SELLSTOP-ордера № ",OrderTicket(), " вернула ошибку № ",GetLastError()); Print("NewPrice SELLSTOP-ордера = ",NewPrice); //Print("StopLoss SELLSTOP-ордера = ",SL); //Print("TakeProfit SELLSTOP-ордера = ",TP); } } } if(OrderType()==OP_BUYLIMIT) // Находится внизу, едет вверх { if(TrailBuyLimit) { NewPrice=Ask-st_TrStop*Point; if(st_StopLoss==0) SL=0.0000; else SL=NewPrice-st_StopLoss*Point; if(st_TakeProfit==0) TP=0.0000; else TP=NewPrice+st_TakeProfit*Point; Rezult=false; Rezult=OrderModify(OrderTicket(),NewPrice,SL,TP,0,CLR_NONE); if(fm!=0 && fm!=-1 && UseTrailingSound) PlaySound(NameTrallingSound); if(Rezult!=0 && Rezult!=-1) Sleep(5000); if(Rezult==0 || Rezult==-1) { Print("Корректировка BUYLIMIT-ордера № ",OrderTicket(), " вернула ошибку № ",GetLastError()); Print("NewPrice BUYLIMIT-ордера = ",NewPrice); //Print("StopLoss BUYLIMIT-ордера = ",SL); //Print("TakeProfit BUYLIMIT-ордера = ",TP); } } } if(OrderType()==OP_SELLLIMIT)//находится вверху, едет вниз { if(TrailSellLimit) { NewPrice=Bid+st_TrStop*Point; if(st_StopLoss==0) SL=0.0000; else SL=NewPrice+st_StopLoss*Point; if(st_TakeProfit==0) TP=0.0000; else TP=NewPrice-st_TakeProfit*Point; Rezult=false; Rezult=OrderModify(OrderTicket(),NewPrice,SL,TP,0,CLR_NONE); if(fm!=0 && fm!=-1 && UseTrailingSound) PlaySound(NameTrallingSound); if(Rezult!=0 && Rezult!=-1) Sleep(5000); if(Rezult==0 || Rezult==-1) { Print("Корректировка SELLLIMIT-ордера № ",OrderTicket(), " вернула ошибку № ",GetLastError()); Print("NewPrice SELLLIMIT-ордера = ",NewPrice); //Print("StopLoss SELLLIMIT-ордера = ",SL); //Print("TakeProfit SELLLIMIT-ордера = ",TP); } } } }//конец работы с выбранным ордером }//Конец цикла }//конец функции //========================================================================================= //=========== Удаление ВСЕХ ИМЕЮЩИХСЯ в рынке ордеров ======================== // Функция DeleteAllOrders() // Удаляет ВСЕ ИМЕЮЩИЕСЯ ордера - и рыночные и отложенные, // независимо от того, к какой валютной паре прицеплен советник //---------------------------------------------------------------------------- bool DeleteAllOrders() { for (int i=OrdersTotal()-1; i>=0; i--) { if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { GLE=GetLastError(); ED=ErrorDescription(GLE); Print("Ошибка ", GLE, " при выборе ордера номер ",i); Print ("Описание ошибки - ",ED); } if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderType()==OP_BUYLIMIT || OrderType()==OP_SELLLIMIT || OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP) OrderDelete(OrderTicket()); if(OrderType()==OP_BUY) // если он открытый в покупку, то... OrderClose(OrderTicket(),OrderLots(),Bid,3); if(OrderType()==OP_SELL)// если он открытый в продажу, то... OrderClose(OrderTicket(),OrderLots(),Ask,3); } } } //============================================================================ // ======== Удаление только рыночных ордеров ================================ // Удаляет ВСЕ рыночные ордера, // независимо от того, к какой валютной паре прицеплен советник //---------------------------------------------------------------------------- void DelRynochn() { for (int i=OrdersTotal()-1; i>=0; i--) { if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { GLE=GetLastError(); ED=ErrorDescription(GLE); Print("Ошибка ", GLE, " при выборе ордера номер ",i); Print ("Описание ошибки - ",ED); } if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if(OrderType()==OP_BUY) // если он открытый в покупку, то... OrderClose(OrderTicket(),OrderLots(),Bid,3); if(OrderType()==OP_SELL)// если он открытый в продажу, то... OrderClose(OrderTicket(),OrderLots(),Ask,3); } } } //============================================================================ //========= Словестное описание ошибок ========================================================================================= // Функция возвращает не код ошибки а её словестное описание //----------------------------------------------------------- string ErrorDescription(int error_code) { string error_string; //---- switch(error_code) { //---- codes returned from trade server case 0: error_string=" Нет ошибки"; break; case 1: error_string=" Нет ошибки, но результат неизвестен"; break; case 2: error_string=" Общая ошибка"; break; case 3: error_string=" Неправильные параметры"; break; case 4: error_string=" Торговый сервер занят"; break; case 5: error_string=" Старая версия клиентского терминала"; break; case 6: error_string=" Нет связи с торговым сервером"; break; case 7: error_string=" Недостаточно прав"; break; case 8: error_string=" Слишком частые запросы"; break; case 9: error_string=" Недопустимая операция нарушающая функционирование сервера"; break; case 64: error_string=" Счет заблокирован"; break; case 65: error_string=" Неправильный номер счета"; break; case 128: error_string=" Истек срок ожидания совершения сделки"; break; case 129: error_string=" Неправильная цена"; break; case 130: error_string=" Неправильные стопы"; break; case 131: error_string=" Неправильный объем"; break; case 132: error_string=" Рынок закрыт"; break; case 133: error_string=" Торговля запрещена"; break; case 134: error_string=" Недостаточно денег для совершения операции"; break; case 135: error_string=" Цена изменилась"; break; case 136: error_string=" Нет цен"; break; case 137: error_string=" Брокер занят"; break; case 138: error_string=" Новые цены"; break; case 139: error_string=" Ордер заблокирован и уже обрабатывается"; break; case 140: error_string=" Разрешена только покупка"; break; case 141: error_string=" Слишком много запросов"; break; case 145: error_string=" Модификация запрещена, так как ордер слишком близок к рынку"; break; case 146: error_string=" Подсистема торговли занята"; break; case 147: error_string=" Использование даты истечения ордера запрещено брокером"; break; case 148: error_string=" Количество открытых и отложенных ордеров достигло предела, установленного брокером"; break; case 4000: error_string=" Нет ошибки"; break; case 4001: error_string=" Неправильный указатель функции"; break; case 4002: error_string=" Индекс массива - вне диапазона"; break; case 4003: error_string=" Нет памяти для стека функций"; break; case 4004: error_string=" Переполнение стека после рекурсивного вызова"; break; case 4005: error_string=" На стеке нет памяти для передачи параметров"; break; case 4006: error_string=" Нет памяти для строкового параметра"; break; case 4007: error_string=" Нет памяти для временной строки"; break; case 4008: error_string=" Неинициализированная строка"; break; case 4009: error_string=" Неинициализированная строка в массиве"; break; case 4010: error_string=" Нет памяти для строкового массива"; break; case 4011: error_string=" Слишком длинная строка"; break; case 4012: error_string=" Остаток от деления на ноль"; break; case 4013: error_string=" Деление на ноль"; break; case 4014: error_string=" Неизвестная команда"; break; case 4015: error_string=" Неправильный переход"; break; case 4016: error_string=" Неинициализированный массив"; break; case 4017: error_string=" Вызовы DLL не разрешены"; break; case 4018: error_string=" Невозможно загрузить библиотеку"; break; case 4019: error_string=" Невозможно вызвать функцию"; break; case 4020: error_string=" Вызовы внешних библиотечных функций не разрешены"; break; case 4021: error_string=" Недостаточно памяти для строки, возвращаемой из функции"; break; case 4022: error_string=" Система занята"; break; case 4050: error_string=" Неправильное количество параметров функции"; break; case 4051: error_string=" Недопустимое значение параметра функции"; break; case 4052: error_string=" Внутренняя ошибка строковой функции"; break; case 4053: error_string=" Ошибка массива"; break; case 4054: error_string=" Неправильное использование массива-таймсерии"; break; case 4055: error_string=" Ошибка пользовательского индикатора"; break; case 4056: error_string=" Массивы несовместимы"; break; case 4057: error_string=" Ошибка обработки глобальныех переменных"; break; case 4058: error_string=" Глобальная переменная не обнаружена"; break; case 4059: error_string=" Функция не разрешена в тестовом режиме"; break; case 4060: error_string=" Функция не подтверждена"; break; case 4061: error_string=" Ошибка отправки почты"; break; case 4062: error_string=" Ожидается параметр типа string"; break; case 4063: error_string=" Ожидается параметр типа integer"; break; case 4064: error_string=" Ожидается параметр типа double"; break; case 4065: error_string=" В качестве параметра ожидается массив"; break; case 4066: error_string=" Запрошенные исторические данные в состоянии обновления"; break; case 4067: error_string=" Ошибка при выполнении торговой операции"; break; case 4099: error_string=" Конец файла"; break; case 4100: error_string=" Ошибка при работе с файлом"; break; case 4101: error_string=" Неправильное имя файла"; break; case 4102: error_string=" Слишком много открытых файлов"; break; case 4103: error_string=" Невозможно открыть файл"; break; case 4104: error_string=" Несовместимый режим доступа к файлу"; break; case 4105: error_string=" Ни один ордер не выбран"; break; case 4106: error_string=" Неизвестный символ"; break; case 4107: error_string=" Неправильный параметр цены для торговой функции"; break; case 4108: error_string=" Неверный номер тикета"; break; case 4109: error_string=" Торговля не разрешена"; break; case 4110: error_string=" Длинные позиции не разрешены"; break; case 4111: error_string=" Короткие позиции не разрешены"; break; case 4200: error_string=" Объект уже существует"; break; case 4201: error_string=" Запрошено неизвестное свойство объекта"; break; case 4202: error_string=" Объект не существует"; break; case 4203: error_string=" Неизвестный тип объекта"; break; case 4204: error_string=" Нет имени объекта"; break; case 4205: error_string=" Ошибка координат объекта"; break; case 4206: error_string=" Не найдено указанное подокно"; break; case 4207: error_string=" Ошибка при работе с объектом"; break; } //---- return(error_string); } //===============================================================================================================================Всё что написано в логе тестера это:
22:41:52 2007.01.15 03:00 unuversal GBPUSDm,M30: Как только цена изменится, Советник начнёт работу.
И больше ни одной записи!
Возможно это из-за того, что в советнике отсутствует нормализация цен на открытие позиций.
Всё что написано в логе тестера это:
22:41:52 2007.01.15 03:00 unuversal GBPUSDm,M30: Как только цена изменится, Советник начнёт работу.
И больше ни одной записи!
Возможно это из-за того, что в советнике отсутствует нормализация цен на открытие позиций.
Почему у меня всё прекрасно открывает?
Переприсоедини советника к графику по новой.
А вообще, он может наткнуться на занятость торгового потока и ждать пока поток освободится. Я не стал коммент писать по этому поводу, чтоб журнал не засорять. Может надо просто подождать ещё одного тика?
Есть ещё вариант - там установлен счётчик ордеров. Если устнаовленных отложенных ордеров достаточно то надпись не изменится. Комментов сейчас добавлю и будет отображаться и в логе в окне графика.
Всё что написано в логе тестера это:
22:41:52 2007.01.15 03:00 unuversal GBPUSDm,M30: Как только цена изменится, Советник начнёт работу.
И больше ни одной записи!
Возможно это из-за того, что в советнике отсутствует нормализация цен на открытие позиций.
Я добавил комменты в код советника ну там и кое что ещё по мелочам. Изменённый код находится на месте прежнего (кстати поставил номер версии - см. вверху кода)
Так что можно смело копировать и компилировать его.