//+------------------------------------------------------------------+ //| TP2BreakevenIf.mq4 | //| I_D | //| http://www.mymmk.com/ | //+------------------------------------------------------------------+ #property copyright "I_D" #property link "http://www.mymmk.com/" #property library //+------------------------------------------------------------------+ //| ВЫСТАВЛЕНИЕ ТЕЙКПРОФИТА В БЕЗУБЫТОК + N п. ПРИ ЛОССЕ В Х п. | //| iLoss - лосс, пунктов (вместе со спрэдом), при котором | //| выставляем тейкпрофит в безубыток + iZepoPlus пунктов | //+------------------------------------------------------------------+ void TP2BreakevenIf(int iTicket,int iLoss,int iZepoPlus) { int i; // counter double dBid, dAsk; // проверяем переданные значения if ((iZepoPlus<0) || (iLoss+iZepoPlus=iLoss*Point) OrderModify(iTicket,OrderOpenPrice(),OrderStopLoss(),OrderOpenPrice()+iZepoPlus*Point,OrderExpiration(),Red); } if (OrderType()==OP_SELL) { dAsk = MarketInfo(Symbol(),MODE_ASK); // если текущий курс ниже курса открытия позиции на iLoss пунктов или больше if ((dAsk-OrderOpenPrice())>=iLoss*Point) OrderModify(iTicket,OrderOpenPrice(),OrderStopLoss(),OrderOpenPrice()-iZepoPlus*Point,OrderExpiration(),Blue); } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| ВЫСТАВЛЕНИЕ СТОПЛОССА В БЕЗУБЫТОК + N п. ПРИ ПРОФИТЕ В Х п. | //| iLoss - лосс, пунктов (вместе со спрэдом), при котором | //| выставляем тейкпрофит в безубыток + iZepoPlus пунктов | //+------------------------------------------------------------------+ void SL2BreakevenIf(int iTicket,int iProfit,int iZepoPlus) { int i; // counter double dBid, dAsk; // проверяем переданные значения if ((iZepoPlus<0) || (iProfit-iZepoPlus=iProfit*Point) if (OrderStopLoss()=iProfit*Point) if ((OrderStopLoss()==0) || (OrderStopLoss()>OrderOpenPrice()-iZepoPlus*Point)) OrderModify(iTicket,OrderOpenPrice(),OrderOpenPrice()-iZepoPlus*Point,OrderTakeProfit(),OrderExpiration(),Blue); } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| СПАСАЕМ ПОЗИЦИЮ | //| если для позиции № iTicket по проишествии iBarsInLoss баров | //| стоплосс не был перенесен в безубыток, то: | //| а) если курс в убытке - тейкпрофит на безубыток или, если не | //| можем (б.у. слишком близко к курсу), закрываем позицию; | //| б) если курс в профите - стоплосс в безубыток или, если не | //| можем (б.у. слишком близко к курсу), закрываем позицию. | //| iZepoPlus - расстояние (пунктов) от 0 (безубытка), на котором | //| устанавливаем стоплосс или тейкпрофит | //| Функция срабатывает на открытии нового бара (1 раз/бар) | //+------------------------------------------------------------------+ void SavePos(int iTicket,int iBarsInLoss,int iZepoPlus) { int i; // counter double dBid, dAsk; // проверяем переданные значения if ((iZepoPlus<0) || (iBarsInLoss<1) || (iTicket==0) ||(!OrderSelect(iTicket,SELECT_BY_TICKET))) { Print("*Спасение* позиции функцией SavePos () невозможно из-за некорректности значений переданных ей аргументов."); return(0); } if (OrderType()==OP_BUY) { dBid = MarketInfo(Symbol(),MODE_BID); // если стоплосс длинной позиции ниже курса открытия if (OrderStopLoss()=iBarsInLoss) { // если курс открытия очередного бара в зоне лоссов if (Open[0]<=OrderOpenPrice()) { // пытаемся установить тейкпрофит в безубыток + iZepoPlus пунктов if (!OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderOpenPrice()+iZepoPlus*Point,0,Red)) // если не вышло, закрываемся OrderClose(OrderTicket(),OrderLots(),dBid,3,Red); } // если курс открытия очередного бара в зоне профита if (Open[0]>OrderOpenPrice()) { // пытаемся установить стоплосс в безубыток if (!OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()+iZepoPlus*Point,OrderTakeProfit(),0,Red)) // а если не получилось, закрываем позицию OrderClose(OrderTicket(),OrderLots(),dBid,3,Red); } } } } if (OrderType()==OP_SELL) { dAsk = MarketInfo(Symbol(),MODE_ASK); // если стоплосс короткой позиции выше курса открытия или стоплосс не определён if ((OrderStopLoss()>OrderOpenPrice()) || (OrderStopLoss()==0)) { // и с момента открытия прошло больше iBarsInLoss баров if (iBarShift(Symbol(),0,OrderOpenTime(),false)>=iBarsInLoss) { // если курс открытия очередного бара в зоне лоссов if (Open[0]>=OrderOpenPrice()) { // пытаемся установить тейкпрофит в безубыток + iZepoPlus пунктов if (!OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderOpenPrice()-(iZepoPlus+MarketInfo(Symbol(),MODE_SPREAD))*Point,0,Blue)) // если не вышло, закрываемся OrderClose(OrderTicket(),OrderLots(),dAsk,3,Blue); } // если курс открытия очередного бара в зоне профита if (Open[0]1 | //| точка встречи курса и стоплосса будет смещена в сторону исход- | //| ного положения курса, при коэфф.<1 - наоборот, ближе к исходно- | //| му стоплоссу. | //+------------------------------------------------------------------+ void KillLoss(int iTicket,double dSpeedCoeff) { // проверяем переданные значения if ((iTicket==0) || (!OrderSelect(iTicket,SELECT_BY_TICKET)) || (dSpeedCoeff<0.1)) { Print("Трейлинг функцией KillLoss() невозможен из-за некорректности значений переданных ей аргументов."); return(0); } double dStopPriceDiff; // расстояние (пунктов) между курсом и стоплоссом double dToMove; // кол-во пунктов, на которое следует переместить стоплосс // текущий курс double dBid = MarketInfo(OrderSymbol(),MODE_BID); double dAsk = MarketInfo(OrderSymbol(),MODE_ASK); // текущее расстояние между курсом и стоплоссом if (OrderType()==OP_BUY) dStopPriceDiff = dBid - OrderStopLoss(); if (OrderType()==OP_SELL) dStopPriceDiff = (OrderStopLoss() + MarketInfo(OrderSymbol(),MODE_SPREAD)*MarketInfo(OrderSymbol(),MODE_POINT)) - dAsk; // проверяем, если тикет != тикету, с которым работали раньше, запоминаем текущее расстояние между курсом и стоплоссом if (GlobalVariableGet("zeticket")!=iTicket) { GlobalVariableSet("sldiff",dStopPriceDiff); GlobalVariableSet("zeticket",iTicket); } else { // итак, у нас есть коэффициент ускорения изменения курса // на каждый пункт, который проходит курс в сторону лосса, // мы должны переместить стоплосс ему на встречу на dSpeedCoeff раз пунктов // (например, если лосс увеличился на 3 пункта за тик, dSpeedCoeff = 1.5, то // стоплосс подтягиваем на 3 х 1.5 = 4.5, округляем - 5 п. Если подтянуть не // удаётся (слишком близко), ничего не делаем. Print("dStopPriceDiff: ",dStopPriceDiff,", sldiff: ",GlobalVariableGet("sldiff")); // кол-во пунктов, на которое приблизился курс к стоплоссу с момента предыдущей проверки (тика, по идее) dToMove = (GlobalVariableGet("sldiff") - dStopPriceDiff) / MarketInfo(OrderSymbol(),MODE_POINT); // записываем новое значение, но только если оно уменьшилось if (dStopPriceDiff0) { // стоплосс, соответственно, нужно также передвинуть на такое же расстояние, но с учетом коэфф. ускорения dToMove = MathRound(dToMove * dSpeedCoeff) * MarketInfo(OrderSymbol(),MODE_POINT); Print("dToMove: ",dToMove); // теперь проверим, можем ли мы подтянуть стоплосс на такое расстояние if (OrderType()==OP_BUY) { if (dBid - (OrderStopLoss() + dToMove)>MarketInfo(OrderSymbol(),MODE_STOPLEVEL)* MarketInfo(OrderSymbol(),MODE_POINT)) OrderModify(iTicket,OrderOpenPrice(),OrderStopLoss() + dToMove,OrderTakeProfit(),OrderExpiration()); } if (OrderType()==OP_SELL) { if ((OrderStopLoss() - dToMove) - dAsk>MarketInfo(OrderSymbol(),MODE_STOPLEVEL) * MarketInfo(OrderSymbol(),MODE_POINT)) OrderModify(iTicket,OrderOpenPrice(),OrderStopLoss() - dToMove,OrderTakeProfit(),OrderExpiration()); } } } } //+------------------------------------------------------------------+