//+------------------------------------------------------------------+
//|                                                      T.a.n.d.e.m |
//|                                           Copyright 2012, NikNet |
//|                                               http://www.nik.net |
//+------------------------------------------------------------------+
extern int MagicNumber=0;

extern string t1_="-----[  PA ]-----";
extern int Div=3; // сравнение от деление
extern int BarHistory=200; // кол-во баров

extern string t2_= "-----[Trade]-----";
extern bool Trade=false;
extern int StopLoss=150;
extern int TakeProfit=450;
//extern int DL=40;
//extern int SH=13;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

  }
//+------------------------------------------------------------------+

int day=-1;
int hour=-1;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double BuyLevel=0;
double SellLevel=0;
double BuyStop=0;
double SellStop=0;
bool IsBuyTrade= false;
bool IsSellTrade=false;
double price=0;
double stop=0;
datetime time=0;
int pt=0;
//+------------------------------------------------------------------+
void CloseThisSymbolAll()
  {
   int _ticket=0;
   for(int trade=OrdersTotal()-1; trade>=0; trade--)
     {
      _ticket=OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);

      if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=MagicNumber) continue;

      if(OrderType()==OP_BUY)
         _ticket=OrderClose(OrderTicket(),OrderLots(),Bid,5,Blue);
      if(OrderType()==OP_SELL)
         _ticket=OrderClose(OrderTicket(),OrderLots(),Ask,5,Red);

     }
  }
//+------------------------------------------------------------------+
int Trend(int PERIOD,int startShift)
  {
   double c1 = iClose(Symbol(), PERIOD, startShift+0);
   double c2 = iClose(Symbol(), PERIOD, startShift+1);
   double c3 = iClose(Symbol(), PERIOD, startShift+2);

   if((c1 > c2) && (c2 > c3)) return OP_BUY;
   if((c1 < c2) && (c2 < c3)) return OP_SELL;
   return -1;
  }
//+------------------------------------------------------------------+
void OnTick()
  {

// сброс 
   if(day!=Day())
     {
      day=Day();

      for(int i=1; i<BarHistory; i++)
        {
         if(PA_PinBar(i,Period(),Div,time,price,stop,pt))
           {
            DrawLines("PA_PB_"+TimeToStr(time)+price,time,price,(pt>0 ? clrRed : clrBlue),Period());
           }
        }
     }

   if(PA_PinBar(0,Period(),Div,time,price,stop,pt))
     {
      if((pt>0)) 
        {
         if(SellLevel!=price) 
           {
            SellStop=stop;
            SellLevel=price;
            DrawLines("PA_PB_"+TimeToStr(time)+price,time,price,clrRed,Period());
            IsSellTrade=true;
           }
        }

      if((pt<0)) 
        {
         if(BuyLevel!=price) 
           {
            BuyStop=stop;
            BuyLevel=price;
            DrawLines("PA_PB_"+TimeToStr(time)+price,time,price,clrBlue,Period());
            IsBuyTrade=true;
           }
        }
     }

   if(Trade )
     {
      int stopLossBuy=(Ask-BuyStop)/Point;
      int stopLossSell=(SellStop-Bid)/Point;

      if(IsBuyTrade && ((Ask-BuyLevel)>0.00050) && (iLow(NULL, PERIOD_M1, 1) > BuyLevel) )
        {
         OpenPendingOrder(OP_BUY,0.01,Ask,5,Bid,StopLoss,TakeProfit,"Buy",MagicNumber,0,clrBlue);
         IsBuyTrade=false;
        }

      if(IsSellTrade && ((SellLevel-Bid)>0.0050) && (iHigh(NULL, PERIOD_M1, 1) < SellLevel))
        {
         OpenPendingOrder(OP_SELL,0.01,Bid,5,Ask,StopLoss,TakeProfit,"Sell",MagicNumber,0,clrRed);
         IsSellTrade=false;
        }
     }

   hour=Hour();
  }
//+------------------------------------------------------------------+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// кол-во открытых сделок
int OrdersCount()
  {
   int count=0;
   for(int trade=OrdersTotal()-1; trade>=0; trade--)
     {
      int select=OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);
      if(OrderSymbol()!=Symbol() || OrderMagicNumber()!=MagicNumber) continue;
      if(OrderType()==OP_SELL || OrderType()==OP_BUY) count++;
     }
   return (count);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool PA_PinBar(int iBarStart,int period,int div,datetime &time,double &price,double &stop,int &PinType)
  {
   int cnt=3;

   double openLeft=iOpen(NULL,period,iBarStart+cnt);
   double closeLeft= iClose(NULL, period, iBarStart+cnt);
   double highLeft = iHigh(NULL, period, iBarStart+cnt);
   double lowLeft=iLow(NULL,period,iBarStart+cnt);

// shift2
   double timeMid=iTime(NULL, period, iBarStart+(cnt-1));
   double openMid=iOpen(NULL, period, iBarStart+(cnt-1));
   double closeMid= iClose(NULL, period, iBarStart+(cnt-1));
   double highMid = iHigh(NULL, period, iBarStart+(cnt-1));
   double lowMid=iLow(NULL,period,iBarStart+(cnt-1));

   double openRight=iOpen(NULL,period,iBarStart+(cnt-2));
//double closeRight= iClose(NULL, period, iBarStart+(cnt-2));
   double highRight=iHigh(NULL,period,iBarStart+(cnt-2));
   double lowRight=iLow(NULL,period,iBarStart+(cnt-2));

//double open=Open[0];

// измеряем длину носа
   double hip= closeMid>openMid ? closeMid : openMid;
   double hi = MathAbs(highMid-hip);
// определяем длину тела
   double body=MathAbs(openMid-closeMid);
// измеряем длину шеи
   double lop= closeMid<openMid ? closeMid : openMid;
   double lo =MathAbs(lop-lowMid);


   bool IsBody=body<=(hi/div);

   bool IsUpOwnerTrend=(highLeft<highMid) && (highRight<highMid);
   bool IsPinUp=IsBody && (lo<=(hi/div));

   bool IsLoOwnerTrend=(lowLeft>lowMid) && (lowRight>lowMid);
   bool IsPinLo=IsBody && (hi<=(lo/div));

   if(IsPinUp && IsUpOwnerTrend)
     {
      PinType=1;
      time=timeMid;
      stop=highMid+(10*Point);
      price=lowMid;
      return IsPinUp;
     }

   if(IsPinLo && IsLoOwnerTrend)
     {
      PinType=-1;
      time=timeMid;
      stop=lowMid-(10*Point);
      price=highMid;
      return IsPinLo;
     }

   return false;
  }
//+------------------------------------------------------------------+
void DrawLines(string name,double time,double price,color col,int period)
  {
   int prd=60;

   if(period==PERIOD_M1) prd=60;
   if(period==PERIOD_M5) prd=(60*5);
   if(period==PERIOD_M15) prd=(60*15);
   if(period==PERIOD_M30) prd=(60*30);
   if(period==PERIOD_H1) prd=(60*60) *1;
   if(period==PERIOD_H4) prd=(60*60)*4;
   if(period==PERIOD_D1) prd=(60*60)*24;

   ObjectCreate(name,OBJ_TREND,0,time,price,time+prd,price);

   ObjectSet(name,OBJPROP_COLOR,col);
   ObjectSet(name,OBJPROP_WIDTH,3);
   ObjectSet(name,OBJPROP_STYLE,STYLE_DASHDOT);
   ObjectSet(name,OBJPROP_RAY,false);
   WindowRedraw();
   return;
  }
//+------------------------------------------------------------------+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
double TakeLong(double price,int stop) { if(stop>0) return(price+stop*Point); return(0); }
double TakeShort(double price,int stop) { if(stop==0) return(0); else return(price-stop*Point); }
double StopLong(double price,int stop) { if(stop==0) return(0); else return(price-stop*Point); }
double StopShort(double price,int stop) { if(stop==0) return(0); else return(price+stop*Point); }
// открытие отложенного ордера 
int OpenPendingOrder(int pType,double pLots,double pLevel,int sp,double pr,int sl,int tp,string pComment,int pMagic,int pDatetime,color pColor)
  {
   int ticket=0;
   int err=0;
   int c=0;
   int NumberOfTries=100;
   switch(pType)
     {

      case 2:
         for(c=0; c<NumberOfTries; c++)
           {
            ticket=OrderSend(Symbol(),OP_BUYLIMIT,pLots,pLevel,sp,StopLong(pr,sl),TakeLong(pLevel,tp),pComment,pMagic,pDatetime,pColor);
            err=GetLastError();
            if(err==0/* NO_ERROR */) break;
            if(!(err==4/* SERVER_BUSY */ || err==137/* BROKER_BUSY */ || err==146/* TRADE_CONTEXT_BUSY */ || err==136/* OFF_QUOTES */)) break;
            Sleep(1000);
           }
         break;
      case 4:
         for(c=0; c<NumberOfTries; c++)
           {
            ticket=OrderSend(Symbol(),OP_BUYSTOP,pLots,pLevel,sp,StopLong(pr,sl),TakeLong(pLevel,tp),pComment,pMagic,pDatetime,pColor);
            err=GetLastError();
            if(err==0/* NO_ERROR */) break;
            if(!(err==4/* SERVER_BUSY */ || err==137/* BROKER_BUSY */ || err==146/* TRADE_CONTEXT_BUSY */ || err==136/* OFF_QUOTES */)) break;
            Sleep(5000);
           }
         break;
      case 0:
         for(c=0; c<NumberOfTries; c++)
           {
            RefreshRates();
            ticket=OrderSend(Symbol(),OP_BUY,pLots,NormalizeDouble(Ask,Digits),sp,StopLong(pr,sl),TakeLong(pr,tp),pComment,pMagic,pDatetime,pColor);
            err=GetLastError();
            if(err==0/* NO_ERROR */) break;
            if(!(err==4/* SERVER_BUSY */ || err==137/* BROKER_BUSY */ || err==146/* TRADE_CONTEXT_BUSY */ || err==136/* OFF_QUOTES */)) break;
            Sleep(5000);
           }
         break;
      case 3:
         for(c=0; c<NumberOfTries; c++)
           {
            ticket=OrderSend(Symbol(),OP_SELLLIMIT,pLots,pLevel,sp,StopShort(pr,sl),TakeShort(pLevel,tp),pComment,pMagic,pDatetime,pColor);
            err=GetLastError();
            if(err==0/* NO_ERROR */) break;
            if(!(err==4/* SERVER_BUSY */ || err==137/* BROKER_BUSY */ || err==146/* TRADE_CONTEXT_BUSY */ || err==136/* OFF_QUOTES */)) break;
            Sleep(5000);
           }
         break;
      case 5:
         for(c=0; c<NumberOfTries; c++)
           {
            ticket=OrderSend(Symbol(),OP_SELLSTOP,pLots,pLevel,sp,StopShort(pr,sl),TakeShort(pLevel,tp),pComment,pMagic,pDatetime,pColor);
            err=GetLastError();
            if(err==0/* NO_ERROR */) break;
            if(!(err==4/* SERVER_BUSY */ || err==137/* BROKER_BUSY */ || err==146/* TRADE_CONTEXT_BUSY */ || err==136/* OFF_QUOTES */)) break;
            Sleep(5000);
           }
         break;
      case 1:
         for(c=0; c<NumberOfTries; c++)
           {
            ticket=OrderSend(Symbol(),OP_SELL,pLots,NormalizeDouble(Bid,Digits),sp,StopShort(pr,sl),TakeShort(pr,tp),pComment,pMagic,pDatetime,pColor);
            err=GetLastError();
            if(err==0/* NO_ERROR */) break;
            if(!(err==4/* SERVER_BUSY */ || err==137/* BROKER_BUSY */ || err==146/* TRADE_CONTEXT_BUSY */ || err==136/* OFF_QUOTES */)) break;
            Sleep(5000);
           }
     }
   return (ticket);
  }
//+------------------------------------------------------------------+
