// ULTRON GBPUSD H1 (https://www.forexfactory.com/thread/840339)
// Created by Pawel Gawron (https://www.forexfactory.com/pawel.gawron)
// Ported from MT4 to MT5 by Yoriz (https://www.forexfactory.com/yoriz)

#property version   "1.2"
#property strict

#include <Trade\Trade.mqh>
#include <Trade\OrderInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\SymbolInfo.mqh>

#define MAGICMA  20131111

//---------------------------------------------------------------------------------------
input double lotsize = 0.1;
input int hour1 = 6;
input int hour2 = 21;

//---------------------------------------------------------------------------------------
double ma1;
double ma2;
double ma3;
double ma4;
double ma5;
double ma6;

double ma1ma2;
double ma2ma1;
double ma3ma4;
double ma4ma3;

double TakeProfit;
double StopLoss;
double TakeProfit1;
double StopLoss1;

int indiLwma9Open  = INVALID_HANDLE;
int indiLwma9Close = INVALID_HANDLE;
int indiSma50Close = INVALID_HANDLE;
int indiSma1Close  = INVALID_HANDLE;

CTrade trade;

//---------------------------------------------------------------------------------------
int OnInit() {
   indiLwma9Open  = iMA(Symbol(), PERIOD_CURRENT, 9, 0, MODE_LWMA, PRICE_OPEN);
   indiLwma9Close = iMA(Symbol(), PERIOD_CURRENT, 9, 0, MODE_LWMA, PRICE_CLOSE);
   indiSma50Close = iMA(Symbol(), PERIOD_CURRENT, 50, 0, MODE_SMA, PRICE_CLOSE);
   indiSma1Close  = iMA(Symbol(), PERIOD_CURRENT, 1, 0, MODE_SMA, PRICE_CLOSE);
   
   trade.SetExpertMagicNumber(MAGICMA);
   trade.SetMarginMode();
   trade.SetTypeFillingBySymbol(Symbol());

   return INIT_SUCCEEDED;
}

//---------------------------------------------------------------------------------------
void OnDeinit(const int reason) {
   IndicatorRelease(indiLwma9Open);
   IndicatorRelease(indiLwma9Close);
   IndicatorRelease(indiSma50Close);
   IndicatorRelease(indiSma1Close);
}

//---------------------------------------------------------------------------------------
void OnTick() {
   ma1 = getIndi(indiLwma9Open, 0);
   ma2 = getIndi(indiLwma9Close, 0);
   ma3 = getIndi(indiSma50Close, 0);
   ma4 = getIndi(indiSma1Close, 0);
   ma1ma2 = ma1-ma2;
   ma2ma1 = ma2-ma1;
   ma3ma4 = ma3-ma4;
   ma4ma3 = ma4-ma3;

   int CountSymbolPositions = 0;
   int positions = PositionsTotal();
   for (int i = 0; i < positions; i++) {
      if (PositionGetTicket(i) != 0) {
         string symbol = PositionGetString(POSITION_SYMBOL);
         long   magic  = PositionGetInteger(POSITION_MAGIC);
         if (symbol == Symbol() && magic == MAGICMA) {
            CountSymbolPositions++;
         }
      }
   }

   MqlTick tick;
   SymbolInfoTick(Symbol(), tick);
   TakeProfit  = tick.bid - 680*Point();
   StopLoss    = tick.ask + 550*Point();
   TakeProfit1 = tick.ask + 680*Point();
   StopLoss1   = tick.bid - 550*Point();
   
   MqlDateTime tm;
   TimeCurrent(tm);
   
   if (ma3ma4 < 0.0048 && ma3 > ma1 && ma3 > ma2 && 
       iClose(Symbol(), PERIOD_CURRENT, 1) < iClose(Symbol(), PERIOD_CURRENT, 2) && 
       iClose(Symbol(), PERIOD_CURRENT, 2) < iOpen(Symbol(), PERIOD_CURRENT, 2) && 
       CountSymbolPositions < 1 && 
       tm.hour > hour1 && tm.hour < hour2 && 
       ma1ma2 < 0.0013 && ma1ma2 > 0.0004) {
      CheckForSell();
   };
   
   if (ma4ma3 < 0.0048 && ma3 < ma1 && ma3 < ma2 && 
       iClose(Symbol(), PERIOD_CURRENT, 1) > iClose(Symbol(), PERIOD_CURRENT, 2) && 
       iClose(Symbol(), PERIOD_CURRENT, 2) > iOpen(Symbol(), PERIOD_CURRENT, 2) && 
       CountSymbolPositions < 1 && 
       tm.hour > hour1 && tm.hour < hour2 && 
       ma2ma1 < 0.0013 && ma2ma1 > 0.0004) {
      CheckForBuy();
   };
}

//---------------------------------------------------------------------------------------
double getIndi(int indiHandle, int bufferNr = 0, int shift = 0) {
   double temp[];
   CopyBuffer(indiHandle, bufferNr, shift, 1, temp);
   return temp[0];
}

//---------------------------------------------------------------------------------------
void CheckForSell() {
   MqlTick tick;
   SymbolInfoTick(Symbol(), tick);
   trade.PositionOpen(Symbol(), ORDER_TYPE_SELL, lotsize, tick.bid, StopLoss, TakeProfit);
}
  
//---------------------------------------------------------------------------------------
void CheckForBuy() {
   MqlTick tick;
   SymbolInfoTick(Symbol(), tick);
   trade.PositionOpen(Symbol(), ORDER_TYPE_BUY, lotsize, tick.ask, StopLoss1, TakeProfit1);
}
