//+------------------------------------------------------------------+ //| ParabolicSAR_2.mq4 | //+------------------------------------------------------------------+ #include extern int TakeProfit1 = 10; extern int TakeProfit2 = 20; extern int TrailingStop = 5; extern int StopLoss = 200; extern double MaximumRisk = 0.02; extern double DecreaseFactor = 3; extern double ParabilicStep = 0.01; extern double ParabolicMaximum = 0.02; extern int Slippage = 0; int BuyMagic1 = 450; int SellMagic1 = 452; int BuyMagic2 = 460; int SellMagic2 = 462; datetime LastOrderTime = 0; double spread; int comment; string com; //+------------------------------------------------------------------+ //| Start function | //+------------------------------------------------------------------+ void start() { //---- check for history and trading if(Bars < 100 || IsTradeAllowed() == false) return; //---- calculate open orders by current symbol // if (CalculateCurrentOrders(Symbol()) == 0) CheckForOpen(); // else { DoTrail(); //CheckForClose(); } } //+------------------------------------------------------------------+ //| Calculate open positions | //+------------------------------------------------------------------+ int CalculateCurrentOrders(string symbol) { int buys = 0; int sells = 0; for(int i = 0; i < OrdersTotal(); i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) break; if(OrderSymbol() == Symbol() && (OrderMagicNumber() == BuyMagic1 || OrderMagicNumber() == BuyMagic2 || OrderMagicNumber() == SellMagic1 || OrderMagicNumber() == SellMagic2) ) { if (OrderType() == OP_BUY) buys++; if (OrderType() == OP_SELL) sells++; } } //---- return orders count if(buys > 0) return(buys); else return(-sells); } //+------------------------------------------------------------------+ //| Calculate optimal lot size | //+------------------------------------------------------------------+ double LotsOptimized() { double lot=0; int orders=HistoryTotal(); // history orders total int losses=0; // number of losses orders without a break //---- select lot size lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1); //---- calcuulate number of losses orders without a break if (DecreaseFactor>0) { for (int i=orders-1;i>=0;i--) { if (OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; } if (OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue; //---- if (OrderProfit()>0) break; if (OrderProfit()<0) losses++; } if (losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1); } //---- return lot size if (lot<0.1) lot=0.1; return(lot); } //+------------------------------------------------------------------+ //| Check for open order conditions | //+------------------------------------------------------------------+ void CheckForOpen() { //---- go trading only for first tiks of new bar //if (Volume[0]>1) return; //---- get Moving Average double parabolic1, parabolic2; parabolic1 = iSAR(NULL, 0, ParabilicStep, ParabolicMaximum, 0); parabolic2 = iSAR(NULL, 0, ParabilicStep, ParabolicMaximum, 1); int MyOrders = CalculateCurrentOrders(Symbol()); //---- sell conditions if (parabolic2 < Close[1] && parabolic1 > Close[0] && MyOrders >= 0 && Time[0] != LastOrderTime) { //OpenSell(); OpenBuy(); LastOrderTime = Time[0]; } //---- buy conditions if (parabolic2 > Close[1] && parabolic1 < Close[0] && MyOrders <= 0 && Time[0] != LastOrderTime) { //OpenBuy(); OpenSell(); LastOrderTime = Time[0]; } } void OpenBuy() { RefreshRates(); int i; datetime begin; int error; comment=comment+1; com="EA_ord_"+comment; CloseAllSell(); begin = TimeCurrent(); int ticket = OrderSend(Symbol(),OP_BUY, LotsOptimized(), Ask, Slippage,Ask-StopLoss*Point,Ask+TakeProfit1*Point,com, BuyMagic1,0,White); if(ticket == -1) { while(ticket == -1 && TimeCurrent() - begin < 20) { error = GetLastError(); Print("Ошибка открытия ордера BUY №1. " + ErrorDescription(error)); Print("Повтор"); RefreshRates(); ticket = OrderSend(Symbol(),OP_BUY, LotsOptimized(), Ask, Slippage,Ask-StopLoss*Point,Ask+TakeProfit1*Point,com, BuyMagic1,0,White); } if(ticket == -1) { error = GetLastError(); Print("Ошибка открытия ордера BUY №1. " + ErrorDescription(error)); } } // открытие 2-го ордера RefreshRates(); begin = TimeCurrent(); ticket = OrderSend(Symbol(),OP_BUY, LotsOptimized(), Ask, Slippage, Ask-StopLoss*Point, Ask+TakeProfit2*Point,com, BuyMagic2,0,White); if(ticket == -1) { while(ticket == -1 && TimeCurrent() - begin < 20) { error = GetLastError(); Print("Ошибка открытия ордера BUY №2. " + ErrorDescription(error)); Print("Повтор"); RefreshRates(); ticket = OrderSend(Symbol(),OP_BUY, LotsOptimized(),Ask, Slippage,Ask-StopLoss*Point,Ask+TakeProfit2*Point,com, BuyMagic2,0,White); } if(ticket == -1) { error = GetLastError(); Print("Ошибка открытия ордера BUY №2. " + ErrorDescription(error)); } } } void OpenSell() { RefreshRates(); int i; datetime begin; int error; comment=comment+1; com="EA_ord_"+comment; CloseAllBuy(); // открытие 1-го ордера begin = TimeCurrent(); int ticket = OrderSend(Symbol(),OP_SELL, LotsOptimized(),Bid, Slippage,Bid+StopLoss*Point,Bid-TakeProfit1*Point,com, SellMagic1,0,Red); if(ticket == -1) { while(ticket == -1 && TimeCurrent() - begin < 20) { Print("Ошибка открытия ордера SELL №1. " + ErrorDescription(error)); Print("Повтор"); RefreshRates(); ticket = OrderSend(Symbol(),OP_SELL, LotsOptimized(),Bid, Slippage,Bid+StopLoss*Point,Bid-TakeProfit1*Point,com, SellMagic1,0,Red); } if(ticket == -1) { error = GetLastError(); Print("Ошибка открытия ордера SELL №1. " + ErrorDescription(error)); } } // открытие 2-го ордера RefreshRates(); begin = TimeCurrent(); ticket = OrderSend(Symbol(),OP_SELL, LotsOptimized(),Bid, Slippage,Bid+StopLoss*Point,Bid-TakeProfit2*Point,com, SellMagic2,0,Red); if(ticket == -1) { while(ticket == -1 && TimeCurrent() - begin < 20) { Print("Ошибка открытия ордера SELL №2. " + ErrorDescription(error)); Print("Повтор"); RefreshRates(); ticket = OrderSend(Symbol(),OP_SELL, LotsOptimized(),Bid, Slippage,Bid+StopLoss*Point,Bid-TakeProfit2*Point,com, SellMagic2,0,Red); } if(ticket == -1) { error = GetLastError(); Print("Ошибка открытия ордера SELL №2. " + ErrorDescription(error)); } } } void DoTrail() { int modok=0; int i, accTotal=OrdersHistoryTotal(); string ca=com+"[tp]"; for (i = accTotal - 1; i >=0; i--) { OrderSelect(i, SELECT_BY_POS, MODE_HISTORY); if (OrderComment()==ca && OrderSymbol() == Symbol()) { if((OrderMagicNumber() == BuyMagic1 || OrderMagicNumber() == SellMagic1)) { ModifyOrders(TrailingStop); break; } } } } // перетаскиваем СЛ ордеров void ModifyOrders(int TrailingStop) { for (int i=OrdersTotal() - 1; i>=0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { // проверяем только BuyMagic2 и SellMagic2, т.к. BuyMagic1 и SellMagic1 уже должны быть закрыты по ТП if(OrderSymbol() == Symbol() && (OrderMagicNumber() == BuyMagic2 || OrderMagicNumber() == SellMagic2)) { if(OrderType()==OP_BUY) { if(OrderStopLoss() - OrderOpenPrice() < TrailingStop*Point) //if(OrderStopLoss() < OrderOpenPrice()) { if(!OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() + TrailingStop*Point, OrderTakeProfit(), 0, Orange)) { Print("Ошибка модификации ордера #" + OrderTicket() + ". " + ErrorDescription(GetLastError())); } } } else if (OrderType()==OP_SELL) { if(OrderOpenPrice() - OrderStopLoss() < TrailingStop*Point) //if(OrderStopLoss() > OrderOpenPrice()) { if(!OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() - TrailingStop*Point, OrderTakeProfit(), 0, Orange)) { Print("Ошибка модификации ордера #" + OrderTicket() + ". " + ErrorDescription(GetLastError())); } } } } } else { Print("Ошибка выбора ордера. " + ErrorDescription(GetLastError())); } } } void CloseAllSell() { int i; int Orders = OrdersTotal(); bool result; datetime begin; if(Orders > 0) { for(i = Orders-1; i >= 0; i--) { if( OrderSelect(i, SELECT_BY_POS, MODE_TRADES) ) { if(OrderSymbol() == Symbol() && OrderType() == OP_SELL && (OrderMagicNumber() == SellMagic1 || OrderMagicNumber() == SellMagic2)) { begin = TimeCurrent(); result = OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, Yellow); // закрываем все встречные ордера while(!result && TimeCurrent() - begin < 20) { result = OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, Yellow); // закрываем все встречные ордера } if(result) { Print("Ошибка закрытия ордера SELL #" + OrderTicket()); } } } else { Print("Не получилось выбрать открытый ордер."); } } } } void CloseAllBuy() { int i; int Orders = OrdersTotal(); bool result; datetime begin; if(Orders > 0) { for(i = Orders-1; i >= 0; i--) { if( OrderSelect(i, SELECT_BY_POS, MODE_TRADES) ) { if(OrderSymbol() == Symbol() && OrderType() == OP_BUY && (OrderMagicNumber() == BuyMagic1 || OrderMagicNumber() == BuyMagic2)) { begin = TimeCurrent(); result = OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, Yellow); // закрываем все встречные ордера while(!result && TimeCurrent() - begin < 20) { result = OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, Yellow); // закрываем все встречные ордера } if(result) { Print("Ошибка закрытия ордера BUY #" + OrderTicket()); } } } else { Print("Не получилось выбрать открытый ордер."); } } } } void init() { spread = Ask - Bid; return; }