narrowestrangesignal_ea

Author: Copyright 2013, Rone.
Orders Execution
Checks for the total of open orders
0 Views
0 Downloads
0 Favorites
narrowestrangesignal_ea
//+------------------------------------------------------------------+
//|                                      NarrowestRangeSignal_EA.mq5 |
//|                                            Copyright 2013, Rone. |
//|                                            rone.sergey@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, Rone."
#property link      "rone.sergey@gmail.com"
#property version   "1.00"
#property description "The Expert Advisor based on the NarrowestRangeSignal indicator. If there is no position, "
#property description "stop orders will be set in both sides of the range by the signal of the indicator. "
#property description "When either of orders triggers, the opposite order is deleted."
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum ENUM_MM_MODE {
   FIXED_LOT,        // Fixed lot
   FIXED_PERCENT     // Fixed percent
};
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
input int            InpBarsInRange = 3;     // Bars in Range
input int            InpCheckPeriod = 10;    // Check Period
input int            InpIndent = 50;         // Order Indent from High/Low
input int            InpTakeProfit = 500;    // Take Profit (pips)
input ENUM_MM_MODE   InpMmMode = FIXED_LOT;  // MM Mode
input double         InpVolume = 1.0;        // Volume(Lot or percent)
//---
int bars_in_range;
int check_period;
int nrs_handle = INVALID_HANDLE;

double take_profit;
double indent;
double inp_volume;
bool is_buy_stop = false;
bool is_sell_stop = false;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
//---
   bars_in_range = InpBarsInRange;
   check_period = InpCheckPeriod;
   
   take_profit = InpTakeProfit * _Point;
   indent = InpIndent * _Point;
   inp_volume = InpVolume;
   
   ResetLastError();
   nrs_handle = iCustom(_Symbol, _Period, "NarrowestRangeSignal", bars_in_range, check_period);
   if ( nrs_handle == INVALID_HANDLE ) {
      Print("Creating NarrowestRangeSignal indicator failed. Error #", GetLastError());
      return(-1);
   }
//---
   return(0);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
//---
   IndicatorRelease(nrs_handle);
//---
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime GetCurrentTime() {
//---
   datetime time[1];
   
   ResetLastError();
   if ( CopyTime(_Symbol, _Period, 0, 1, time) != 1 ) {
      Print(__FUNCTION__, ": getting time data failed. Error #", GetLastError());
      return((datetime)0);
   }
//---
   return(time[0]);
}
//+------------------------------------------------------------------+
//| Check volume value function                                      |
//+------------------------------------------------------------------+
double CheckLotValue(double volume) {
//---
   double min_volume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
   double max_volume = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
   double volume_step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
//---
   if ( volume < min_volume ) {
      volume = min_volume;
   } else if ( volume > max_volume ) {
      volume = max_volume;
   }
//---
   int digits = (int)MathCeil(MathLog10(1/volume_step));
//---
   return(NormalizeDouble(volume, digits));
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double CalculateLot() {
//---
   double result;
   
   if ( InpMmMode == FIXED_LOT ) {
      result = inp_volume;
   } else {
      double free_margin = AccountInfoDouble(ACCOUNT_FREEMARGIN);
      long leverage = AccountInfoInteger(ACCOUNT_LEVERAGE);
      
      result = NormalizeDouble((free_margin/1000/leverage)*inp_volume, 1); 
   }
//---
   return(CheckLotValue(result));
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool OpenPendingOrder(ENUM_ORDER_TYPE type, double price, double sl) {
//---
   MqlTick last_tick;
   
   ResetLastError();
   if ( !SymbolInfoTick(_Symbol, last_tick) ) {
      Print(__FUNCTION__, ": getting tick data failed. Error #", GetLastError());
      return(false);
   }
//---
   double tp;
   if ( type == ORDER_TYPE_BUY_STOP ) {
      price += (last_tick.ask - last_tick.bid);
      tp = price + take_profit;
   } else {
      tp = price - take_profit;
   }
   
   CTrade trade;
   
   if ( !trade.OrderOpen(_Symbol, type, CalculateLot(), price, price, sl, tp) ) {
      Print(__FUNCTION__, ": opening order failed. Error #", GetLastError());
      return(false);
   }
//---
   return(true);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsNarrowestRangeSignal(double &max_price, double &min_price) {
//---
   double nrs_values[], high[], low[];
   int to_copy = bars_in_range + 1;
   
   ResetLastError();
   if ( CopyBuffer(nrs_handle, 2, 1, 1, nrs_values) == 1
      && CopyHigh(_Symbol, _Period, 0, to_copy, high) == to_copy
      && CopyLow(_Symbol, _Period, 0, to_copy, low) == to_copy)
   {
      if ( nrs_values[0] != 0.0 && nrs_values[0] != EMPTY_VALUE ) {
         if ( ArrayMaximum(high) != bars_in_range && ArrayMinimum(low) != bars_in_range ) {
            max_price = high[ArrayMaximum(high)];
            min_price = low[ArrayMinimum(low)];
            return(true);
         }
      }
   } else {
      Print(__FUNCTION__, ": getting NarrowestRangeSignal or/and high or/and low data failed. Error #", 
         GetLastError());
   }
//---
   return(false);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CheckOrders() {
//---
   datetime cur_time = GetCurrentTime();
   static datetime prev_time;
   
   if ( cur_time == prev_time ) {
      return;
   }
//---
   double max_high, min_low;
   
   if ( IsNarrowestRangeSignal(max_high, min_low) ) {
      DeletePendingOrders();
      if ( !is_buy_stop ) {
         if ( !OpenPendingOrder(ORDER_TYPE_BUY_STOP, max_high+indent, min_low-indent) ) {
            return;
         }
         is_buy_stop = true;
      }
      if ( !is_sell_stop ) {
         if ( !OpenPendingOrder(ORDER_TYPE_SELL_STOP, min_low-indent, max_high+indent) ) {
            return;
         }
         is_sell_stop = true;
      }
   }
//---
   prev_time = cur_time;
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DeletePendingOrders() {
//---
   datetime cur_time = GetCurrentTime();
   static datetime prev_time;   
   
   if ( prev_time == cur_time ) {
      return;
   }
   
   for ( int ord = OrdersTotal() - 1; ord >= 0; ord-- ) {
      ulong ticket;
      
      if ( (ticket = OrderGetTicket(ord)) > 0 ) {
         if ( OrderGetString(ORDER_SYMBOL) == _Symbol ) {
            CTrade trade;
            
            if ( !trade.OrderDelete(ticket) ) {
               Print(__FUNCTION__, ": deleting order failed. Error #", GetLastError());
               return;
            }
         }
      }   
   }
//---
   is_buy_stop = false;
   is_sell_stop = false;
   prev_time = cur_time;
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {
//---
   if ( PositionSelect(_Symbol) ) {
      DeletePendingOrders();
   } else {
      CheckOrders();
   }
//---   
}
//+------------------------------------------------------------------+

Comments