//+------------------------------------------------------------------+ //| SAR Trading v2.mq4 | //| Copyright © 2005, Cronex. | //| | //+------------------------------------------------------------------+ #property copyright "Copyright © 2006, Cronex" #include #include //---- extern double Lots = 0.1; extern double MaximumLots = 0.5; extern double TakeProfit = 100; extern double StopLoss = 15; extern double TrailingStep = 1; extern double MaximumRisk = 0.025; extern double DecreaseFactor = 20; extern double MAPeriod = 18; extern double MAShift = 2; //---- #define MAGICSAR 19680213 //+------------------------------------------------------------------+ //| Calculate open positions | //+------------------------------------------------------------------+ int CalculateCurrentOrders(string symbol) { int Buys = 0, Sells = 0; //---- for(int i = 0; i < OrdersTotal(); i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) break; //---- if(OrderSymbol() == Symbol() && OrderMagicNumber() == MAGICSAR) { if(OrderType() == OP_BUY) Buys++; //---- if(OrderType()==OP_SELL) Sells++; } } //---- return orders volume if(Buys > 0) return(Buys); else return(-Sells); } //+------------------------------------------------------------------+ //| Calculate optimal lot size | //+------------------------------------------------------------------+ double LotsOptimized() { double Lot = Lots; 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; if(MaximumLots != 0 && Lot > MaximumLots) Lot = MaximumLots; return(Lot); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OrderTrailingStop() { if(StopLoss > 0) { for(int i = 0; i < OrdersTotal(); i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == false) break; if(OrderSymbol() == Symbol() && OrderMagicNumber() == MAGICSAR) { if(OrderType() == OP_BUY) { if(Bid - OrderOpenPrice() > Point*(StopLoss + TrailingStep) && OrderStopLoss() Point*(StopLoss+TrailingStep) && OrderStopLoss() > Ask + Point*(StopLoss + TrailingStep)) ErrorCheckOut(OrderModify(OrderTicket(), 0, Ask + Point*(StopLoss), OrderTakeProfit(), 0, Blue)); } } } } //---- } //+------------------------------------------------------------------+ //| Check for open order conditions | //+------------------------------------------------------------------+ void CheckForOpen() { double SAR,MA; SAR = iSAR(NULL, 0, 0.02, 0.2, 0); MA = iMA(NULL, 0, MAPeriod, MAShift, MODE_SMA, PRICE_MEDIAN, 0); //============================== Покупка ============================ if(SAR < MA || iClose(NULL, 0, MAShift) < MA) { ErrorCheckOut(OrderSend(Symbol(), OP_BUY, LotsOptimized(), Ask, 3, Bid - StopLoss*Point, Ask + TakeProfit*Point, "", MAGICSAR, 0, Lime)); } //============================== Продажа ============================ else if(SAR > MA || iClose(NULL, 0, MAShift) > MA) { ErrorCheckOut(OrderSend(Symbol(), OP_SELL, LotsOptimized(), Bid, 3, Ask + StopLoss*Point, Bid - TakeProfit*Point , "", MAGICSAR, 0, DarkOrange)); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void ErrorCheckOut(bool LastErr) { int Error; if(LastErr != TRUE) { Error = GetLastError(); if(Error != 0) Print("LastError = ",Error," : ",ErrorDescription(Error)); } } //+------------------------------------------------------------------+ //| Start of expert | //+------------------------------------------------------------------+ int start() { if(Bars < 100 || IsTradeAllowed() == false) return; if(CalculateCurrentOrders(Symbol()) == 0) CheckForOpen(); else OrderTrailingStop(); } //+------------------------------------------------------------------+