//+------------------------------------------------------------------+ //| Audi-one.mq4 | //| Copyright 2017, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2017, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property strict extern double Lots = 0.01; extern int TakeProfit = 10; extern int Step = 10; extern int Magic = 132; extern int Slip = 2; extern bool Shift = false; extern bool RangeTime = false; extern double RangeStart = 09.00; extern double RangeEnd = 20.00; extern bool Trailing = false; extern bool TP_for_TS = false; extern int TrailStart = 5; extern int TrailStep = 2; int Password =000; int ticketbuy; int ticketsell; int newticketbuy; int newticketsell; int NewTicketOrder; int newticket; bool modi; double BuyPos; double SellPos; double tpBuyNew; double tpSellNew; double tpBuy; double tpSell; double LastLot; double TrallStartUSD; double EndTrall; double ProfitUSD; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { if(Check()==false) // Если условия использования не проходят то завершаем выполнение return (INIT_FAILED); else {if (Digits == 3 || Digits == 5) { TakeProfit *= 10; Step *= 10; Slip *= 10; TrailStart *=10; TrailStep *=10; } return(INIT_SUCCEEDED); } } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { if( AllOrders() == 0) //Проверяем есть ли ордера, если нет,то выставляем две начальных отложки { //-------Значения для функуии траллинг стопа, задаются первоначальные при старте новых отложек TrallStartUSD = NormalizeDouble (MarketInfo (Symbol(),MODE_TICKVALUE)*TrailStart*Lots,2); EndTrall = 0; //---------------------------------------------------------------------------------------------- if ( RangeTime == true ) // Проверяем есть ли у нас ограничение по времени на открытие первых сделок { int Cur_Hour=Hour(); // Серверное время в часах double Cur_Min =Minute(); // Серверное время в минутах double Cur_time=Cur_Hour + Cur_Min/100; // Текущее время RangeStart = NormalizeDouble(RangeStart,2); RangeEnd = NormalizeDouble (RangeEnd,2); if (Cur_time>=RangeStart && Cur_time<=RangeEnd) { bool OFO = OpenFirstOrders(); if(OFO == false) Print("Открытие первого ордера завершилось с ошибкой#",GetLastError()); } } else //Если функция проверки отключена то просто продолжаем открывать ордера { bool OFO = OpenFirstOrders(); if(OFO == false) Print("Открытие первого ордера завершилось с ошибкой#",GetLastError()); } } //Функция открытия первых ордеров завершилась //Проверяем появился ли у нас открытый ордер, и если появился то меняем противополжный отложенный ордер-увеличиваем лот for (int z = OrdersTotal()-1;z>=0; z--) {if (modi == false) { if (OrderSelect(z, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic) { if (OrderType() == OP_BUY || OrderType() == OP_SELL) { if (OrderType() == OP_BUY) // Если у нас появился открытый рыночный ордер BUY то мы удаляем отложенный SellStop и выставляем новый с увеличенным лотом //Удаляем отложенный ордер на продажу----------------------------------------------------------------------------------------- { bool delorder = OrderDelete (ticketsell, Black); if(delorder == false) Print("Удаление отложенного ордера на продажу для дальнейшей модификации завершилось с ошибкой #",GetLastError()); //---------------------------------------------------------------------------------------------------------------------------- //Выставляем новый отложенный ордер на продажу с увеличенным лотом (можно добавить проверку на позицию относительно открытого) if (Shift == true) { SellPos = NormalizeDouble (Bid - Step*Point, Digits); // Определяем позицию для нового ордера SellStop } double NewLotsSell = NormalizeDouble (Lots*2,2); //Оперделяем новый лот продаж в два раза больше первоначального newticketsell = OrderSend (Symbol(), OP_SELLSTOP, NewLotsSell, SellPos,0, 0, 0,"", Magic, 0, Red); // Выставляем первый отложенный ордер на продажу if(newticketsell<=0) {Print("Установка отложенного ордера на продажу с увеличенным лотом завершилось с ошибкой #",GetLastError());} else { modi = true; // Тригер равен одному, больше данный цикл не повторится NewTicketOrder = newticketsell; LastLot = NewLotsSell; } } //---------------------------------------------------------------------------------------------------------------------------- if (OrderType() == OP_SELL) // Если у нас появился открытый рыночный ордер SELL то мы удаляем отложенный BuyStop и выставляем новый с увеличенным лотом //Удаляем отложенный ордер на покупку----------------------------------------------------------------------------------------- { bool delorder = OrderDelete (ticketbuy, Black); if(delorder == false) Print("Удаление отложенного ордера на покупку для дальнейшей модификации завершилось с ошибкой #",GetLastError()); //---------------------------------------------------------------------------------------------------------------------------- //Выставляем новый отложенный ордер на покупку с увеличенным лотом (можно добавить проверку на позицию относительно открытого) if (Shift == true) { BuyPos = NormalizeDouble (Ask + Step*Point, Digits); // Определяем позицию для нового ордера SellStop } double NewLotsBuy = NormalizeDouble (Lots*2,2); //Оперделяем новый лот покупок в два раза больше первоначального newticketbuy = OrderSend (Symbol(), OP_BUYSTOP, NewLotsBuy, BuyPos,0, 0, 0,"", Magic, 0, Blue); // Выставляем первый отложенный ордер на продажу if(newticketbuy<=0) {Print("Установка отложенного ордера на покупку с увеличенным лотом завершилось с ошибкой #",GetLastError());} else { modi = true; // Тригер равен одному, больше данный цикл не повторится NewTicketOrder = newticketbuy; LastLot = NewLotsBuy; } } //------------------------------------------------------------------------------------------------------------------------------ } } } } } //----Дальше следует проверка на трэллинг стоп-------------------------- if (Trailing == false) //Вычисляем тейк профит в валюте депозита--------------------------------------------------------- { double TakeProfitUSD = NormalizeDouble (MarketInfo (Symbol(),MODE_TICKVALUE)*TakeProfit*Lots,2); //Вычисляем значение тейк профита для начальных условий в валюте депозита if ( TakeProfitUSD <= AllProfitUSD()) //Если тэйк профит в валюте депозита равен общей прибыли открытых ордеров, то закрываем все ордера { ProfitUSD = AllProfitUSD(); bool EndAllOrders = CloseAllOrders(); if ( EndAllOrders == true) { Print("Все ордера закрыты!С суммой по всем ордерам = ",ProfitUSD); modi = false; } else Print("Закрытие всех ордеров по тейк профиту прошло с ошибкой #",GetLastError()); } } //Цикл проверки по траллинг стопу----------------------------------------------------------------------------- else { if (TP_for_TS == false) { Trailingf(); } else { Trailingf(); double TakeProfitUSD = NormalizeDouble (MarketInfo (Symbol(),MODE_TICKVALUE)*TakeProfit*Lots,2); //Вычисляем значение тейк профита для начальных условий в валюте депозита if ( TakeProfitUSD <= AllProfitUSD()) //Если тэйк профит в валюте депозита равен общей прибыли открытых ордеров, то закрываем все ордера { bool EndAllOrders = CloseAllOrders(); if ( EndAllOrders == true) { Print("Все ордера закрыты по тейк профиту"); modi = false; } else Print("Закрытие всех ордеров по тейк профиту прошло с ошибкой #",GetLastError()); } } } //--------------------------------------------------------------------------------------------- //Цикл проверки открытия отложенного ордера и выставления нового-------------------------------- if (OrderSelect (NewTicketOrder,SELECT_BY_TICKET)) { if (OrderType() == OP_BUY) { LastLot = NormalizeDouble (LastLot*2,2); //Оперделяем новый лот продаж в два раза больше предыдущего newticket = OrderSend (Symbol(), OP_SELLSTOP, LastLot, SellPos,0, 0, 0,"", Magic, 0, Red); // Выставляем дополнительный отложенный ордер на продажу if(newticket<0) Print("Установка отложенного ордера на продажу с увеличенным лотом завершилось с ошибкой #",GetLastError()); else NewTicketOrder = newticket; } if (OrderType() == OP_SELL) { LastLot = NormalizeDouble (LastLot*2,2); //Оперделяем новый лот покупок в два раза больше предыдущего newticket = OrderSend (Symbol(), OP_BUYSTOP, LastLot, BuyPos,0, 0, 0,"", Magic, 0, Red); // Выставляем дополнительный отложенный ордер на покупку if(newticket<0) Print("Установка отложенного ордера на покупку с увеличенным лотом завершилось с ошибкой #",GetLastError()); else NewTicketOrder = newticket; } } //Закрываем цикл проверки на прибыль и открытия нового ордера и идем на новый тик--------------------------------------------------------- } //+------------------------------------------------------------------+ //Функция подсчета прибыли по всем открытым ордерам в валюте депозита //+------------------------------------------------------------------+ double AllProfitUSD() { double SumProfit = 0; for (int y = OrdersTotal()-1;y>=0; y--) { if (OrderSelect(y, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic) if (OrderType() == OP_BUY || OrderType() == OP_SELL) SumProfit = NormalizeDouble (SumProfit + OrderProfit(), 2); } } return (SumProfit); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //Функция подсчета всех ордеров от советника //+------------------------------------------------------------------+ int AllOrders() { int count = 0; for (int i = OrdersTotal()-1;i>=0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic) count++; } } return (count); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //Функция закрытия всех ордеров //+------------------------------------------------------------------+ bool CloseAllOrders() { bool rez = false; for (int q = OrdersTotal()-1;q>=0; q--) { if (OrderSelect(q, SELECT_BY_POS, MODE_TRADES)) { if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic) { if (OrderType() == OP_BUY || OrderType() == OP_SELL) { //------------------------Закрытие ордера на покупку------------------------------------------------------------------ if (OrderType() == OP_BUY) { int NT = OrderTicket(); double LS = OrderLots(); double CenaBid = NormalizeDouble (MarketInfo(Symbol(), MODE_BID), Digits); bool ClOrder = OrderClose (NT, LS, CenaBid, Slip, Black); if ( ClOrder == true) rez = true; else {Print("Закрытие оредра завершилось с ошибкрой для тикета: ",NT," номер ошибки: ",GetLastError()); rez = false; } } //------------------------Закрытие ордера на продажу------------------------------------------------------------------ else { int NT = OrderTicket(); double LS = OrderLots(); double CenaAsk = NormalizeDouble (MarketInfo(Symbol(), MODE_ASK), Digits); bool ClOrder = OrderClose (NT, LS, CenaAsk, Slip, Black); if ( ClOrder == true) rez = true; else {Print("Закрытие оредра завершилось с ошибкрой для тикета: ",NT," номер ошибки: ",GetLastError()); rez = false; } } } //---------------------------Закрытие отложенных ордеров------------------------------------------------------------------- else { int NT = OrderTicket(); if (OrderDelete (NT)) { Print ("Отложенный ордер успешно удален"); rez = true; } } } } } return (rez); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //Функция открытия первых ордеров //+------------------------------------------------------------------+ bool OpenFirstOrders () { bool otvet; bool otvetbuy = false; bool otvetsell = false; modi = false; BuyPos = NormalizeDouble (Ask + Step*Point, Digits); // Определяем позицию для ордера BuyStop ticketbuy = OrderSend (Symbol(), OP_BUYSTOP, Lots, BuyPos,0, 0, 0,"", Magic, 0, Blue); // Выставляем перый отложенный ордер на покупку if(ticketbuy<0) { Print("Установка первого отложенного ордера для покупки завершилось с ошибкой #",GetLastError()); } else otvetbuy = true; SellPos = NormalizeDouble (Bid - Step*Point, Digits); // Определяем позицию для ордера SellStop ticketsell = OrderSend (Symbol(), OP_SELLSTOP, Lots, SellPos,0, 0, 0,"", Magic, 0, Red); // Выставляем первый отложенный ордер на продажу if(ticketsell<0) { Print("Установка первого отложенного ордера для продажи завершилось с ошибкой #",GetLastError()); } else otvetsell = true; if ( otvetbuy == true && otvetsell == true ) otvet = true; else { Print("OrderSend завершилась с ошибкой для одного из ордеров #",GetLastError()); otvet = false; } return (otvet); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //Функция trailingf //+------------------------------------------------------------------+ void Trailingf() { if (TrallStartUSD <= AllProfitUSD()) { double StepUSDTrall = NormalizeDouble (MarketInfo (Symbol(),MODE_TICKVALUE)*TrailStep*Lots,2); // подсчитываем шаг в валюте депозита TrallStartUSD = NormalizeDouble (TrallStartUSD + StepUSDTrall, 2 ); // переносим значение по траллу в валюте депозита EndTrall = NormalizeDouble (EndTrall + StepUSDTrall,2); // вычисляем значение в валюте депозита для закрытия всех ордеров } if (EndTrall > 0) { if (EndTrall >= AllProfitUSD()) { ProfitUSD = AllProfitUSD(); bool closetrall = CloseAllOrders(); if (closetrall == true) Print ("ВСЕ ордера были закрыты по траллинг стопу с общей прибылью по факту:", ProfitUSD," ожидаемая прибыль : ",EndTrall); } } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //Функция Check () проверка на демосчет и пароль //+------------------------------------------------------------------+ bool Check() // Пользов. функция проверки .. { // .. условий использования if (IsDemo()==true) // Если это демо-счёт, то.. return(true); // .. других ограничений нет int Key=AccountNumber()*3+15112017; // Вычисляем ключ if (Password == Key) // Если пароль верный, то.. return(true); // ..разрешаем работу на реале Alert("Неправильный пароль. Эксперт не работает."); return(false); // Выход из пользов. функции }