OpenBreakout





//+------------------------------------------------------------------+
//|                                                 OpenBreakout.mq4 |
//|                                                         Scorpion |
//|                                              www.fxfisherman.com |
//+------------------------------------------------------------------+
#property copyright "Scorpion"
#property link      "http://www.fxfisherman.com"
#include <stdlib.mqh>

#define ts_mode_disable 0
#define ts_mode_fixed_sl 1
#define ts_mode_atr 2
#define ts_mode_half_volatility 3
#define ts_mode_breakout 4

//---- input parameters
extern string    _______Position_______;
extern double    Pip_Value=10;
extern double    Lots=1;
extern int       TP=0;
extern int       SL=0;
int       SL_Mode=1;

extern string    _______Session_______;
extern int From_Hour=13;
extern int From_Min=0;
extern int To_Hour=18;
extern int To_Min=30;

extern string    ______TrailingStop_____;
extern int       TS_Mode=0;       // 0 = disabled, 1 = Fixed SL, 2 = ATR, 3 = Half Volatility, 4 = Breakout Yesterday Hi/Lo
extern int       TS_Trigger=15;
int              TS_Sensitivity=3;
double           TS_DynamicFactor=0.5;   // applied only if TrailingStopMode = 2 or 3
int              Evaluate_Interval=0; // -1 chart, 0 tick, > 0 specified min

extern string    _______Indicators______;
extern int       Breakout_Pips = 5;

string expert_name = "OpenBreakout 1";
int main_magic;
int open_slippage=5;
int close_slippage=10;

datetime dtNextEvaluate;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
   main_magic = 1003000 + GetTimeframeConstant(Period()) + GetSymbolConstant(Symbol());
   watermark();
   return(0);
  }
  
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
   return(0);
  }
  
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
 
  // control entry orders
  int ticket = OrderTicketByMagicNum(main_magic);
  
  // control trailing stops of market orders
  ticket = OrderTicketByMagicNum(main_magic);
  if (ticket > 0) ControlTrailingStop(ticket, SL, TS_Mode, TS_Trigger, TS_DynamicFactor, TS_Sensitivity);
  
  // analyse chart
  bool AnalyseNow;
  datetime TimeNow = CurTime();
  if (Evaluate_Interval==0)
  {
    AnalyseNow=true;
  }else if (TimeNow >= dtNextEvaluate) {
    AnalyseNow=true;
    if (Evaluate_Interval>0)
    {
      dtNextEvaluate=TimeNow - (TimeNow % (Evaluate_Interval*60)) + (Evaluate_Interval*60);
    } else {
      dtNextEvaluate=TimeNow - (TimeNow % (Period()*60)) + (Period()*60);
    }
  }

  bool IsBuy, IsSell, IsCloseBought, IsCloseSold;
  if(AnalyseNow)
  {
    static datetime last_cross;
    if (last_cross != Time[0])
    {
      if (Bid >= Open[0] + (Breakout_Pips * Point))
      {
        last_cross = Time[0];
        IsBuy=True;        
      }else if(Bid <= Open[0] - (Breakout_Pips * Point)){
        last_cross = Time[0];
        IsSell=True;
      }
    }
    IsCloseBought = IsSell;
    IsCloseSold = IsBuy;
    
    double From_Time = From_Hour + (From_Min/60);
    double To_Time = To_Hour + (To_Min/60);
    double Cur_Time = Hour() + (Minute()/60);
    if (!(From_Time <= Cur_Time && Cur_Time <= To_Time))
    {
      IsBuy = False;
      IsSell = False;
    }
  }
  
  // check for exit and cancellation of orders
  if (ticket > 0)
  {
    if (OrderSelectEx(ticket,SELECT_BY_TICKET,MODE_TRADES)==false) return(0);  
    if (OrderType() == OP_BUY && IsCloseBought)
    {
      Alert(expert_name, ": Close order #", ticket," at ", Bid);
      CloseNow(ticket);
    } else if (OrderType() == OP_SELL && IsCloseSold) {
      Alert(expert_name, ": Close order #", ticket," at ", Ask);
      CloseNow(ticket);
    }
  }
  
  // check for entry ( enough money > safe mode off > signal given > enter) 
  if (AccountFreeMargin()>=(100 * Pip_Value * Lots))
  {
    ticket = OrderTicketByMagicNum(main_magic);
    if (ticket==0)
    {
      static int prev_time;
      static int prev_type;
      if (IsBuy && !IsSell && prev_type != OP_BUY) {
        ticket = BuyNow();
        if (ticket > 0)
        {
          prev_time = CurTime();
          prev_type = OP_BUY;
        }
        Alert(expert_name, ": Buy ", Symbol()," at ", Ask);
      } else if(IsSell && !IsBuy && prev_type != OP_SELL) {
        ticket = SellNow();
        if (ticket > 0)
        {
          prev_time = CurTime();
          prev_type = OP_SELL;
        }
        Alert(expert_name, ": Sell ", Symbol()," at ", Bid);
      } else if(IsSell && IsBuy) {
        Print("Error: Buy and sell signals are issued at the same time!");
      }
    }
  }else{
    Alert("Error: insufficient fund. Free Margin = ", AccountFreeMargin());
  }
  
  return(0);
}

//+------------------------------------------------------------------+
//| Buy                                                              |
//+------------------------------------------------------------------+
int BuyNow()
{
    double TrueSL, TrueTP;
    TrueSL = Get_SL(OP_BUY, Ask, SL, SL_Mode, TS_DynamicFactor);
    if (TP > 0) TrueTP = Bid+(TP*Point);
    int ticket = OrderSendEx(Symbol(), OP_BUY, Lots, Ask, open_slippage*Point, TrueSL, TrueTP, expert_name + " " + Symbol() + Period(), main_magic, 0, Yellow);
    return(ticket);
}

//+------------------------------------------------------------------+
//| Sell                                                             |
//+------------------------------------------------------------------+

int SellNow()
{
  double TrueSL, TrueTP;
  TrueSL = Get_SL(OP_SELL, Bid, SL, SL_Mode, TS_DynamicFactor);
  if (TP > 0) TrueTP = Bid-(TP*Point);
  int ticket = OrderSendEx(Symbol(), OP_SELL, Lots, Bid, open_slippage*Point, TrueSL, TrueTP, expert_name + " " + Symbol() + Period(), main_magic, 0, Yellow);
  return(ticket);
}


//+------------------------------------------------------------------+
//| Close                                                            |
//+------------------------------------------------------------------+
bool CloseNow(int ticket)
{
  if (OrderSelectEx(ticket, SELECT_BY_TICKET))
  {
    if (OrderType() == OP_BUY)
    {
      OrderCloseEx(ticket, OrderLots(), Bid, close_slippage);
    }else if (OrderType() == OP_SELL){
      OrderCloseEx(ticket, OrderLots(), Ask, close_slippage);
    }
  }
}


//+------------------------------------------------------------------+
//| Control trailing stop                                            |
//+------------------------------------------------------------------+
void ControlTrailingStop(int ticket, double SL, int TS_Mode, int TS_Trigger, double TS_DynamicFactor, int TS_Sensitivity)
{
  if (ticket == 0 || TS_Mode == 0) return;
  
  double ts;
  if (OrderSelectEx(ticket, SELECT_BY_TICKET, MODE_TRADES)==false) return;
  if (OrderType() == OP_BUY)
  {
    ts = Get_SL(OP_BUY, Bid, SL, TS_Mode, TS_DynamicFactor);
    if ((ts >= OrderStopLoss() + TS_Sensitivity*Point) && (ts > 0)  && (Bid >= OrderOpenPrice() + TS_Trigger*Point )) 
    {
      if (Bid - ts >= 5 * Point)
      {
        OrderModifyEx(ticket, OrderOpenPrice(), ts, OrderTakeProfit(), 0);
      }else if(Bid <= ts){
        CloseNow(ticket);
      }
    }
    
  }else if(OrderType() == OP_SELL){
    ts = Get_SL(OP_SELL, Ask, SL, TS_Mode, TS_DynamicFactor);
    if ((ts <= OrderStopLoss() - TS_Sensitivity*Point) && (ts > 0) && (Ask <= OrderOpenPrice() - TS_Trigger*Point))
    {
      if (ts - Ask >= 5 * Point)
      {
        OrderModifyEx(ticket, OrderOpenPrice(), ts, OrderTakeProfit(), 0);
      }else if(ts <= Ask){
        CloseNow(ticket);
      }
    }
  }
  
}


double Get_SL(int order_type, double price, double sl, int sl_mode, double sl_dynamicfactor)
{
  if (sl_mode == 0) return(0);
  
  double ts;
  double ma_0, hh, ll;
  if (order_type == OP_BUY)
  {
    switch (sl_mode)
    {
      case ts_mode_fixed_sl: if(sl > 0) ts = Bid-(Point*sl); break;
      case ts_mode_atr: ts = Low[0] - (sl_dynamicfactor * iATR(NULL,0,14,0)); break;
      case ts_mode_half_volatility: ts = Low[0] - (sl_dynamicfactor *(High[0]-Low[0])); break;
      case ts_mode_breakout: ts = Low[1] - Point; break;
    }
  }else if(order_type == OP_SELL){
  
    switch (sl_mode)
    {
      case ts_mode_fixed_sl: if(sl > 0) ts = Ask+(Point*sl); break;
      case ts_mode_atr: ts = High[0] + (sl_dynamicfactor * iATR(NULL,0,14,0)); break;
      case ts_mode_half_volatility: ts = High[0] + (sl_dynamicfactor *(High[0]-Low[0])); break;
      case ts_mode_breakout: ts = High[1] + Point; break;
    }
  }
  return(ts);
}


//+------------------------------------------------------------------+
//| Extended order execution functions for used in multiple pairs    |
//| with automatic retry attempts.                                   |
//+------------------------------------------------------------------+
int OrderSendEx(string symbol, int cmd, double volume, double price, int slippage, double stoploss, double takeprofit, string comment, int magic, datetime expiration=0, color arrow_color=CLR_NONE) {
  if(!WaitWhileBusy())
  {
    Print("Error in OrderSendEx(): Timeout encountered");
    return(-1);
  }
  SetBusyState();
  int ticket = OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment, magic, expiration, arrow_color);
  Sleep(5000);
  if (ticket==-1)
  {
    ticket = OrderSend(symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment, magic, expiration, arrow_color);
    Sleep(5000);
  }
  ReleaseBusyState();  
  return(ticket);
}


bool OrderCloseEx(int ticket, double lots, double price, int slippage, color Color=CLR_NONE)
{
  if(!WaitWhileBusy())
  {
    Print("Error in OrderCloseEx(): Timeout encountered");
    return(false);
  }
  SetBusyState();
  bool ret = OrderClose(ticket, lots, price, slippage, Color);
  Sleep(5000);
  if (ret==false)
  {
    ret = OrderClose(ticket, lots, price, slippage, Color);
    Sleep(5000);
  }
  ReleaseBusyState();  
  return(ret);
}

bool OrderModifyEx( int ticket, double price, double stoploss, double takeprofit, datetime expiration, color arrow_color=CLR_NONE)
{
  if(!WaitWhileBusy())
  {
    Print("Error in OrderModifyEx(): Timeout encountered");
    return(false);
  }
  SetBusyState();
  bool ret = OrderModify(ticket, price, stoploss, takeprofit, expiration, arrow_color);
  if(ret)
  {
    Sleep(5000);
  }else{
    Print("Error in OrderModifyEx(): ", LastErrorText());
  }
  ReleaseBusyState();  
  return(ret);
}


//+------------------------------------------------------------------+
//| Extended OrderSelect()                                           |
//+------------------------------------------------------------------+
bool OrderSelectEx(int index, int select, int pool = MODE_TRADES)
{
  if (OrderSelect(index,select,pool)==true)
  {
    return(true);
  }else{
    Print("Error: Order #", index ," cannot be selected. ", LastErrorText());
  }
}


//+------------------------------------------------------------------+
//| Calling state functions                                          |
//+------------------------------------------------------------------+
bool WaitWhileBusy()
{
   datetime OldCurTime;
   int timeoutsec=15;
   
   OldCurTime=CurTime();
   while (GlobalVariableCheck("InTrade") || !IsTradeAllowed()) {
      if(OldCurTime + timeoutsec <= CurTime()) {
         return(false); 
      }
      Sleep(1000);
   }
   return(true);
}

void SetBusyState()
{
  GlobalVariableSet("InTrade", CurTime());  // set lock indicator
}

void ReleaseBusyState()
{
  GlobalVariableDel("InTrade");   // clear lock indicator
}

//+------------------------------------------------------------------+
//| Get order ticket by magic number                                 |
//+------------------------------------------------------------------+
int OrderTicketByMagicNum(int magic_number) {

  for(int i=0;i<OrdersTotal();i++)
  {
    if (OrderSelect(i, SELECT_BY_POS) == false) continue;
    if (OrderMagicNumber() == magic_number) return(OrderTicket());
  }   
      
}


//+------------------------------------------------------------------+
//| Time frame interval appropriation function                       |
//+------------------------------------------------------------------+
int GetTimeframeConstant(int chart_period) {
   switch(chart_period) {
      case 1:  // M1
         return(50);
      case 5:  // M5
         return(100);
      case 15:
         return(150);
      case 30:
         return(200);
      case 60:
         return(250);
      case 240:
         return(300);
      case 1440:
         return(350);
      case 10080:
         return(400);
      case 43200:
         return(450);
   }
}


//+------------------------------------------------------------------+
//| Symbol to index                                                  |
//+------------------------------------------------------------------+
int GetSymbolConstant(string symbol) {

	if(symbol=="EURUSD" || symbol=="mEURUSD" || symbol=="EURUSDm") {	return(1);
	} else if(symbol=="GBPUSD" || symbol=="GBPUSDm") { return(2);
	} else if(symbol=="USDCHF" || symbol=="USDCHFm") {	return(3);
	} else if(symbol=="USDJPY" || symbol=="USDJPYm") {	return(4);
	} else if(symbol=="USDCAD" || symbol=="USDCADm") {	return(5);
	} else if(symbol=="AUDUSD" || symbol=="AUDUSDm") {	return(6);
	} else if(symbol=="CHFJPY" || symbol=="CHFJPYm") {	return(7);
	} else if(symbol=="EURAUD" || symbol=="EURAUDm") {	return(8);
	} else if(symbol=="EURCAD" || symbol=="EURCADm") {	return(9);
	} else if(symbol=="EURCHF" || symbol=="EURCHFm") {	return(10);
	} else if(symbol=="EURGBP" || symbol=="EURGBPm") {	return(11);
	} else if(symbol=="EURJPY" || symbol=="EURJPYm") {	return(12);
  } else if(symbol=="GBPCHF" || symbol=="GBPCHFm") {	return(13);
	} else if(symbol=="GBPJPY" || symbol=="GBPJPYm") {	return(14);
	} else if(symbol=="GOLD"   || symbol=="GOLDm") {	return(15);
	} else {Print("Error: Unexpected symbol."); return(0);
	}
}

//+------------------------------------------------------------------+
//| Get last error description                                       |
//+------------------------------------------------------------------+
string LastErrorText()
{
  return(ErrorDescription(GetLastError()));
}

void watermark()
  {
   ObjectCreate("fxfisherman", OBJ_LABEL, 0, 0, 0);
   ObjectSetText("fxfisherman", "fxfisherman.com", 11, "Lucida Handwriting", RoyalBlue);
   ObjectSet("fxfisherman", OBJPROP_CORNER, 2);
   ObjectSet("fxfisherman", OBJPROP_XDISTANCE, 5);
   ObjectSet("fxfisherman", OBJPROP_YDISTANCE, 10);
   return(0);
  }



Sample





Analysis



Market Information Used:

Series array that contains open time of each bar
Series array that contains open prices of each bar
Series array that contains the lowest prices of each bar
Series array that contains the highest prices of each bar


Indicator Curves created:


Indicators Used:

Indicator of the average true range


Custom Indicators Used:

Order Management characteristics:

It automatically opens orders when conditions are reached
It Closes Orders by itself
It can change open orders parameters, due to possible stepping strategy
Checks for the total of open orders

Other Features:

It issuies visual alerts to the screen

BackTest : USDJPY on H1

From 2009-11-01 to 2009-11-30 Profit Factor:0.20 Total Net Profit:-6816.21

BackTest : EURUSD on H1

From 2009-12-01 to 2010-01-17 Profit Factor:0.24 Total Net Profit:-9025.00

BackTest : USDCAD on H1

From 2009-12-01 to 2010-01-01 Profit Factor:0.20 Total Net Profit:-9103.06

BackTest : EURUSD on H1

From 2009-08-01 to 2009-10-01 Profit Factor:0.25 Total Net Profit:-9182.00

BackTest : GBPUSD on H1

From 2010-01-01 to 2010-02-27 Profit Factor:0.24 Total Net Profit:-9071.00

Request Backtest for OpenBreakout


From : (yyyy/mm/dd) To: (yyyy/mm/dd)

Pair: Period: