//+------------------------------------------------------------------+
//|                                         FullPips Magic Order.mq4 |
//|                                                      Version 1.0 |
//|                                   Copyright © 2012, FullPips.com |
//|                                          http://www.fullpips.com |
//+------------------------------------------------------------------+

#property copyright "Copyright ©2012, Eric J. Schuepbach, info@fullpips.com"
#property link      "http://www.fullpips.com"

#include <WinUser32.mqh>
#include <stderror.mqh>
#include <stdlib.mqh>

#define Version "Magic Order 1.0"
#define NL "\n"

#property show_inputs
//--------------------------------------------------------------------
extern string label_01      = "Order Type Selection";
extern bool   gb_BUY        = false;
extern bool   gb_SELL       = false;

extern bool   gb_BUYLIMIT   = false;
extern bool   gb_SELLLIMIT  = false;

extern bool   gb_BUYSTOP    = false;
extern bool   gb_SELLSTOP   = false;

extern string label_02      = "Values";

extern bool   gbGlobalMagic = true;
extern int    giMagic       = 0;

extern double gdLot         = 0.01;
extern double gdPrice       = 0;      
extern int    giSlippage    = 3;
               
//--- Definition of global variables---
double gdStopLevel, gdTickValue, gdBrokerMaxLot, gdBrokerMinLot, gdBrokerLotStep;


//+------------------------------------------------------------------+
//| script initialization function                                   |
//+------------------------------------------------------------------+
int init() {
   
   gdTickValue     = MarketInfo(Symbol(), MODE_TICKVALUE);
   gdStopLevel     = MarketInfo(Symbol(), MODE_STOPLEVEL);
   gdBrokerMaxLot  = MarketInfo(Symbol(), MODE_MAXLOT);
   gdBrokerMinLot  = MarketInfo(Symbol(), MODE_MINLOT);
   gdBrokerLotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
   
return(0);
}

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+

int start()
{
   fbOpenTrade();

   return(0);
}

//+------------------------------------------------------------------+
//| open order on specified direction                                |
//+------------------------------------------------------------------+
bool fbOpenTrade() {

   //definition of local variables
   int    liDir, liSlip, liMagic, liRetryCount, liError;
   double ldLots, ldPrice;
   
   if      (gb_BUY      ) { liDir = OP_BUY;       ldPrice = NormalizeDouble(MarketInfo(Symbol(), MODE_ASK), MarketInfo(Symbol(), MODE_DIGITS)); }
   else if (gb_SELL     ) { liDir = OP_SELL;      ldPrice = NormalizeDouble(MarketInfo(Symbol(), MODE_BID), MarketInfo(Symbol(), MODE_DIGITS)); }
   else if (gb_BUYLIMIT ) { liDir = OP_BUYLIMIT;  ldPrice = NormalizeDouble(gdPrice,                        MarketInfo(Symbol(), MODE_DIGITS)); }
   else if (gb_SELLLIMIT) { liDir = OP_SELLLIMIT; ldPrice = NormalizeDouble(gdPrice,                        MarketInfo(Symbol(), MODE_DIGITS)); }
   else if (gb_BUYSTOP  ) { liDir = OP_BUYSTOP;   ldPrice = NormalizeDouble(gdPrice,                        MarketInfo(Symbol(), MODE_DIGITS)); }
   else if (gb_SELLSTOP ) { liDir = OP_SELLSTOP;  ldPrice = NormalizeDouble(gdPrice,                        MarketInfo(Symbol(), MODE_DIGITS)); }
   else    { Alert("Any Trade operation was selected !"); return(false); }
   
   if      ( gbGlobalMagic && GlobalVariableCheck("Magic")) liMagic = GlobalVariableGet("Magic");
   else if (!gbGlobalMagic) liMagic = giMagic;
   else    { Alert("Global Magic is not selected !");     return(false); }

   liSlip = giSlippage;
   
   ldLots = fdNormalizeLotSize(gdLot);
     
   liRetryCount = 0;
   while (liRetryCount < 5 && !IsTradeContextBusy()) {
      if (OrderSend(Symbol(), liDir, ldLots, ldPrice, liSlip, 0, 0, StringConcatenate(liMagic , " < Magic ", "____"), liMagic) > 0)
         return(true);
      liError = GetLastError();
      Alert("WARNING: trade open error ", OrderSymbol(), " ", liDir, " liError : ", ErrorDescription(liError));
      liRetryCount ++;
      Sleep(1000);
      RefreshRates();
   }
   if (liRetryCount >= 5) {
      Alert("WARNING: Couldn''t open trade 5 times, giving up");
      return(false);
   }   
}

//+------------------------------------------------------------------+
//| normalize lot size                                               |
//+------------------------------------------------------------------+
double fdNormalizeLotSize(double ldLots) {

   ldLots = NormalizeDouble(MathRound(ldLots / gdBrokerLotStep) * gdBrokerLotStep, 2);
   if      (ldLots < gdBrokerMinLot) ldLots = gdBrokerMinLot;
   else if (ldLots > gdBrokerMaxLot) ldLots = gdBrokerMaxLot;
   return  (ldLots);
}


