//+------------------------------------------------------------------+ //| Divergence Xpert.mq4 | //| Copyright © 2009, TheXpert | //| theforexpert@gmail.com | //+------------------------------------------------------------------+ #property copyright "Copyright © 2009, TheXpert" #property link "theforexpert@gmail.com" #property copyright "CCI Version - ForTrader.ru" #property link "ftyuriy@gmail.com" extern string Group1 = "Параметры для ордеров"; // magic number needed for filtering orders opened by certain EA extern int Magic = 12345; // lots size of opening orders. If 0 it is counted automatically extern double TradeLots = 0; // risk for automatic lots size counting extern double RiskPercentage = 0; // maximum acceptable slippage for the price extern int Slippage = 3; // maximum loop count for orders opening if failed due to requoting extern int TimesToRepeat = 3; extern string Group3 = "Параметры для стратегии"; extern int CCIPer = 14; extern int BBPer = 20; extern int BBDeviation = 2; extern int Depth = 1; extern int ShowHidden = 0; extern int UseClose = 0; extern int Target = 0; extern int Loss = 500; string symbol; bool CriticalError = false; /// \brief Equal to ternar operator /// needed = Condition ? IfTrue : IfFalse; /// \param IfTrue /// \param IfFalse /// \return matching value from parameters double DoubleIf(bool Condition, double IfTrue, double IfFalse) { if (Condition) return (IfTrue); else return (IfFalse); } void WaitForContext() { while (IsTradeContextBusy()) { Sleep(100); } } void OpenBuy(int MN, int Target, int Loss, double Lot) { int count = 0; while (count < TimesToRepeat) { WaitForContext(); RefreshRates(); double TP = DoubleIf(Target > 0, Ask + Target*Point, 0); double buyfilterband = iBands(NULL,0,BBPer,BBDeviation,0,PRICE_CLOSE,MODE_LOWER,1); double sellfilterband = iBands(NULL,0,BBPer,BBDeviation,0,PRICE_CLOSE,MODE_UPPER,1); double SL = DoubleIf(Loss > 0, Ask - 500*Point, 0); double LotsToBid = DoubleIf(Lot == 0, GetLotsToBid(RiskPercentage), Lot); int res = OrderSend(Symbol(), OP_BUY, LotsToBid, Ask, Slippage, SL, TP, NULL, MN, 0, Blue); if (res > 0) return; count++; } } void OpenSell(int MN, int Target, int Loss, double Lot) { int count = 0; while (count < TimesToRepeat) { WaitForContext(); RefreshRates(); double TP = DoubleIf(Target > 0, Bid - Target*Point, 0); double buyfilterband = iBands(NULL,0,BBPer,BBDeviation,0,PRICE_CLOSE,MODE_LOWER,1); double sellfilterband = iBands(NULL,0,BBPer,BBDeviation,0,PRICE_CLOSE,MODE_UPPER,1); double SL = DoubleIf(Loss > 0, Bid + 500*Point, 0); double LotsToBid = DoubleIf(Lot == 0, GetLotsToBid(RiskPercentage), Lot); int res = OrderSend(Symbol(), OP_SELL, LotsToBid, Bid, Slippage, SL, TP, NULL, MN, 0, Red); if (res > 0) return; count++; } } void CloseSells(int MagicNumber, int Slippage) { for(int i = OrdersTotal() - 1; i >= 0; i--) { // already closed if(OrderSelect(i, SELECT_BY_POS) == false) continue; // not current symbol if(OrderSymbol() != Symbol()) continue; // order was opened in another way if(OrderMagicNumber() != MagicNumber) continue; if(OrderType() == OP_SELL) { int count = 0; while (count < TimesToRepeat) { WaitForContext(); RefreshRates(); if (OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, Red)) { break; } count++; } } } } void CloseBuys(int MagicNumber, int Slippage) { for(int i = OrdersTotal(); i >= 0; i--) { // already closed if(OrderSelect(i, SELECT_BY_POS) == false) continue; // not current symbol if(OrderSymbol() != Symbol()) continue; // order was opened in another way if(OrderMagicNumber() != MagicNumber) continue; if(OrderType() == OP_BUY) { int count = 0; while (count < TimesToRepeat) { WaitForContext(); RefreshRates(); if (OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, Blue)) { break; } count++; } } } } bool GetActiveOrders(int MagicNumber = -1) { for(int i = 0; i < OrdersTotal(); i++) { // already closed if(OrderSelect(i, SELECT_BY_POS) == false) continue; // not current symbol if(OrderSymbol() != Symbol()) continue; // order was opened in another way if(OrderMagicNumber() != MagicNumber && MagicNumber != -1) continue; if(OrderType() == OP_SELL || OrderType() == OP_BUY) { return (true); } } return (false); } int GetOrdersCount(int MagicNumber = -1, int Type = -1, string symb = "") { int count = 0; for(int i = 0; i < OrdersTotal(); i++) { // already closed if(OrderSelect(i, SELECT_BY_POS) == false) continue; // not current symbol if(OrderSymbol() != Symbol() && symb == "") continue; // not specified symbol if(OrderSymbol() != symb && symb != "" && symb != "all") continue; // order was opened in another way if(OrderMagicNumber() != MagicNumber && MagicNumber != -1) continue; if(OrderType() == Type || Type == -1) { count++; } } return (count); } double GetLotsToBid(double RiskPercentage) { double margin = MarketInfo(Symbol(), MODE_MARGINREQUIRED); double minLot = MarketInfo(Symbol(), MODE_MINLOT); double maxLot = MarketInfo(Symbol(), MODE_MAXLOT); double step = MarketInfo(Symbol(), MODE_LOTSTEP); double account = AccountEquity(); double percentage = account*RiskPercentage/100; if (margin*step == 0) return(minLot); double lots = MathRound(percentage/margin/step)*step; if(lots < minLot) { lots = minLot; } if(lots > maxLot) { lots = maxLot; } return (lots); } void Check() { double buy = iCustom(symbol, 0, "Divergence_cci", CCIPer, Depth, ShowHidden, 0, 2, 1); double sell = iCustom(symbol, 0, "Divergence_cci", CCIPer, Depth, ShowHidden, 0, 1, 1); double buyfilterband = iBands(NULL,0,BBPer,BBDeviation,0,PRICE_CLOSE,MODE_LOWER,1); double sellfilterband = iBands(NULL,0,BBPer,BBDeviation,0,PRICE_CLOSE,MODE_UPPER,1); if (buy != EMPTY_VALUE && Low[1]<=buyfilterband) { if (UseClose == 0 || Low[1]<=buyfilterband) CloseSells(Magic, Slippage); if (GetOrdersCount(Magic, OP_BUY) == 0) { OpenBuy(Magic, Target, Loss, TradeLots); } } else if (UseClose == 1 || High[1]>=sellfilterband) { CloseBuys(Magic, Slippage); } if (sell != EMPTY_VALUE && High[1]>=sellfilterband) { if (UseClose == 0 || High[1]>=sellfilterband) CloseBuys(Magic, Slippage); if (GetOrdersCount(Magic, OP_SELL) == 0) { OpenSell(Magic, Target, Loss, TradeLots); } } else if (UseClose == 1 || Low[1]<=buyfilterband) { CloseSells(Magic, Slippage); } } datetime LastTime; int init() { symbol = Symbol(); LastTime = Time[0]; } int start() { if (CriticalError) return(0); if (!IsTradeAllowed()) return(0); double margin = AccountFreeMargin(); double minBet = GetLotsToBid(0)*MarketInfo(symbol, MODE_MARGINREQUIRED); if (!GetActiveOrders(Magic) && minBet > margin) { CriticalError = true; return(0); } if (LastTime < Time[0]) { LastTime = Time[0]; } else { return(0); } Check(); return(0); }