CCI_Reversy 1.1





//+------------------------------------------------------------------+
//|                                                  CCI_Reversy.mq4 |
//|                               Copyright © Evgeniy Trofimov, 2009 |
//|                                   http://vkontakte.ru/id5374887/ |
//+------------------------------------------------------------------+
/*
 ýòîì ïðèìåðå äåìîíñòðèðóåòñÿ âûïîëíåíèå îáðàòíîé çàäà÷è CCI:
Äàíî:
- òåêóùåå ñîñòîÿíèå ðûíêà (High, Low, Close) çà ïåðèîä CCIPeriod
Íàéòè:
- î÷åâèäíóþ öåíó Close, åñëè CCI áóäåò ðàâåí çàäàííîìó ÷èñëó FindCCI.
Óñëîâèå:
- åñëè íàéäåííàÿ öåíà îêàæåòñÿ âûøå îòìåòêè High èëè íèæå Low, òî çíà÷åíèå,
  âîçâðàùàåòñÿ ðàâíûì EMPTY_VALUE, à íà ãðàôèêå íè÷åãî íå îòîáðàæàåòñÿ.
*/
#property copyright "Copyright © Evgeniy Trofimov, 2009"
#property link      "http://vkontakte.ru/id5374887/"
#define mn 20090811
#define Slippage 30
extern int  CCIPeriod = 14;
extern double FindCCI = 100.0;
extern double FilterCCI = 50.0;
extern double Lots=0.1;
extern double Risk=0.03; //risk, if Lots = 0
int      OldTicket, round;
datetime LastTime;
double   minlot, maxlot, stoplimit, spread;
//+------------------------------------------------------------------+
int init(){
   minlot = MarketInfo(Symbol(), MODE_MINLOT);
   maxlot = MarketInfo(Symbol(), MODE_MAXLOT);
   round = MathAbs(MathLog(minlot)/MathLog(10.0))+0.5; //êîýôôèöèåíò îêðóãëåíèÿ ëîòà (òîëüêî äëÿ ýòîãî ñîâåòíèêà)
   stoplimit = (MarketInfo(Symbol(), MODE_STOPLEVEL)+Slippage)*Point;
   spread = MarketInfo(Symbol(), MODE_SPREAD)*Point;
}//init()
//+------------------------------------------------------------------+
int deinit() {
   if(ObjectFind("MyLine")!=-1) ObjectDelete("MyLine");
   Comment("");
   return(0);
}//deinit()
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start() {
   double Price=PriceCCI(FindCCI);
   double CCI=iCCI(NULL,0,CCIPeriod,PRICE_TYPICAL,0);
   double OL = OpenLots(); //îáíîâëåíèå ïåðåìåííîé OldTicket
   double WL;
   if(OL!=0) {
      OrderSelect(OldTicket,SELECT_BY_TICKET);
      if((OrderType()==OP_BUY && CCI<=0) || (OrderType()==OP_SELL && CCI>=0)) {
         CloseAllPozitions();
         return(0);
      }   
      Modify(OldTicket, Price);
   } else {
      WL = WaitedLots();//îáíîâëåíèå ïåðåìåííîé OldTicket
      if(WL!=0){ 
         OrderSelect(OldTicket,SELECT_BY_TICKET);
         if((OrderType()==OP_BUYSTOP && Price<Ask) || (OrderType()==OP_SELLSTOP && Price>Bid)) {
            OrderDelete(OldTicket);
         } else {
            ModifySleep(OldTicket, Price);
         }
      } else {
         if(MathAbs(CCI)>FilterCCI) {
            if(Price>Ask)  BUYSleep(Price, MyLot());
            if(Price<Bid) SELLSleep(Price, MyLot());
         }
      }
   }
   return(0);
} //start()
//+------------------------------------------------------------------+
double PriceCCI(double LevelCCI, int CurrentCandle=0) {
   //Âû÷èñëÿåì òåêóùèé CCI
   double MovBuffer;
   double Price, SummPrice, Abs, SummAbs;
   double K = 0.015;
   int j;
   for(int i=CCIPeriod-1; i>=0; i--) {
      j=i+CurrentCandle;
      Price = (High[j]+Low[j]+Close[j])/3;
      MovBuffer=iMA(NULL,0,CCIPeriod,0,MODE_SMA,PRICE_TYPICAL,CurrentCandle);
      Abs = MathAbs(Price-MovBuffer);
      if(i>0) {
         SummPrice += Price;
         SummAbs += Abs;
      }
   }//Next i
   double CCI = (Price-MovBuffer)/((SummAbs+Abs)*K/CCIPeriod);
   Comment("CCI("+CCIPeriod+") = "+DoubleToStr(CCI,4)+"\nFindCCI = "+DoubleToStr(LevelCCI,1));
   // çàâèñèìîñòè îò çíàêà CCI äëÿ ðàñ÷¸òà íåîáõîäèìîé öåíû èñïîëüçóåòñÿ ñîîòâåòñòâóþùàÿ ôîðìóëà
   double H = High[CurrentCandle];
   double L =  Low[CurrentCandle];
          i = CCIPeriod;
   if(CCI>=0) {
      CCI=LevelCCI;
      Price = -(H*i-L*i*i-H*i*i+L*i-CCI*H*K-CCI*L*K+3*SummPrice*i-
      CCI*3*K*SummPrice+CCI*H*K*i+CCI*L*K*i+CCI*3*K*SummAbs*i)/
      (i-i*i-CCI*K+CCI*K*i);
   } else {
      CCI=-LevelCCI;
      Price = -(H*i-L*i*i-H*i*i+L*i+CCI*H*K+CCI*L*K+3*SummPrice*i+
      CCI*3*K*SummPrice-CCI*H*K*i-CCI*L*K*i+CCI*3*K*SummAbs*i)/
      (i-i*i+CCI*K-CCI*K*i);
   }
   if(ObjectFind("MyLine")!=-1) ObjectDelete("MyLine");
   if(Price>H || Price<L) {
      ObjectCreate("MyLine", OBJ_HLINE, 0, 0,Price);
      ObjectSet("MyLine", OBJPROP_COLOR, Green); 
   } else {
      ObjectCreate("MyLine", OBJ_HLINE, 0, 0,Price);
   }
   return(Price);
}//PriceCCI()
//+------------------------------------------------------------------+
int Modify(int ticket, double sl = 0.0, double tp = 0.0) {
   if(OrderSelect(ticket, SELECT_BY_TICKET)) {
      sl=NormalizeDouble(sl,Digits);
      tp=NormalizeDouble(tp,Digits);
      //if(OrderStopLoss()<sl+Slippage*Point/2 && OrderStopLoss()>sl-Slippage*Point/2
      //&& OrderTakeProfit()<tp+Slippage*Point/2 && OrderTakeProfit()>tp-Slippage*Point/2) return(0);
      if(OrderType()==OP_BUY) {
         if(sl>0) {
            if(OrderStopLoss()>0)
               if(OrderStopLoss()+Slippage*Point>=sl) return(0);
            if(Bid-sl<stoplimit) return(0);
         }
         if(tp>0) if(tp-Ask<stoplimit) return(0);
      } else if(OrderType()==OP_SELL) {
         if(sl>0) {
            if(OrderStopLoss()>0)
               if(OrderStopLoss()-Slippage*Point<=sl) return(0);
            if(sl-Ask<stoplimit) {
               Print("Ñëèøêîì áëèçêèé ñòîï (",(sl-Ask)/Point," ïóíêòîâ). Òðåáóåòñÿ íå ìåíåå: ", stoplimit/Point);
               return(0);
            }
         }
         if(tp>0) if(Bid-tp<stoplimit) {
            Print("Ñëèøêîì áëèçêèé ïðîôèò (",(Bid-tp)/Point," ïóíêòîâ). Òðåáóåòñÿ íå ìåíåå: ", stoplimit/Point);
            return(0);
         }
      }
      if(sl>0 && tp>0) 
         if(OrderModify(ticket,OrderOpenPrice(), sl, tp, 0)==FALSE) Print("Îøèáêà OrderModify(): ",GetLastError());
      else if(sl>0)
         if(OrderModify(ticket,OrderOpenPrice(), sl, OrderTakeProfit(), 0)==FALSE) Print("Îøèáêà OrderModify(): ",GetLastError());
      else if(tp>0)
         if(OrderModify(ticket,OrderOpenPrice(), OrderStopLoss(), tp, 0)==FALSE) Print("Îøèáêà OrderModify(): ",GetLastError());
   }
   return(0);
}//Modify()
//+------------------------------------------------------------------+
int ModifySleep(int ticket, double price = 0.0, double sl = 0.0, double tp = 0.0) {
// Ìîäèôèêàöèÿ îòëîæåííûõ îðäåðîâ
   if(OrderSelect(ticket, SELECT_BY_TICKET)) {
      price=NormalizeDouble(price,Digits);
      sl=NormalizeDouble(sl,Digits);
      tp=NormalizeDouble(tp,Digits);
      //if(OrderOpenPrice()==price && OrderStopLoss()==sl && OrderTakeProfit()==tp) return(0);
      if(OrderStopLoss()<sl+Slippage*Point/2 && OrderStopLoss()>sl-Slippage*Point/2
      && OrderTakeProfit()<tp+Slippage*Point/2 && OrderTakeProfit()>tp-Slippage*Point/2
      && OrderOpenPrice()<price+Slippage*Point/2 && OrderOpenPrice()>price-Slippage*Point/2) return(0);
      if(OrderType()==OP_BUYSTOP) {
         if(price-Ask<stoplimit) return(0);
         if(sl>0) if(price-spread-sl<stoplimit) return(0);
         if(tp>0) if(tp-price<stoplimit) return(0);
      } else if(OrderType()==OP_SELLSTOP) {
         if(Bid-price<stoplimit) return(0);
         if(sl>0) if(sl-price-spread<stoplimit) return(0);
         if(tp>0) if(price-tp<stoplimit) return(0);
      }
      if(OrderModify(ticket, price, sl, tp, 0)==FALSE) Print("Îøèáêà OrderModify(): ",GetLastError());
   }   
   return(0);
}//ModifySleep()
//+------------------------------------------------------------------+
double OpenLots(){
   //Ôóíêöèÿ âîçâðàùàåò îòêðûòûé îáúåì âñåõ ñäåëîê ïî òåêóùåìó èíñòðóìåíòó
   double j;
   OldTicket=0;
   int total = OrdersTotal();
   for (int i = 0; i < total; i++) {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == mn) {
         if(OldTicket==0) OldTicket=OrderTicket();
         if(OrderType()==OP_BUY) {
            j=j+OrderLots();
         } else if(OrderType()==OP_SELL) {
            j=j-OrderLots();
         }
      }
   }
   return(j);
}//OpenLots()
//+------------------------------------------------------------------+
int WaitedLots(){
   //Ôóíêöèÿ âîçâðàùàåò êîëè÷åñòâî îòëîæåííûõ îðäåðîâ
   int j=0;
   OldTicket=0;
   int total = OrdersTotal();
   for (int i = 0; i < total; i++) {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == mn) {
         if(OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP) {
            if(OldTicket==0) OldTicket=OrderTicket();
            j++;
         }
      }
   }
   return(j);
}//WaitedLots()
//+------------------------------------------------------------------+
int BUYSleep(double price, double lt, double sl=0, double tp=0) {
// Ñîçäàíèå îòëîæåííûõ îðäåðîâ íà ïîêóïêó (òåêóùàÿ öåíà íèæå price)
   int ticket = -1; //ïîêóïàåì ïî öåíå Ask
   Print("Ïîïûòêà ñîçäàòü îòëîæåííûé îðäåð íà ïîêóïêó ïî öåíå ",price,", sl=",sl,", tp=",tp,", Ask=",Ask,", Bid=", Bid);
   price=NormalizeDouble(price,Digits);
   if(price-Ask<stoplimit) {
      Print("Ïðåâûøåíà ìèíèìàëüíàÿ ãðàíèöà âûñòàâëåíèÿ îòëîæåííîãî îðäåðà íà ïîêóïêó ïî öåíå îòêðûòèÿ");
      Print("Ìèíèìàëüíàÿ ãðàíèöà ",stoplimit/Point, " ïóíêòîâ");
      return(0);
   }
   if(sl>0) {
      sl=NormalizeDouble(sl,Digits);
      if(price-spread-sl<stoplimit) {
         Print("BUYSleep: Íåïðàâèëüíàÿ ãðàíèöà StopLoss. Ìèíèìóì: ",stoplimit/Point, " ïóíêòîâ îò öåíû Bid");
         return(0);
      }
   }
   if(tp>0) {
      tp=NormalizeDouble(tp,Digits);
      if(tp-price<stoplimit) {
         Print("BUYSleep: Íåïðàâèëüíàÿ ãðàíèöà TakeProfit. Ìèíèìóì: ",stoplimit/Point, " ïóíêòîâ îò öåíû Ask");
         return(0);
      }
   }
   ticket = OrderSend(Symbol(), OP_BUYSTOP, lt, price, Slippage, sl, tp, WindowExpertName(), mn, 0, Blue); 
   if (ticket > 0) Sleep(10000);
   return(ticket);
}//BUYSleep()
//+------------------------------------------------------------------+
int SELLSleep(double price, double lt, double sl=0, double tp=0) {
// Ñîçäàíèå îòëîæåííûõ îðäåðîâ íà ïðîäàæó (òåêóùàÿ öåíà âûøå price)
   int ticket = -1; //ïðîäà¸ì ïî öåíå Bid
   Print("Ïîïûòêà ñîçäàòü îòëîæåííûé îðäåð íà ïðîäàæó ïî öåíå ",price,", sl=",sl,", tp=",tp,", Ask=",Ask,", Bid=", Bid);   
   price=NormalizeDouble(price,Digits);
   if(Bid-price<stoplimit) {
      Print("Ïðåâûøåíà ìèíèìàëüíàÿ ãðàíèöà âûñòàâëåíèÿ îòëîæåííîãî îðäåðà íà ïðîäàæó ïî öåíå îòêðûòèÿ");
      Print("Ìèíèìàëüíàÿ ãðàíèöà ",stoplimit/Point, " ïóíêòîâ");
      return(0);
   }
   if(sl>0) {
      sl=NormalizeDouble(sl,Digits);
      if(sl-price-spread<stoplimit) {
         Print("SELLSleep: Íåïðàâèëüíàÿ ãðàíèöà StopLoss. Ìèíèìóì: ",stoplimit/Point, " ïóíêòîâ îò öåíû Bid");
         return(0);
      }
   }
   if(tp>0) {
      tp=NormalizeDouble(tp,Digits);
      if(price-tp<stoplimit) {
         Print("SELLSleep: Íåïðàâèëüíàÿ ãðàíèöà TakeProfit. Ìèíèìóì: ",stoplimit/Point, " ïóíêòîâ îò öåíû Ask");
         return(0);
      }
   }
   ticket = OrderSend(Symbol(), OP_SELLSTOP, lt, price, Slippage, sl, tp, WindowExpertName(), mn, 0, Red); 
   if (ticket > 0) Sleep(10000);
   return(ticket);
}//SELLSleep()
//+------------------------------------------------------------------+
double MyLot(int SL_pips=0) {
   if(SL_pips==0) SL_pips=10000;
   if(Lots>0) return(Lots);
   double MINLOTS = MarketInfo(Symbol(), MODE_MINLOT);
   double MAXLOTS = MarketInfo(Symbol(), MODE_MAXLOT);
   double LOTVAL  = MarketInfo(Symbol(), MODE_TICKVALUE);
   if(MAXLOTS>AccountFreeMargin()*0.99/MarketInfo(Symbol(),MODE_MARGINREQUIRED))//ãäå 0.99 - êîýôôèöèåíò çàïàñà
      MAXLOTS=AccountFreeMargin()*0.99/MarketInfo(Symbol(),MODE_MARGINREQUIRED);
   double round = MathAbs(MathLog(MarketInfo(Symbol(), MODE_LOTSTEP))/MathLog(10.0))+0.5; //êîýôôèöèåíò îêðóãëåíèÿ ëîòà
   double lot = NormalizeDouble(AccountFreeMargin() * Risk / (SL_pips  * LOTVAL), round);
   if(lot < MINLOTS)
      lot = MINLOTS;
   else if(lot > MAXLOTS)
      lot = MAXLOTS;
   return(lot);   
}//MyLot()
//+------------------------------------------------------------------+
int CloseAllPozitions() {
   int n;
   double PriceClose;
   if(IsTradeAllowed()) {
      int  total = OrdersTotal();
      for (int i = total-1; i >= 0; i--) {
         OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
         if(OrderMagicNumber()==mn && OrderSymbol()==Symbol()) {
            if(OrderType()==OP_BUY) {
               PriceClose=MarketInfo(OrderSymbol(),MODE_BID);
            } else if(OrderType()==OP_SELL) {
               PriceClose=MarketInfo(OrderSymbol(),MODE_ASK);
            }
            n=0;
            while(IsTradeContextBusy() || !IsConnected()) {
               Sleep(2000);
               n++;
               if(n>9) break;
            }
            if(!OrderClose(OrderTicket(),OrderLots(),PriceClose,Slippage))
               Print("Ñòàâêà íå çàêðûâàåòñÿ ïî ïðè÷èíå îøèáêè ¹ ",GetLastError());
         } // Åñëè ñâîé
      } // Next i
   } // Ñîâåòíèêó ìîæíî òîðãîâàòü
   return(0);
}//CloseAllPozitions()






Sample





Analysis



Market Information Used:

Series array that contains close prices for each bar
Series array that contains the highest prices of each bar
Series array that contains the lowest prices of each bar


Indicator Curves created:


Indicators Used:

Commodity channel index
Moving average indicator


Custom Indicators Used:

Order Management characteristics:

It can change open orders parameters, due to possible stepping strategy
Checks for the total of open orders
It automatically opens orders when conditions are reached
It Closes Orders by itself

Other Features: