SimpleS&R-v1.3

Author: Copyright � 2007, LEGRUPO Version 1.6
Price Data Components
Series array that contains open time of each bar
Orders Execution
Checks for the total of open ordersIt automatically opens orders when conditions are reachedIt can change open orders parameters, due to possible stepping strategyIt Closes Orders by itself
0 Views
0 Downloads
0 Favorites

Profitability Reports

AUD/USD Oct 2024 - Jan 2025
33.00 %
Total Trades 468
Won Trades 0
Lost trades 0
Win Rate 0.00 %
Expected payoff -9.91
Gross Profit 2255.40
Gross Loss -6891.80
Total Net Profit -4636.40
-100%
-50%
0%
50%
100%
SimpleS&R-v1.3
//+------------------------------------------------------------------+
//|                                                   Simple S&R.mq4 |
//|                                        Copyright © 2008, LEGRUPO |
//|                                           http://www.legrupo.com |
//|                                                     Version: 1.1 |
//| History:                                                         |
//| 1.0 => Release version to the public                             |
//| 1.1 => fixes on this releases:                                   |
//|        1) StopLoss bug fixed;                                    |
//|        2) Now the EA close the open and pending orders on the    |
//|           end of the day, you just need to see when day ends     |
//|           on your broker. InterbankFX is GMT, so it is 0 on them |
//|        3) You don't need to manage the MagicNumber anymore       |
//| 1.3 => 10 Feb 2008 (Tinashe B Chipomho chipomho@xtra.co.nz       |
//|        Improved order handling routines, embedded the indicator  |
//|        making backtesting possible, close half of the position   |
//|        when the pivot point is reached.                          |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#include <WinUser32.mqh>
#include <stderror.mqh>
#include <stdlib.mqh>

#property copyright "Copyright © 2007, LEGRUPO Version 1.6"
#property link      "http://www.legrupo.com"

extern bool TimeSpecific = false;
extern int Slippage = 3;
extern double Lots = 0.2;
extern int ExpertID=1900;
extern int TakeProfitRange = 8;
extern int StopLoss = 100;
extern double FirstHalf = 0.1;

int MagicNumber = 10;
double Pivot = 0;

int CreateMagicNumber(){
   int SymbolCode  = 0;
   int PeriodCode  = 0;
   
   //---- Symbol Code
        if( StringSubstr(Symbol(),0,6) == "AUDCAD") { SymbolCode = 1000; }
   else if( StringSubstr(Symbol(),0,6) == "AUDJPY") { SymbolCode = 2000; }
   else if( StringSubstr(Symbol(),0,6) == "AUDNZD") { SymbolCode = 3000; }
   else if( StringSubstr(Symbol(),0,6) == "AUDUSD") { SymbolCode = 4000; }
   else if( StringSubstr(Symbol(),0,6) == "CHFJPY") { SymbolCode = 5000; }
   else if( StringSubstr(Symbol(),0,6) == "EURAUD") { SymbolCode = 6000; }
   else if( StringSubstr(Symbol(),0,6) == "EURCAD") { SymbolCode = 7000; }
   else if( StringSubstr(Symbol(),0,6) == "EURCHF") { SymbolCode = 8000; }
   else if( StringSubstr(Symbol(),0,6) == "EURGBP") { SymbolCode = 9000; }
   else if( StringSubstr(Symbol(),0,6) == "EURJPY") { SymbolCode = 1000; }
   else if( StringSubstr(Symbol(),0,6) == "EURUSD") { SymbolCode = 1100; }
   else if( StringSubstr(Symbol(),0,6) == "GBPCHF") { SymbolCode = 1200; }
   else if( StringSubstr(Symbol(),0,6) == "GBPJPY") { SymbolCode = 1300; }
   else if( StringSubstr(Symbol(),0,6) == "GBPUSD") { SymbolCode = 1400; }
   else if( StringSubstr(Symbol(),0,6) == "NZDJPY") { SymbolCode = 1500; }
   else if( StringSubstr(Symbol(),0,6) == "NZDUSD") { SymbolCode = 1600; }
   else if( StringSubstr(Symbol(),0,6) == "USDCAD") { SymbolCode = 1700; }
   else if( StringSubstr(Symbol(),0,6) == "USDCHF") { SymbolCode = 1800; }
   else if( StringSubstr(Symbol(),0,6) == "USDJPY") { SymbolCode = 1900; }
                     
   
   //---- Period Code
   if( TimeSpecific ){
     if( Period() == PERIOD_M1 )      { PeriodCode = 10; }
     else if( Period() == PERIOD_M5 ) { PeriodCode = 20; }
     else if( Period() == PERIOD_M15 ){ PeriodCode = 30; }
     else if( Period() == PERIOD_M30 ){ PeriodCode = 40; }
     else if( Period() == PERIOD_H1 ) { PeriodCode = 50; }
     else if( Period() == PERIOD_H4 ) { PeriodCode = 60; }
     else if( Period() == PERIOD_D1 ) { PeriodCode = 70; }
     else if( Period() == PERIOD_W1)  { PeriodCode = 80; }
     else if( Period() == PERIOD_MN1 ){ PeriodCode = 90; }
   }
   else
     PeriodCode = 0;
   //---- Calculate MagicNumber
   return(ExpertID+SymbolCode+PeriodCode);
}

bool HasBuyOrder(double price){
  int total = OrdersTotal();
  double min = Slippage * Point;
  
  for(int i=0; i<total; i++){
    if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true){
      if (OrderSymbol()!=Symbol()) continue;
      if (OrderMagicNumber()!=MagicNumber)continue;
      if ((OrderType()==OP_BUY) || (OrderType()==OP_BUYLIMIT) || (OrderType()==OP_BUYSTOP)) {
        if ((OrderOpenPrice()-(Slippage*Point)<=price) && (OrderOpenPrice()+(Slippage*Point)>=price)){
          return (true);
        }
      }
    }
  }
  return (false);
}

bool HasSellOrder(double price){
  int total = OrdersTotal();
  double min = Slippage * Point;
  for(int i=0; i<total; i++){
    if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true){
      if (OrderSymbol()!=Symbol()) continue;
      //if (OrderMagicNumber()!=MagicNumber)continue;
      if ((OrderType()==OP_SELL) || (OrderType()==OP_SELLLIMIT) || (OrderType()==OP_SELLSTOP)) {
        if ((OrderOpenPrice()-min<=price) && (OrderOpenPrice()+min>=price)){
          return (true);
        }
      }
    }
  }
  return (false);
}


double GetLots(string name){
  //use this function to calculate the number of lots to use
  //if market conditions are favourable we might want to double
  //the lots.
  return (Lots);
}

string OrderType2String(int type){
  if (type==OP_BUY)
    return ("BUY");
  else if (type==OP_BUYLIMIT)
    return ("BUY LIMIT");
  else if (type==OP_BUYSTOP)
    return ("BUY STOP");
  else if (type==OP_SELL)
    return ("SELL");
  else if (type==OP_SELLLIMIT)
    return ("SELL LIMIT");
  else if (type==OP_SELLSTOP)
    return ("SELL STOP");
  return ("Unknown Order Type");  
}
/////////////////////////////////////////////////////////////////////////////////
// int _IsTradeAllowed( int MaxWaiting_sec = 30 )
//
// the function checks the trade context status. Return codes:
//  1 - trade context is free, trade allowed
//  0 - trade context was busy, but became free. Trade is allowed only after 
//      the market info has been refreshed.
// -1 - trade context is busy, waiting interrupted by the user (expert was removed from 
//      the chart, terminal was shut down, the chart period and/or symbol was changed, etc.)
// -2 - trade context is busy, the waiting limit is reached (MaxWaiting_sec). 
//      Possibly, the expert is not allowed to trade (checkbox "Allow live trading" 
//      in the expert settings).
//
// MaxWaiting_sec - time (in seconds) within which the function will wait 
// until the trade context is free (if it is busy). By default,30.
/////////////////////////////////////////////////////////////////////////////////
int _IsTradeAllowed(int MaxWaiting_sec = 30){
  
  if (IsTesting())
    return (1);
    
  // check whether the trade context is free
  if(!IsTradeAllowed()){
    int StartWaitingTime = GetTickCount();
    Print("Trade context is busy! Wait until it is free...");
    // infinite loop
    while(true){
      // if the expert was terminated by the user, stop operation
      if(IsStopped()){ 
        Print("The expert was terminated by the user!"); 
        return(-1); 
      }
      // if the waiting time exceeds the time specified in the 
      // MaxWaiting_sec variable, stop operation, as well
      if(GetTickCount() - StartWaitingTime > MaxWaiting_sec * 1000){
        Print("The waiting limit exceeded (" + MaxWaiting_sec + " ???.)!");
        return(-2);
      }
      
      // if the trade context has become free,
      if(IsTradeAllowed()){
        Print("Trade context has become free!");
        return(0);
      }
      // if no loop breaking condition has been met, "wait" for 0.1 
      // second and then restart checking            
      Sleep(100);
    }
  }
  else
   return(1);
}


int CreateOrder(int cmd, double price, double stoploss, double takeprofit, double lots, double expiration){
  int ticket = -1;
 
  if (!IsConnected()){
    Print("CreateOrder(): Not Connected.");
    return (-1);
  }
  
  if (IsStopped()){
    Print("CreateOrder(): Stopped.");
    return (-1);
  }

  
  // check whether trade context is free
  int TradeAllow = _IsTradeAllowed();
  if(TradeAllow < 0){ 
    return(-1); 
  }
    
  if(TradeAllow == 0){
    RefreshRates();
  }
 
  string comment = "SimpleFiboS&REA : ";
  Print("Opening "+OrderType2String(cmd) +" Order: Price["+price+"] StopLoss["+stoploss+"] TakeProfit["+takeprofit+"]");
  ticket = OrderSend(Symbol(), cmd, lots, price, Slippage, stoploss,
                     takeprofit, comment, MagicNumber, expiration);
  int err=GetLastError();
  if (err!=0){
    Print(""+OrderType2String(cmd) +" Failed to create Order: "+ err+" "+ ErrorDescription(err));
  }                  
                    
  return (ticket);
 
                      
}


/**
 * In this function place only buy orders.
 */
int PlaceSupportOrder(double price, double pivot, double lots, double stoploss, double takeprofit, datetime expiration){
  
  int ticket = -1;
  RefreshRates();
  double servers_min_stop = MarketInfo(Symbol(), MODE_STOPLEVEL) * MarketInfo(Symbol(), MODE_POINT);
  //if the price is within + or - Slippage*Point simply buy.
  if (  (((Slippage*Point) + Ask) >= price) && 
        (((Slippage*Point) - Ask) <= price) ){
    Print("Opening a buy order at market price.");
  }
   
  int cmd = OP_BUYLIMIT;
  //if the price is too close to the stoplevel there is 
  //nothing much we can do
  if (MathAbs(Ask-price) > servers_min_stop){
    if (Ask < price){
      cmd = OP_BUYSTOP;
    }
    //Print("SupportOrder: "+ OrderType2String(cmd)+" Price["+price+"] Pivot["+pivot+"] StopLoss["+stoploss+"] TakeProfit["+takeprofit+"] Expiration["+TimeToStr(expiration,TIME_DATE|TIME_MINUTES)+"]");
    ticket = CreateOrder(cmd, NormalizeDouble(price,Digits), NormalizeDouble(stoploss,Digits), NormalizeDouble(takeprofit,Digits), lots, expiration);
  }
  return (ticket);
}

/**
 * In this function place only buy orders.
 */
int PlaceResistanceOrder(double price, double pivot, double lots, double stoploss, double takeprofit, datetime expiration){
  
  int ticket = -1;
  RefreshRates();
  double servers_min_stop = MarketInfo(Symbol(), MODE_STOPLEVEL) * MarketInfo(Symbol(), MODE_POINT);
  //if the price is within + or - Slippage*Point simply buy.
  if (  (((Slippage*Point) + Bid) >= price) && 
        (((Slippage*Point) - Bid) <= price) ){
    Print("Opening a sell order at market price.");
  }
   
  int cmd = OP_SELLLIMIT;
  //if the price is too close to the stoplevel there is 
  //nothing much we can do
  if (MathAbs(Bid-price) > servers_min_stop){
    if (Bid > price){
      cmd = OP_SELLSTOP;
    }
    Print("ResistanceOrder: "+ OrderType2String(cmd)+" Price["+price+"] Pivot["+pivot+"] StopLoss["+stoploss+"] TakeProfit["+takeprofit+"] Expiration["+TimeToStr(expiration,TIME_DATE|TIME_MINUTES)+"]");
    ticket = CreateOrder(cmd, NormalizeDouble(price,Digits), NormalizeDouble(stoploss,Digits), NormalizeDouble(takeprofit,Digits), lots, expiration);
  }
  return (ticket);
}

int PartiallyClose(int type,int ticket, double openprice, double takeprofit){
  int TradeAllow = _IsTradeAllowed();
  
  double closeprice = 0.0;
    
  Print("Moving to break even and partially closing position ");          
  Print("  TradeAllow["+TradeAllow+"] ticket["+ ticket+"] openprice["+openprice+"] takeprofit["+takeprofit+"] type["+type+"] ");          
  if (TradeAllow >= 0){

    if(TradeAllow == 0)
      RefreshRates();
      
    if (OrderModify(ticket,openprice,openprice,takeprofit,0)!=true)
      Print(OrderType2String(type)+"  Failed to modify to break even: "+ ErrorDescription(GetLastError()));
              
    TradeAllow = _IsTradeAllowed();
    if (TradeAllow==0)
      RefreshRates();

    if (type==OP_BUY)
      closeprice=Bid;
    else if (type==OP_SELL)            
      closeprice=Ask;
      
    Print(" After modify trade allow "+ TradeAllow);          
    Print(OrderType2String(type)+"  : Closing first lot, Ticket["+ticket+"] FirstLots["+FirstHalf+"] Ask["+Ask+"] Bid["+Bid+"] ClosePrice["+closeprice+"]"); 
    
    if (OrderClose(ticket,FirstHalf,closeprice,Slippage)!=true)
      Print(OrderType2String(type)+" Failed to partially close an open order: "+ ErrorDescription(GetLastError()));

     return (0);              
  }  
  return (-1);
}

int TrackOrders(){
  int i=0, ticket=-1;
  int total = OrdersTotal();
  
  int modify = -1;
  double pivot = Pivot;//NormalizeDouble(ObjectGet("PIVOT", OBJPROP_PRICE1), Digits);
  double servers_min_stop = MarketInfo(Symbol(), MODE_STOPLEVEL) * MarketInfo(Symbol(), MODE_POINT);
  
  for(i=(total-1);i>=0; i--){
    
    //if we cant select an order ignore it.
    if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)!=true)
      continue;

    //if its not our order just leave it.
    if (OrderMagicNumber()!=MagicNumber)
     continue;
      
    //dont be nosy and manipulate other people's orders.
    if (OrderSymbol()!=Symbol())
      continue;

    //orders not yet filled leave them as well.
    if ((OrderType()!=OP_SELL)&&(OrderType()!= OP_BUY))
      continue;
      
    //not doing anything to orders that are not yet profitable
    //let the stoploss take care of it.
    //TODO: This might be not be acceptable in certain market conditions.
    if (OrderProfit()<=0)
      continue;
      
    ticket = OrderTicket();     
    
    if (OrderType()==OP_SELL){
      //sell order
      if (MathAbs(OrderOpenPrice()-pivot)>=servers_min_stop){
        if (pivot>=Ask){
          //we have gone past the pivot point,
          if (((OrderStopLoss()>OrderOpenPrice())|| (OrderStopLoss()==0)) && (FirstHalf>0)) {
            //the stop loss is still untouched, close the first half and move the 
            //stop loss to break even.
            modify = PartiallyClose(OrderType(),OrderTicket(),OrderOpenPrice(),OrderTakeProfit());
          }
        }
      }
      
    }
    else if (OrderType()==OP_BUY){
      //buy Order
      if (MathAbs(OrderOpenPrice()-pivot)>=servers_min_stop){
        if (pivot<=Bid){
          if (((OrderStopLoss()<OrderOpenPrice())|| (OrderStopLoss()==0) ) && (FirstHalf>0)){
            //the stop loss is still untouched, close the first half and move the stop loss to break
            //even.
            modify = PartiallyClose(OrderType(),OrderTicket(),OrderOpenPrice(),OrderTakeProfit());
          }
        }
      }
      
    }
    
    //TrailingStop(OrderType(),OrderTicket(), OrderOpenPrice(), OrderTakeProfit(), OrderStopLoss());
  }  
  
}

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init(){
  MagicNumber = CreateMagicNumber();
  return(0);
}

//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit(){
  return(0);
}

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start(){

  double rates[1][6],yesterday_close,yesterday_high,yesterday_low;
  ArrayCopyRates(rates, Symbol(), PERIOD_D1);
  
  
  if(DayOfWeek() == 1){
    if(TimeDayOfWeek(iTime(Symbol(),PERIOD_D1,1)) == 5){
      yesterday_close = rates[1][4];
      yesterday_high = rates[1][3];
      yesterday_low = rates[1][2];
    }
    else{
      for(int d = 5;d>=0;d--){
        if(TimeDayOfWeek(iTime(Symbol(),PERIOD_D1,d)) == 5){
          yesterday_close = rates[d][4];
          yesterday_high = rates[d][3];
          yesterday_low = rates[d][2];
        }
      }  
    }
  }
  else{
    yesterday_close = rates[1][4];
    yesterday_high = rates[1][3];
    yesterday_low = rates[1][2];
  }
  
  
  double R = yesterday_high - yesterday_low;//range
  double pivot = NormalizeDouble((yesterday_high + yesterday_low + yesterday_close)/3,Digits);// Standard Pivot
  Pivot=NormalizeDouble(pivot,Digits);
  double r3 = NormalizeDouble(pivot + (R * 1.000),Digits);
  double r2 = NormalizeDouble(pivot + (R * 0.618),Digits);
  double r1 = NormalizeDouble(pivot + (R * 0.382),Digits);
  double s1 = NormalizeDouble(pivot - (R * 0.382),Digits);
  double s2 = NormalizeDouble(pivot - (R * 0.618),Digits);
  double s3 = NormalizeDouble(pivot - (R * 1.000),Digits);
  
  
  
   double servers_min_stop = MarketInfo(Symbol(), MODE_STOPLEVEL) * MarketInfo(Symbol(), MODE_POINT);
  
   //well just use 1min before the end of day.
   //this is the expiration for our pending orders.
   datetime TimeToEndOfDay = StrToTime("23:59");
   
   double takeprofit = 0;
   int ticket = -1; //default ticket number.
   double stoploss = StopLoss * Point; //default stop loss level.
   //
   
   
   //well just no order placing in the last minute of the day.
   if (TimeToStr(TimeCurrent(),TIME_DATE|TIME_MINUTES)!=TimeToStr(TimeToEndOfDay,TIME_DATE|TIME_MINUTES)){
     //check if we have orders at various fibo points, if not we need to open 
     //the orders.      
     //start by opening orders from s3,r3 then move to s2,r2 then move to s1,r1 
     
     if ( HasSellOrder(r3)!= true) {
       //open a sell order at r3 
       takeprofit = s1+MathMin(TakeProfitRange*Point, servers_min_stop);
       stoploss = r3+MathMax(StopLoss * Point,servers_min_stop);
       ticket = PlaceResistanceOrder(r3,pivot, GetLots("r3"), stoploss, takeprofit ,TimeToEndOfDay);
     }
   
     if ( HasSellOrder(r2)!= true) {
       //open a sell order at r2 
       takeprofit = s1+MathMin(TakeProfitRange*Point, servers_min_stop);
       stoploss = r3+MathMax(StopLoss * Point,servers_min_stop);
       ticket = PlaceResistanceOrder(r2,pivot, GetLots("r2"), stoploss, takeprofit ,TimeToEndOfDay);
     }

     if ( HasSellOrder(r1)!= true) {
       //open a sell order at r1 
       takeprofit = s1+MathMin(TakeProfitRange*Point, servers_min_stop);
       stoploss = r3+MathMax(StopLoss * Point,servers_min_stop);
       ticket = PlaceResistanceOrder(r1,pivot, GetLots("r1"), stoploss, takeprofit ,TimeToEndOfDay);
     }
     
     if ( HasBuyOrder(s3)!= true) {
       //open a buy order at s3 
       takeprofit = r1-MathMax(TakeProfitRange*Point, servers_min_stop);
       stoploss = s3-MathMax(StopLoss * Point,servers_min_stop);
       ticket = PlaceSupportOrder(s3,pivot, GetLots("s3"), stoploss, takeprofit ,TimeToEndOfDay);
     }
     
     if ( HasBuyOrder(s2)!= true) {
       //open a buy order at s2 
       takeprofit = r1-MathMax(TakeProfitRange*Point, servers_min_stop);
       stoploss = s2-MathMax(StopLoss * Point,servers_min_stop);
       ticket = PlaceSupportOrder(s2,pivot, GetLots("s2"), stoploss, takeprofit ,TimeToEndOfDay);
     }

     if ( HasBuyOrder(s1)!= true) {
       //open a sell order at s1 
       takeprofit = r1-MathMax(TakeProfitRange*Point, servers_min_stop);
       stoploss = s1-MathMax(StopLoss * Point,servers_min_stop);
       ticket = PlaceSupportOrder(s1,pivot, GetLots("s1"), stoploss, takeprofit ,TimeToEndOfDay);
     }
     
  }
  
  TrackOrders();
  
  return(0);
}
//+------------------------------------------------------------------+

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---