SDS_UMM_ver1





//+------------------------------------------------------------------+
//|                                                 SDS_UMM_ver1.mq4 |
//|                                                         Zen_Leow |
//|                                                                  |
//+------------------------------------------------------------------+
/*
Indicators: 
1. 200 SMA (option to change period by user)
2. ADR - 50 pips or greater on the previous 10 days
3. PSAR - this can be optional to use with the SMA (user defined) that allows trades only to be taken when both indicators agree

R/R ratio: 1:1 

Stop loss: (user defined) will be using 100 pips to include spread

Take profit: (user defined) will be using 100 pips after covering spread

Pairs:
All that have an ADR equal to or greater than 50 pips

Broker: Personal preference (will test using IBFX w/10K starting balance)

Money Management: Each contract will be equal to .1 lot. (option to change lot size per user)

Example using MM: To begin open 1 contract for each pair in the direction of the indicator(s). If a win is obtained, continue with 1 contract. If a loss is obtained in a given pair then increase 1 contract for the next trade. Continue to add 1 contract if consecutive losses. Once a win is generated after a loss reverse contract size by 1 until the contract size returns back to the beginning of 1 thus eliminating all the losing trades.

Exaple of opening a trade:

Long - at the open of a new candle if the previous candle is > 200 SMA (optional to add the PSAR and trade only when both agree)

Short - at the open of a new candle if the previous candle is < 200 SMA
(optional to add the PSAR and trade only when both agree)

Let the position run until either the take profit or stop loss is hit.
*/

#property copyright "Zen_Leow"
#property link      ""
#include <stdlib.mqh>
#include <stderror.mqh>

extern int       EA_MAGIC_NUM = 275931;
extern int       MA_Period = 200;
extern int       MA_TYPE = MODE_SMA;
extern bool      UsePSAR = true;
extern int       ADR_Days = 10;
extern int       Min_Range = 50;

extern int       Start_Hour = 0;
extern int       Start_Minute = 0;

extern double    Slippage = 3.0;
extern int       TakeProfit = 100;
extern int       StopLoss = 100;

extern int       LotSizeFactor = 1;
extern double    Lots = 0.1;

string msg = "";
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   WriteComment();
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }

void WriteComment()
{
   msg = "";
   
   msg = msg + "Average Range of "+ADR_Days+" days: "+GetAverageRange(ADR_Days);
   msg = msg +" \nLotSizeFactor: "+LotSizeFactor;
   if (UsePSAR)
   {
      msg = msg +" \nPSAR used?: YES";
   }
   else
   {
      msg = msg +" \nPSAR used?: NO";
   }
   msg = msg + "\nStart_Hour: "+Start_Hour;
   msg = msg + "\nStart_Minute: "+Start_Minute;
   
   Comment(msg);
}

int GetAverageRange(int DaysNum)
{
   int range = 0;
   for(int i=1;i<=DaysNum;i++)
   {
      range = range + ((iHigh(NULL,PERIOD_D1,i) - iLow(NULL,PERIOD_D1,i)) / Point);
   }
   range = range / DaysNum;
   return (range);
}

double GetMAValue(int index)
{
   return (iMA(NULL,0,MA_Period,0,MA_TYPE,PRICE_CLOSE,index));
}

double GetSARValue(int index)
{
   return (iSAR(NULL,0,0.02,0.2,index));
}

bool ShouldBuy()
{
   if (Close[1] > GetMAValue(1) && GetAverageRange(ADR_Days) >= Min_Range)
   {
      if (UsePSAR) 
      {
         if(Low[1] > GetSARValue(1))
         {
            return (true);
         }
         else
         {
            return (false);
         }
      }
      else
      {
         return (true);
      }
   }
   return (false);
}

bool ShouldSell()
{
   if (Close[1] < GetMAValue(1) && GetAverageRange(ADR_Days) >= Min_Range)
   {
      if (UsePSAR) 
      {
         if(High[1] < GetSARValue(1))
         {
            return (true);
         }
         else
         {
            return (false);
         }
      }
      else
      {
         return (true);
      }
   }
   return (false);
}

int GetLotSizeFactor()
{
   int histotal = OrdersHistoryTotal();
   if (histotal > 0)
   {
      for(int cnt=histotal-1;cnt>=0;cnt--) // retrieve closed orders counting from the last.
      {
         if(OrderSelect(cnt,SELECT_BY_POS,MODE_HISTORY))
         {
            if(OrderSymbol()==Symbol() && OrderMagicNumber() == EA_MAGIC_NUM)
            {
               if(OrderProfit() < 0) // latest order close was a loss
               {
                  LotSizeFactor = LotSizeFactor + 1;
                  return (LotSizeFactor);
               }
               else // latest order closed was a win
               {
                  LotSizeFactor = LotSizeFactor - 1;
                  if (LotSizeFactor <= 0)
                  {
                     LotSizeFactor = 1;
                  }
                  return (LotSizeFactor);
               }
            }
         }
      }
   }
   return (LotSizeFactor); // no trades recorded in history just return the starting number.
}

bool DecideToOpenTrade()
{
   int total = OrdersTotal();
   if (total > 0)
   {
      for(int cnt=0;cnt<total;cnt++)
      {
         if(OrderSelect(cnt,SELECT_BY_POS))
         {
            if(OrderSymbol()==Symbol() && OrderMagicNumber() == EA_MAGIC_NUM) // currently there's a trade running, don't add to it.
            {
               return (false);
            }
         }
      }
   }
   // in case trades has already opened and closed within the candle
   int histotal = OrdersHistoryTotal();
   if (histotal > 0)
   {
      for(cnt=0;cnt<histotal;cnt++)
      {
         if(OrderSelect(cnt,SELECT_BY_POS,MODE_HISTORY))
         {
            if(OrderSymbol()==Symbol() && OrderMagicNumber() == EA_MAGIC_NUM)
            {
               if (Time[0] <= OrderOpenTime()) // don't open a new position if we're still on the same candle
               {
                  return (false);
               }
            }
         }
      }
   }
   return (true);
}

void SendOrders (int BuyOrSell, double LotSize, double PriceToOpen, double Slippage, double SL_Price, double TP_Price, string comments, datetime ExpirationTime)
{
LotSize = 0.1;
   int PositionType, ticket, errorType;
   
   if (BuyOrSell == OP_BUY)
   {  
      PositionType = OP_BUY;
      Print("Bid: "+Bid+" Ask: "+Ask+" | Opening Buy Order: "+Symbol()+", "+PositionType+", "+LotSize+", "+PriceToOpen+", "+Slippage+", "+SL_Price+", "+TP_Price+", "+comments+", "+EA_MAGIC_NUM+", "+ExpirationTime+", Green");
      ticket=OrderSend(Symbol(),PositionType,LotSize,PriceToOpen,Slippage,SL_Price,TP_Price,comments,EA_MAGIC_NUM,ExpirationTime,Green);
      if(ticket>0)
      {
         if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) 
         {
            
            Print("BUY order opened : ",OrderOpenPrice());
            msg = ticket + ": Buy position opened on "+Symbol()+" at "+ Day()+"/"+Month()+"/"+Year()+" - "+Hour()+":"+Minute()+":"+Seconds();
            WriteToLogFile(msg);
            Start_Hour = 0;
            Start_Minute = 0;
         }
      }
      else 
      {  
         errorType = GetLastError();
         Print("Error opening BUY order : ", ErrorDescription(errorType));
         msg = "CANNOT open BUY position on "+Symbol()+" at "+ Day()+"/"+Month()+"/"+Year()+" - "+Hour()+":"+Minute()+":"+Seconds();
         WriteToLogFile(msg);
      }
   }
   if (BuyOrSell == OP_SELL)
   {  
      PositionType = OP_SELL;
      Print("Bid: "+Bid+" Ask: "+Ask+" | Opening Sell Order: "+Symbol()+", "+PositionType+", "+LotSize+", "+PriceToOpen+", "+Slippage+", "+SL_Price+", "+TP_Price+", "+comments+", "+EA_MAGIC_NUM+", "+ExpirationTime+", Red");
      ticket=OrderSend(Symbol(),PositionType,LotSize,PriceToOpen,Slippage,SL_Price,TP_Price,comments,EA_MAGIC_NUM,ExpirationTime,Red);
      if(ticket>0)
      {
         if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) 
         {
            
            Print("Sell order opened : ",OrderOpenPrice());
            msg = ticket + ": Sell position opened on "+Symbol()+" at "+ Day()+"/"+Month()+"/"+Year()+" - "+Hour()+":"+Minute()+":"+Seconds();
            WriteToLogFile(msg);
            Start_Hour = 0;
            Start_Minute = 0;
         }
      }
      else 
      {  
         errorType = GetLastError();
         Print("Error opening SELL order : ", ErrorDescription(errorType));
         msg = "CANNOT open SELL position on "+Symbol()+" at "+ Day()+"/"+Month()+"/"+Year()+" - "+Hour()+":"+Minute()+":"+Seconds();
         WriteToLogFile(msg);
      }
   }
}

void WriteToLogFile(string input)
{
   string filename = "SDS_MM-"+Symbol()+"-"+Day()+"-"+Month()+"-"+Year()+".log";
   int handle = FileOpen(filename,FILE_READ|FILE_WRITE);
   if (handle>1)
   {
      FileSeek(handle, 0, SEEK_END); // go to end of file
      FileWrite(handle, input);
      FileClose(handle);
   }
}

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
{
   WriteComment();
//----
   int CurrentHour = TimeHour(TimeCurrent());
   int CurrentMinute = TimeMinute(TimeCurrent());
   if (CurrentHour == Start_Hour && CurrentMinute == Start_Minute)
   {
      double PriceToOpen;
      double TakeProfitPrice;
      double StopLossPrice;
      
      if (ShouldBuy())
      {
         if (DecideToOpenTrade())
         {
            PriceToOpen = Ask;
            if (TakeProfit == 0)
            {
               TakeProfitPrice = 0;
            }
            else
            {
               TakeProfitPrice = PriceToOpen + (TakeProfit * Point);
               TakeProfitPrice = NormalizeDouble(TakeProfitPrice,Digits);
            }
            if (StopLoss == 0)
            {
               StopLossPrice = 0;
            }
            else
            {
               StopLossPrice = PriceToOpen - (StopLoss * Point);
               StopLossPrice = NormalizeDouble(StopLossPrice,Digits);
            }
            SendOrders(OP_BUY, Lots * GetLotSizeFactor(), PriceToOpen, Slippage, StopLossPrice, TakeProfitPrice, "SDS_MM_Buy_"+EA_MAGIC_NUM, 0);
         }
      }
      if (ShouldSell())
      {
         if (DecideToOpenTrade())
         {
            PriceToOpen = Bid;
            if (TakeProfit==0)
            {
               TakeProfitPrice = 0;
            }
            else
            {
               TakeProfitPrice = PriceToOpen - (TakeProfit * Point);
               TakeProfitPrice = NormalizeDouble(TakeProfitPrice,Digits);
            }
            if (StopLoss==0)
            {
               StopLossPrice = 0;
            }
            else
            {
               StopLossPrice = PriceToOpen + (StopLoss * Point);
               StopLossPrice = NormalizeDouble(StopLossPrice,Digits);
            }
            SendOrders(OP_SELL, Lots * GetLotSizeFactor(), PriceToOpen, Slippage, StopLossPrice, TakeProfitPrice, "SDS_MM_Sell_"+EA_MAGIC_NUM, 0);
         }
      }
   }
//----
   return(0);
}
//+------------------------------------------------------------------+



Sample





Analysis



Market Information Used:

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


Indicator Curves created:


Indicators Used:

Moving average indicator
Parabolic Stop and Reverse system


Custom Indicators Used:

Order Management characteristics:
Checks for the total of closed orders

Checks for the total of open orders
It automatically opens orders when conditions are reached

Other Features:

Uses files from the file system
It writes information to file

BackTest : EURUSD on H1

From 2009-11-01 to 2009-11-30 Profit Factor:0.36 Total Net Profit:-90.00

BackTest : USDJPY on H1

From 2009-11-01 to 2009-11-30 Profit Factor:0.50 Total Net Profit:-66.48

BackTest : EURUSD on H1

From 2009-12-01 to 2010-01-17 Profit Factor:1.46 Total Net Profit:60.00

BackTest : USDCAD on H1

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

BackTest : EURUSD on H1

From 2009-08-01 to 2009-10-01 Profit Factor:0.68 Total Net Profit:-80.00

BackTest : GBPUSD on H1

From 2010-01-01 to 2010-02-27 Profit Factor:0.60 Total Net Profit:-100.00

BackTest : USDCAD on H1

From 2009-01-01 to 2010-01-01 Profit Factor:0.39 Total Net Profit:-1004.89

BackTest : EURUSD on H1

From 2010-03-01 to 2010-03-27 Profit Factor:0.54 Total Net Profit:-60.00

BackTest : GBPUSD on H1

From 2010-01-01 to 2010-04-16 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2010-04-01 to 2010-04-30 Profit Factor:0.75 Total Net Profit:-30.00

BackTest : EURUSD on H1

From 2010-05-01 to 2010-05-31 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2010-06-01 to 2010-06-30 Profit Factor:0.00 Total Net Profit:0.00

Request Backtest for SDS_UMM_ver1


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

Pair: Period: