//+------------------------------------------------------------------+
//|                                              Tim's Engulfing.mq5 |
//|                                                    Joji the Goat |
//|                                 https://www.specterfinancial.com |
//+------------------------------------------------------------------+
#property copyright "Joji"
#property version "1.0"
#include <Trade/Trade.mqh>

CTrade trade;

input double riskPercent = 1.0;
input int InpMagicNumber;
int totalBars;
double slDistance;

int OnInit(){

   totalBars = iBars(_Symbol,PERIOD_CURRENT);

return(INIT_SUCCEEDED);
}



void OnTick(){

   int bars = iBars(_Symbol,PERIOD_CURRENT);
   if(bars > totalBars){
   totalBars = bars;
   double lots;
   int engulfingSignal = getEngulfingSignal();
   if(engulfingSignal < 0){
   Print(__FUNCTION__,"Bearish Buy Signal");
   slDistance = iOpen(_Symbol,PERIOD_CURRENT,1) - iClose(_Symbol,PERIOD_CURRENT,1);
   calcLots();
   lots = calcLots();
   trade.BuyStop(lots,iHigh(_Symbol,PERIOD_CURRENT,1),_Symbol,iLow(_Symbol,PERIOD_CURRENT,1),0,ORDER_TIME_GTC,0,"Engulfing");
   }else if(engulfingSignal > 0){
   Print(__FUNCTION__,"Bullish Sell Signal");
   slDistance = iClose(_Symbol,PERIOD_CURRENT,1) - iOpen(_Symbol,PERIOD_CURRENT,1);
   calcLots();
   lots = calcLots();
   trade.SellStop(lots,iLow(_Symbol,PERIOD_CURRENT,1),_Symbol,iHigh(_Symbol,PERIOD_CURRENT,1),0,ORDER_TIME_GTC,0,"Engulfing");
   }
   }
   
  for(int i = PositionsTotal()-1; i >= 0; i--){
  ulong posTicket = PositionGetTicket(i);
  
   if(PositionSelectByTicket(posTicket)){
      if(PositionGetString(POSITION_SYMBOL)==_Symbol){
      double beSL;
      int n;
      double newSL; 
      double trailSL;
      double bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
      if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){
            n =1;
            beSL = PositionGetDouble(POSITION_PRICE_OPEN);
            newSL = (((PositionGetDouble(POSITION_PRICE_OPEN) - PositionGetDouble(POSITION_SL)) * n));
            if(bid > (beSL + newSL)){
         
               if(trade.PositionModify(posTicket,beSL,0)){
                     Print(__FUNCTION__, "Position was modified");
      }
            if(bid > (beSL + (newSL * 2))){
               trailSL = (newSL * 2);
               if(trade.PositionModify(posTicket,trailSL,0)){
                     Print(__FUNCTION__, "Position was modified");
            
            }
      
         }
      }
      }
   }
  
  }
}
}

/////Testing hammers as well

int getHammerSignal(){
   double high = iHigh(_Symbol, PERIOD_CURRENT,1);
   double low = iLow(_Symbol,PERIOD_CURRENT,1);
   double open = iOpen(_Symbol,PERIOD_CURRENT,1);
   double close = iClose(_Symbol,PERIOD_CURRENT,1);
   
   return 0;
}

int getEngulfingSignal(){

   datetime time = iTime(_Symbol,PERIOD_CURRENT,1);
   
   //Bullish
   double high1 = iHigh(_Symbol,PERIOD_CURRENT,1);
   double low1 = iLow(_Symbol,PERIOD_CURRENT,1);
   double open1 = iOpen(_Symbol,PERIOD_CURRENT,1);
   double close1 = iClose(_Symbol,PERIOD_CURRENT,1);
   //shift value
   double high2 = iHigh(_Symbol, PERIOD_CURRENT,2);
   double low2 = iLow(_Symbol,PERIOD_CURRENT,2);
   double open2 = iOpen(_Symbol,PERIOD_CURRENT,2);
   double close2 = iClose(_Symbol,PERIOD_CURRENT,2);
   //bullish logic
   if(open1 < close1){
      if(open2 > close2)
         if(high1 > high2 && low1 < low2){
            if(close1 > open2 && open1 < close2){
            createObj(time,low1,233,1,clrGreen,"Bullish ENG");
            return 1;
            }
         }
       }
    //bearish logic
      if(open1 > close1){
         if(open2 < close2)
            if(high1 > high2 && low1 < low2){
               if(close1 < open2 && open1 > close2){
               createObj(time,high1,234,-1,clrRed,"Bearish ENG");
               return -1;
               }
            }
          }
   return 0;
}

/// draw shit and shit
void createObj(datetime time, double price, int arrowCode, int direction, color clr, string txt){
   string objName = "";
   StringConcatenate(objName, "Signal@", time, "at",DoubleToString(price,_Digits),"(",arrowCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price)){
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrowCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(direction > 0) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(direction < 0) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
      }
   string objNameDesc = objName+txt;
   if(ObjectCreate(0,objNameDesc,OBJ_TEXT,0,time,price)){
      ObjectSetString(0,objNameDesc,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,objNameDesc,OBJPROP_COLOR,clr);
      if(direction > 0) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(direction < 0) ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
      }
 }
 ///obvs calculate risk 
 double calcLots(){
   double ticksize = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE);
   double tickvalue = SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE);
   double lotstep = SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
 
   if(ticksize == 0 || tickvalue == 0 || lotstep == 0){
   Print(__FUNCTION__, "Lot Size Error");
   return 0;
   }
   
   double riskMoney = AccountInfoDouble(ACCOUNT_BALANCE) * riskPercent / 100;
   double moneyLotstep = (slDistance / ticksize) * tickvalue * lotstep;
   
   if(moneyLotstep == 0){
   Print(__FUNCTION__,"Lot Size Error");
      return 0;
   }
   
   double lots = MathFloor(riskMoney / moneyLotstep) * lotstep;
   
   return lots;
   
 }
 
 /////Trailing stop free me from this prison of pain
 
 
 int CountOpenPositions(){
 
 int counter = 0;
 int total = PositionsTotal();
   for(int i=total-1; i>0; i--){
   ulong ticket = PositionGetTicket(i);
   if(ticket<=0){Print("Failed to get position ticket"); return -1;}
   if(!PositionSelectByTicket(ticket)){Print("Failed to get magic number"); return -1;}
   ulong magicNumber;
   if(!PositionGetInteger(POSITION_MAGIC, magicNumber)){Print("Failed to get magic number"); return -1;}
   if(InpMagicNumber==magicNumber){counter++;}
   }
   return counter;
 }
 