//+------------------------------------------------------------------+ //| iK_3D.mq4 | //| Ivan Katsko | //| | //+------------------------------------------------------------------+ #property copyright "Ivan Katsko" #property link "ICQ:372739628" //--------------------------------------------------------------- 1 -- #define NONE 0 extern bool Shift = true; // Задаваемый флаг сдвига ордера extern int TrendMode = 1; //extern bool MACD = true; // Использовать MACD как индикатор тренда //extern bool MA = true; // Использовать MA как индикатор тренда //extern bool Silense = true; // Использовать Silense как индикатор тренда //extern bool iKTrend = true; // Использовать iKTrend как индикатор тренда extern int SilenseLevel = 10; // Перод МА/MACD extern int PeriodMA = 12; // Перод МА/MACD extern int PeriodStoch = 3; // Замедление Stochastic extern double Lots = 1; // Жестко заданное колич. лотов ("0" - советник выбирает сам) //extern int Discret=1; // Дискретность подбора: 1 - каждая позиция; 2 - через позицию и т.д. extern double Stop = 0; extern double Profit = 0; extern int Level = 10; // Минимальный уровень близости к рынку extern datetime StartDateTime = D'01.01.2011'; //Начало работы extern datetime FinishDateTime = D'31.12.2011'; //Конец работы extern double Prots = 0.07; // Процент свободных средств extern int SlipPage = 3; // Проскальзывание котирокок - в пунктах bool MACD = true, MA = true, Silense = true, iKTrend = true, New_Bar=false, // Флаг нового бара End_Bar=false, // Флаг конца бара Cls=false, // Критерий для закрытия Work=true, // Эксперт будет работать. Opn_R=false, // Критерий готовности к открытию ордеров Shift_U=false, // Критерий для сдвига вверх Shift_D=false, // Критерий для сдвига вниз Scalp_Up, TrendUP, TrendDN, // Тренд Вверх, Вниз FMStoch, NMStoch, SMStoch, // Разрешено первое, следующее и второе измерение Стохастика AllowBuy, AllowSell, // Разрешено покупать, продавать AllowFindForw, AllowFindBack, // Разрешить поик Вперед, Назад AllowFindTralingStop=false, // Разрешить поиск ТрейлингСтопа AllowEsc =false, // Разрешить сброс после закрытия ордера EscStoch =false, EscMACD =false, EscMA =false, EcsSilense =false, EcsSiKTrend =false, Tag_msg1=false, // Флаг сообщения 1 Tag_msg2=false, // Флаг сообщения 2 Tag_msg3=true; string Symb; // Название финанс. инструмента static datetime New_Time; int MaxLength = 30, // К-во обрабатываемых варов NPeriod, NNPeriod; // Следующий и после-следующий период double TakeProfit =10, // ТР для открываемого ордера StopLoss =10, // SL для открываемого ордера OpenLevelUP, OpenLevelDN, // Уровень для открытия Вверх, Вниз StopTradeLevelUP, StopTradeLevelDN, // Уровень включения СтопТрейда Вверх, Вниз StopTradeUP, StopTradeDN, // СтопТрейда Вверх, Вниз algoritm = NONE, // Алгоритм: ">0" - "сегодня как вчера"; "<0" - "сегодня не как вчера" sum_TP, // Ожидаемая адаптированная сумма дохода dirOpen = NONE, // Направление текущее : ">0" - купить; "<0" - продать Trade2 = NONE, // Направление торговли в текущем ТФ на 1-ом баре MACD1 = NONE, // MACD0 = NONE, // MA0 = NONE, // MA1 = NONE, // iK0 = NONE, Silense0= NONE, Silense1= NONE, StochM = NONE, StochM1 = NONE, StochS = NONE, ScalpLevel, // now_direction = NONE, // Направление настоящее: ">0" - купить; "<0" - продать // Level, // Минимальный уровень SL/TP // Discret, // Дискретность подбора: 1 - каждая позиция; 2 - через позицию и т.д. New_Open, // Достигнутый уровень цены New_SL, // Уровень закрытия ордера index_1=2, // Множитель 1 для сдвига index_2; // Множитель 2 для сдвига //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { Fun_New_Bar(); // Определение начала нового бара //---- int Total, // Количество ордеров в окне Tip=-1, // Тип выбран. ордера (B=0,S=1) Ticket; // Номер ордера datetime Time_Begin, // Момент начала рабочего периода Op_Time; // Время открытия ордера double Lot, // Колич. лотов в выбранном ордере Lts, // Колич. лотов в открываемом ордере Min_Lot, // Минимальное количество лотов Step, // Шаг изменения размера лота Free, // Текущие свободные средства One_Lot, // Стоимость одного лота Price, // Цена выбранного ордера SL, // SL выбранного ордера TP; // TP выбранного ордера bool Ans =false, // Ответ сервера после закрытия Opn_B=false, // Критерий для открытия Buy Opn_S=false; // Критерий для открытия Sell Cls =false; // Критерий для закрытия Time_Begin=GetTickCount(); // засекаем начало выполнения программы //------------------- Один раз за период -- if (New_Bar) // Один раз за период выполняется следующее { Tag_msg1=true; End_Bar=false; // Opn_R=true; // Предварит.обработка if(TimeCurrent()=FinishDateTime) //Время финиша наступило { Alert("Время финиша наступило. Эксперт не работает.",": ",Symb,", ",Period()); return; // Выход из start() } if(Bars < MaxLength) // Недостаточно баров { Alert("Недостаточно баров в окне. Эксперт не работает.",": ",Symb,", ",Period()); return; // Выход из start() } if(Work==false) // Критическая ошибка { Alert("Критическая ошибка. Эксперт не работает.",": ",Symb,", ",Period()); return; // Выход из start() } } //------------------- Конец один раз за период -- if ((TimeCurrent()-Time[0]-50)>(Period()-1)*60 //За 10 секунд до начала периода && Tag_msg1 ) { // Alert("Внимание! Начинается новый период!",": ",Symb,", ",Period()); Tag_msg1=false; End_Bar=true; } //----------------------- Учёт ордеров Symb=Symbol(); // Название фин.инстр. Total=0; // Количество ордеров for(int i=1; i<=OrdersTotal(); i++) // Цикл перебора ордер { if (OrderSelect(i-1,SELECT_BY_POS)==true) // Если есть следующий { // Анализ ордеров: if (OrderSymbol()!=Symb)continue; // Не наш фин. инструм if (OrderType()>1) // Попался отложенный { Alert("Обнаружен отложенный ордер. Эксперт не работает.",": ",Symb,", ",Period()); return; // Выход из start() } Total++; // Счётчик рыночн. орд if (Total>1) // Не более одного орд { Alert("Несколько рыночных ордеров. Эксперт не работает.",": ",Symb,", ",Period()); return; // Выход из start() } Ticket =OrderTicket(); // Номер выбранн. орд. Op_Time=OrderOpenTime(); // Время открытия выбр.орд. Tip =OrderType(); // Тип выбранного орд. Price =OrderOpenPrice(); // Цена выбранн. орд. SL =OrderStopLoss(); // SL выбранного орд. TP =OrderTakeProfit(); // TP выбранного орд. Lot =OrderLots(); // Количество лотов } } if (New_Bar) // В начале нового периода { if (Total==0) // Если нет открытых ордеров Opn_R=true; // разрешить открытие ордер else // если ордер был открыт Opn_R=false; // запретить открытие (при закрытии терминалом) } if (Total==0) // Если нет открытых ордеров { Cls=false; // Ещё нечего закрывать Shift_U=false; // Обнуляем критерий для сдвига вверх Shift_D=false; // Обнуляем критерий для сдвига вниз ObjectDelete("New_Open"); // Одаляем линии ObjectDelete("New_SL"); // NextTrade = iCustom(0, 0, "iK_trend_v01.6",PeriodMA,History,VerExtr,4,NextPeriod, 3, 0); } //---- Исходные данные if(MACD) { MACD0 = iMACD(0,NNPeriod,PeriodMA,PeriodMA*2,9,PRICE_MEDIAN,MODE_MAIN,0); MACD1 = iMACD(0,NNPeriod,PeriodMA,PeriodMA*2,9,PRICE_MEDIAN,MODE_MAIN,1); } if(MA) { MA0 = iMA(0,NNPeriod,PeriodMA,0,MODE_EMA,PRICE_MEDIAN,0); MA1 = iMA(0,NNPeriod,PeriodMA,0,MODE_EMA,PRICE_MEDIAN,1); } if(Silense) { Silense0 = iCustom(0, NNPeriod, "Silense",PeriodMA,288, 1, 0); Silense1 = iCustom(0, NNPeriod, "Silense",PeriodMA,288, 1, 1); } if(iKTrend) iK0= iCustom(0, NNPeriod, "iK_trend_v01.6",PeriodMA,100,4,4,0, 2, 0); StochM = iStochastic(0,NPeriod,5,3,PeriodStoch,MODE_EMA,0,MODE_MAIN,0); StochM1 = iStochastic(0,NPeriod,5,3,PeriodStoch,MODE_EMA,0,MODE_MAIN,1); StochS = iStochastic(0,NPeriod,5,3,PeriodStoch,MODE_EMA,0,MODE_SIGNAL,0); //---- Сброс после закрытия ордера if(AllowEsc && Total==0) {AllowEsc=false; TrendUP=false; TrendDN=false; AllowFindForw=false; } //---- Сброс при начале или изменении тренда if(Total==0) { if((AllowBuy && BidStopLoss)) EscStoch=true; if(MACD &&((MACD0>MACD1 && TrendDN) ||(MACD0MACD1) ||(!TrendUP && !TrendDN && MACD0MA1 && TrendDN) ||(MA0MA1) ||(!TrendUP && !TrendDN && MA0Silense1 && Silense0>SilenseLevel) ||(!MACD && MA && Silense && MA0Silense1 && Silense0>SilenseLevel) ||(MACD && MA && Silense && MACD0Silense1 && Silense0>SilenseLevel) ||(iKTrend && !Silense && iK0<0) ||(iKTrend && Silense && iK0<0 && Silense0>Silense1 && Silense0>SilenseLevel))) {TrendDN=true; TrendUP=false; ObjectDelete("TrendDN"); ObjectCreate("TrendDN",OBJ_VLINE,0,Time[0],0); ObjectSet("TrendDN",OBJPROP_COLOR,Red); } else if((MACD && !MA && !Silense && MACD0==MACD1) ||(MA && !MACD && !Silense && MA0==MA1) ||(MACD && MA && !Silense && MACD0MA1) ||(MACD && MA && !Silense && MACD0>MACD1 && MA0MA1) || Silense0<=Silense1)) ||(MACD && MA && Silense && ((MACD0>MACD1 && MA0StochS) || (TrendDN && StochMStochS))) {SMStoch=true; NMStoch=false; OpenLevelDN=0.99*Low[0]; OpenLevelUP=1.01*High[0]; } if(SMStoch) //Это основная волна {if(TrendUP && StochM<=80 && StochM>StochM1) AllowBuy=true; else if(TrendDN && StochM>=20 && StochMHigh[iHighest(NULL,0,MODE_HIGH,3,1)]) {OpenLevelUP=High[iHighest(NULL,0,MODE_HIGH,3,1)]; StopLoss=OpenLevelUP; AllowFindBack=true; } if(TrendDN) //Для входа по SELL if(iLowest(NULL,0,MODE_LOW,3,1)==2 && !(iHighest(NULL,0,MODE_HIGH,3,1)==2) && OpenLevelDNLow[i]) StopLoss=Low[i]; else {AllowFindBack=false; AllowFindForw=true; break; } } if(TrendDN) for(i=3; i<20; i++) { if(StopLossLow[0]) StopLoss=Low[0]; if(TrendDN) if(StopLossStopTradeLevelUP) {StopLoss=Price + SlipPage*Point; AllowFindTralingStop=true; AllowFindForw=false; } if(Tip==1 && BidHigh[iHighest(NULL,0,MODE_HIGH,3,1)]) StopLoss=High[iHighest(NULL,0,MODE_HIGH,3,1)]; if(Tip==0) if(iLowest(NULL,0,MODE_LOW,3,1)==2 && StopLossStopLoss)) { Cls = true; // надо закрывать ордер Opn_R=false; // до начала нового периода ордеров не открывать } //---- Условия открытия ордера if(Total==0 // открытых ордеров нет, && AllowFindForw && Opn_R) // ордер в этом периоде ещё не открывался { if(AllowBuy && Ask>OpenLevelUP) Opn_B=true; // надо открывать ордер на Buy if(AllowSell && Bid 0) // Если заданы лоты,то Lts =Lots; // с ними и работаем else // % свободных средств Lts=MathFloor(Free*Prots/One_Lot/Step)*Step;// Для открытия if(Lts < Min_Lot) Lts=Min_Lot; // Не меньше минимальн if (Lts*One_Lot > Free && // Лот дороже свободн. TimeCurrent()<(Time[0] + 2*60) && // не прошло ещё более 2-х минут Total==0) // и ордер не открыт { Alert(" Не хватает денег на ", Lts," лот",": ",Symb,", ",Period()); return; // Выход из start() } //--------------------------------------------------------------- 6 -- // Закрытие ордеров while(Ticket>0) // Цикл закрытия орд. { if(Tip==0 && Cls==true) // Открыт ордер Buy.. { // и есть критерий закр Alert("Попытка закрыть Buy: ",Symb,", ",Period()); RefreshRates(); // Обновление данных Ans=OrderClose(Ticket,Lot,Bid,2,Blue); // Закрытие Buy if(Ans==true) // Получилось :) break; // Выход из цикла закр if(Fun_Error(GetLastError())==1) // Обработка ошибок { // Opn_R=false; // до начала нового периода ордеров не открывать Opn_R=true; // можно снова открывать continue; // Повторная попытка } return; // Выход из start() } if(Tip==1 && Cls==true) // Открыт ордер Sell.. { // и есть критерий закр Alert("Попытка закрыть Sell: ",Symb,", ",Period()); RefreshRates(); // Обновление данных Ans=OrderClose(Ticket,Lot,Ask,2,Red); // Закрытие Sell if(Ans==true) // Получилось :) break; // Выход из цикла закр if(Fun_Error(GetLastError())==1) // Обработка ошибок { // Opn_R=false; // до начала нового периода ордеров не открывать Opn_R=true; // можно снова открывать continue; // Повторная попытка } return; // Выход из start() } break; // Выход из while } //---- Установим СтопЛосс и ТейкПрофит if(Opn_B) { if(Stop==0) SL=Ask-New_Stop((Ask-StopLoss)/Point)*Point; else if((Ask-StopLoss)/Point>Stop) SL=Ask - New_Stop(Stop)*Point; else SL=StopLoss; if(Profit==0) if(Shift) TP=Ask+100*(Ask-StopLoss); else TP=Ask+New_Stop(2.5*(Ask-StopLoss)/Point)*Point; } if(Opn_S) { if(Stop==0) SL=Bid+New_Stop((StopLoss-Bid)/Point)*Point; else if((StopLoss-Bid)/Point>Stop) SL=Bid+New_Stop(Stop)*Point; else SL=StopLoss; if(Profit==0) if(Shift) TP=Bid-100*(StopLoss-Bid); else TP=Bid-New_Stop(2.5*(StopLoss-Bid)/Point)*Point; } //---- Открытие ордеров while(Opn_R) // Цикл открытия орд. { if(Total==0 && Opn_B==true) // Открытых орд. нет + { // критерий откр. Buy RefreshRates(); // Обновление данных Alert("Попытка открыть Buy: ",Symb,", ",Period()); Ticket=OrderSend(Symb,OP_BUY,Lts,Ask,2,SL,TP,0,0,0,Blue);//Открытие Buy if(Ticket > 0) // Получилось :) {AllowEsc=true; return; // Выход из start() } if(Fun_Error(GetLastError())==1) // Обработка ошибок continue; // Повторная попытка return; // Выход из start() } if(Total==0 && Opn_S==true) // Открытых орд. нет + { // критерий откр. Sell RefreshRates(); // Обновление данных Alert("Попытка открыть Sell: ",Symb,", ",Period()); Ticket=OrderSend(Symb,OP_SELL,Lts,Bid,2,SL,TP,0,0,0,Red);//Открытие Sel if(Ticket > 0) // Получилось :) {AllowEsc=true; return; // Выход из start() } if(Fun_Error(GetLastError())==1) // Обработка ошибок continue; // Повторная попытка return; // Выход из start() } break; // Выход из while } //---- return; // Выход из start() } //-------------------------------------------------------------- 10 -- int Fun_Error(int Error) // Ф-ия обработ ошибок { switch(Error) { // Преодолимые ошибки case 4: Alert("Торговый сервер занят. Пробуем ещё раз..",": ",Symb,", ",Period()); Sleep(3000); // Простое решение return(1); // Выход из функции case 128: Alert("Истек срок ожидания..",": ",Symb,", ",Period()); return(1); // Выход из функции case 130:Alert("Слишком близко стопы",": ",Level,", ",Symb,", ",Period()); if (Point==0.0001) Level++; else Level=Level+10; // Прирастить минимальный уровень SL/TP Opn_R=false; // Ордеров в этом периоде не открывать // Sleep(5000); // Простое решение return(1); // Выход из функции case 135:Alert("Цена изменилась. Пробуем ещё раз..",": ",Symb,", ",Period()); RefreshRates(); // Обновим данные return(1); // Выход из функции case 136:Alert("Нет цен. Ждём новый тик..",": ",Symb,", ",Period()); while(RefreshRates()==false) // До нового тика Sleep(1); // Задержка в цикле return(1); // Выход из функции case 137:Alert("Брокер занят. Пробуем ещё раз..",": ",Symb,", ",Period()); Sleep(3000); // Простое решение return(1); // Выход из функции case 138:Alert("Запрошенная цена устарела..",": ",Symb,", ",Period()); return(1); // Выход из функции case 145:Alert("Ордер слишком близок к рынку . Пробуем через 15сек.",": ",Symb,", ",Period()); Cls = false; // Sleep(15000); // Простое решение return(1); // Выход из функции case 146:Alert("Подсистема торговли занята. Пробуем ещё..",": ",Symb,", ",Period()); Sleep(500); // Простое решение return(1); // Выход из функции // Критические ошибки case 2: Alert("Общая ошибка.",": ",Symb,", ",Period()); return(0); // Выход из функции case 5: Alert("Старая версия терминала.",": ",Symb,", ",Period()); Work=false; // Больше не работать return(0); // Выход из функции case 64: Alert("Счет заблокирован.",": ",Symb,", ",Period()); Work=false; // Больше не работать return(0); // Выход из функции case 133:Alert("Торговля запрещена.",": ",Symb,", ",Period()); return(0); // Выход из функции case 134:Alert("Недостаточно денег для совершения операции.",": ",Symb,", ",Period()); return(0); // Выход из функции default: Alert("Возникла ошибка ",Error,": ",Symb,", ",Period()); // Другие варианты return(0); // Выход из функции } } //-------------------------------------------------------------- 11 -- int New_Stop(int Parametr) // Проверка стоп-прик. { int Min_Dist=MarketInfo(Symbol(),MODE_STOPLEVEL)+MarketInfo(Symbol(), MODE_SPREAD)+SlipPage;// Миним. дистанция if (Parametr < Min_Dist) // Если меньше допуст. { Parametr=Min_Dist; // Установим допуст. } return(Parametr); // Возврат значения } //+------------------------------------------------------------------+ void Fun_New_Bar() // Ф-ия обнаружения нового бара { New_Bar=false; // Нового бара нет if(New_Time!=Time[0]) // Сравниваем время { New_Time=Time[0]; // Теперь время такое New_Bar=true; // Поймался новый бар } } //-------------------------------------------------------------- 12 -- //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { Tag_msg1=true; // Флаг сообщения 1 New_Time=Time[0]; // Время текущего бара switch (Period()) // Установка NextPeriod { case 1: NPeriod = 5; NNPeriod = 30; break; // Период 1-но минутный case 5: NPeriod = 30; NNPeriod = 240; break; // Период 5-ти минутный case 15: NPeriod = 30; NNPeriod = 240; break; // Период 15-ти минутный case 30: NPeriod = 240; NNPeriod = 1440; break; // Период 30-ти минутный case 60: NPeriod = 240; NNPeriod = 1440; break; // Период часовой case 240: NPeriod = 1440; NNPeriod = 10080; break; // Период 4-х часовой case 1440: NPeriod = 10080; NNPeriod = 43200; break; // Период дневной default: break; } switch (TrendMode) { case 1: MACD=true; MA=true; Silense=false; iKTrend=false; break; case 2: MACD=true; MA=false; Silense=false; iKTrend=false; break; case 3: MACD=false; MA=true; Silense=false; iKTrend=false; break; case 4: MACD=true; MA=true; Silense=true; iKTrend=false; break; case 5: MACD=true; MA=false; Silense=true; iKTrend=false; break; case 6: MACD=false; MA=true; Silense=true; iKTrend=false; break; case 7: MACD=false; MA=false; Silense=false; iKTrend=true; break; case 8: MACD=false; MA=false; Silense=true; iKTrend=true; break; default: break; } // Учёт ордеров при инициализации int Total, // Количество ордеров в окне Ticket, Tip=-1; // Тип выбран. ордера (B=0,S=1) double TP, SL, Price; // Цена выбранного ордера Symb=Symbol(); // Название фин.инстр. for(int i=1; i<=OrdersTotal(); i++) // Цикл перебора ордер { if (OrderSelect(i-1,SELECT_BY_POS)==true) // Если есть следующий { // Анализ ордеров: if (OrderSymbol()!=Symb)continue; // Не наш фин. инструм if (OrderType()>1) // Попался отложенный { Alert("Обнаружен отложенный ордер. Эксперт не работает.",": ",Symb,", ",Period()); return; // Выход из start() } Total++; // Счётчик рыночн. орд if (Total>1) // Не более одного орд { Alert("Несколько рыночных ордеров. Эксперт не работает.",": ",Symb,", ",Period()); return; // Выход из start() } Ticket =OrderTicket(); // Номер выбранн. орд. Tip =OrderType(); // Тип выбранного орд. Price =OrderOpenPrice(); // Цена выбранн. орд. SL =OrderStopLoss(); // SL выбранного орд. TP =OrderTakeProfit(); // TP выбранного орд. } } if (Level0 // Если есть открытый ордер && !Shift) // И сдвиг не установлен { New_Open=Price; // Вначале уровень цены равен ТР New_SL=SL; // а уровень закрытия равен SL Alert("Инит. Ордер не изменен. TP=",TP,", SL=",SL,": ",Symb,", ",Period()); } if (Ticket>0 // Если есть открытый ордер && Shift) // И установлен сдвиг { // Восстановление ТР при инициализации if (MathAbs(Price-TP)/Point < 500 && Tip==0) TP=Price + New_Stop(TakeProfit+1000)*Point; if (MathAbs(Price-TP)/Point < 500 && Tip==1) TP=Price - New_Stop(TakeProfit+1000)*Point; if (OrderModify(Ticket,Price,SL,TP,0)) { Alert("Инит. Ордер изменен. TP=",TP,", SL=",SL,": ",Symb,", ",Period()); } else { Alert("Инит. Ордер не изменен, ошибка ",GetLastError(),": ",Symb,", ",Period()); } // Установка New_Open и New_SL при инициализации New_Open=0; New_SL=0; if (Tip==0) // ордер открыт на покупку { // разрешен сдвиг New_Open=Price + New_Stop(TakeProfit)*Point; // Вначале уровень цены равен ТР New_SL=SL; // а уровень закрытия равен SL if (Bid>New_Open) // но если сдвиг уже начался { New_Open=Bid; // новый достигнутый уровень цены New_SL=New_Open // новый уровень закрытия ордера -(3*MarketInfo(Symb,MODE_SPREAD)*Point // ниже нового уровня на 2 стоп уровня +index_2*(New_Open-(Price+(TakeProfit // плюс 0.1 (увеличивается) -MarketInfo(Symb, MODE_SPREAD))*Point))); // с учетом спреда } } if (Tip==1) // ордер открыт на покупку { // разрешен сдвиг New_Open=Price - New_Stop(TakeProfit)*Point; // Вначале уровень цены равен ТР New_SL=SL; // а уровень закрытия равен SL if (AskMACD1) || (MA && !MACD && !Silense && MA0>MA1) || (MACD && MA && !Silense && MACD0>MACD1 && MA0>MA1) || (MACD && !MA && Silense && MACD0>MACD1 && Silense0>Silense1 && Silense0>SilenseLevel) || (!MACD && MA && Silense && MA0>MA1 && Silense0>Silense1 && Silense0>SilenseLevel) || (MACD && MA && Silense && MACD0>MACD1 && MA0>MA1 && Silense0>Silense1 && Silense0>SilenseLevel) || (iKTrend && !Silense && iK0>0) || (iKTrend && Silense && iK0>0 && Silense0>Silense1 && Silense0>SilenseLevel)) {TrendUP=true; ObjectDelete("TrendUP"); ObjectCreate("TrendUP",OBJ_VLINE,0,Time[0],0); ObjectSet("TrendUP",OBJPROP_COLOR,Green); } else if((MACD && !MA && !Silense && MACD0Silense1 && Silense0>SilenseLevel) || (!MACD && MA && Silense && MA0Silense1 && Silense0>SilenseLevel) || (MACD && MA && Silense && MACD0Silense1 && Silense0>SilenseLevel) || (iKTrend && !Silense && iK0<0) || (iKTrend && Silense && iK0<0 && Silense0>Silense1 && Silense0>SilenseLevel)) {TrendDN=true; ObjectDelete("TrendDN"); ObjectCreate("TrendDN",OBJ_VLINE,0,Time[0],0); ObjectSet("TrendDN",OBJPROP_COLOR,Red); } else {TrendUP=false; TrendDN=false; ObjectDelete("TrendUP"); ObjectDelete("TrendDN"); } //---- Определим сигнал для входа в рынок StochM = iStochastic(0,NPeriod,5,3,3,MODE_EMA,0,MODE_MAIN,0); StochS = iStochastic(0,NPeriod,5,3,3,MODE_EMA,0,MODE_SIGNAL,0); if((TrendUP && StochM>StochS) // Ждем встречную волну || (TrendDN && StochMStochS)) {FMStoch=false; NMStoch=true; SMStoch=false; } OpenLevelDN=NONE; OpenLevelUP=NONE; //Alert("TrendUP=",TrendUP," TrendDN=",TrendDN," StochM=",StochM," StochS=",StochS," FMStoch=",FMStoch," NMStoch=",NMStoch," SMStoch=",SMStoch); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { // Учёт ордеров при деинициализации int Total, // Количество ордеров в окне Tip=-1, // Тип выбран. ордера (B=0,S=1) Ticket; double TP, SL, Price; // Цена выбранного ордера Symb=Symbol(); // Название фин.инстр. for(int i=1; i<=OrdersTotal(); i++) // Цикл перебора ордер { if (OrderSelect(i-1,SELECT_BY_POS)==true) // Если есть следующий { // Анализ ордеров: if (OrderSymbol()!=Symb)continue; // Не наш фин. инструм if (OrderType()>1) // Попался отложенный { Alert("Обнаружен отложенный ордер. Эксперт не работает.",": ",Symb,", ",Period()); return; // Выход из start() } Total++; // Счётчик рыночн. орд if (Total>1) // Не более одного орд { Alert("Несколько рыночных ордеров. Эксперт не работает.",": ",Symb,", ",Period()); return; // Выход из start() } Ticket =OrderTicket(); // Номер выбранн. орд. Tip =OrderType(); // Тип выбранного орд. Price =OrderOpenPrice(); // Цена выбранн. орд. SL =OrderStopLoss(); // SL выбранного орд. } } if (Ticket>0 // Если есть открытый ордер && Shift) // И установлен сдвиг { //---- ТР для открытого не сдвинутого ордера if (Tip==0 // Если ордер открыт на покупку, && !(Shift_U||Shift_D)) // не начат сдвиг, TP=Ask + New_Stop(TakeProfit)*Point; if (Tip==1 // Если ордер открыт на продажу, && !(Shift_U||Shift_D)) // не начат сдвиг, TP=Bid - New_Stop(TakeProfit)*Point; //---- ТР для открытого и сдвинутого ордера if (Tip==0 // Если ордер открыт на покупку, && (Shift_U||Shift_D)) // начат сдвиг, { TP=New_Open + New_Stop(TakeProfit)*Point; SL=New_SL; } if (Tip==1 // Если ордер открыт на продажу, && (Shift_U||Shift_D)) // начат сдвиг, { TP=New_Open - New_Stop(TakeProfit)*Point; SL=New_SL; } //---- Установить реальный ТР для открытого ордера if (OrderModify(Ticket,Price,SL,TP,0)) { Alert("Деинит. Ордер изменен. TP=",TP,", SL=",SL,": ",Symb,", ",Period()); return; } else { Alert("Деинит. Ордер не изменен, ошибка ",GetLastError(),": ",Symb,", ",Period()); } } // нет открытых ордеров ObjectDelete("New_Open"); ObjectDelete("New_SL"); return(0); }