fozzy_2-2[1]





//+------------------------------------------------------------------+
//|                                                    fozzy_2-1.mq4 |
//|             Copyright © 2006, Taylor Stockwell & Daniel Frieling |
//|                        stockwet@yahoo.com & tradeigel@gmail.com  |
//|                                                    Version: 2.2  |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Taylor Stockwell & Daniel Frieling"
#property link      "stockwet@yahoo.com & tradeigel@gmail.com"

/* =============== Updates
:: 9-29-2006: Changed okToCheck to support trading only on 00 GMT, if the Use_00_GMT variable is set to 
              true. Otherwise, trades open on new bar.    
:: 9-30-2006: Added parameter to specify MA method. Uses EMA by default now.
:: 10-2-2006: Added ability to set SL according to ATR(10) method, as described by BeachBum
:: 10-3-2006: Added feature for taking partial profit out at a specified level. User specifies number of lots to take out.
              Currently, this feature only supports a single partial profit takeout. It looks to see if the order lots
              is equal to the Lots value. So, the EA can be "tricked" into taking additional partial profit by modifying the 
              Lots value to equal the current open order lots remaining and resetting the partial profit value.   
:: 10-9-2006: Added alert feature when a cross occurs. Also added Trade_Live parameter to turn live trading on and off.
:: 10-17-2006: Bug Fix: TP amount getting set to 0 on B/E and Trailing Stop functions.
:: 10-23-2006: Bug Fix: RSI MA values being incorrectly calculated in EA.
*/

//=============== VARS external
extern bool Use_BB_Filter = true; //Set to false if you want to take ALL crosses regardless of BB median line
extern bool Use_00_GMT = true;    //Only trade daily charts. Set to false if want to trade lower timeframes
extern double Lots = 2.0;         //Lots to trade with
extern double Take_Partial_Profit_Lots = 1.0;
extern int Take_Partial_Profit = 40; //Set to 0 to turn Partial Profit off.
extern int TakeProfit = 130;      //Where to take profit out at
extern bool Use_ATR_Stop = true;   //Set to true if set initial stop based on ATR(10) versus high/low prev bar.
extern double Use_ATR_Pct = 0.7;
extern int Init_Stop_Cushion = 0; //Stops set at previous high/low, plus a little cushion above or below
extern bool TrailingStop = true;  //Set to true if you want to use the trailing stop
extern int TrailingAct = 65;      //When to start trailing (BE + Trailing Step)
extern int TrailingStep = 25;     // How much to trail by
extern int Start_BE = 40;         // When to move to B/E
extern int MA_Method=MODE_EMA;
extern int    RSIPeriod = 8;      // RSI period to use
extern int    RSIMAPeriod = 8;    // MA on RSI period to use
extern int    BandsPeriod=20;     // Bollinger Bands period to use
extern bool Alert_Me = true;
extern bool Trade_Live = true;
extern bool Test_Info = true;

//=============== VARS internal
int magic = 7984; //Magic number for system - same as topic ID at FF
int lastBars;
string EA_comment = "Fozzy Method v2.2";
double version=2.2;
int Slippage = 2;
bool alertme=0;
//---- indicator parameters

int    BandsShift=0;
double BandsDeviations=2.0;


//=============== function: init
int init()
  {
//  Comment("Last RSI: ", rsiVal(1), 
//    "\nRSI Vals: ", rsiVal(0), 
//    "\nRSIMA Vals: ", rsiMAVal(0),
//    "\nBands: ",bands1());

    lastBars = Bars;
  }
  
double getATR()
{
  double atr=iATR(NULL,0,10,0);
  double atr_val = atr*Use_ATR_Pct;
  return(atr_val);
}

double rsiMAVal(int shift)
{
  double rsi[];
  ArrayResize(rsi, Bars);
  ArraySetAsSeries(rsi,true);
  for(int i=Bars; i>=0; i--)
  {
  rsi[i]=iRSI(Symbol(),0, RSIPeriod, PRICE_CLOSE,i+shift);
  }
  double ma = iMAOnArray(rsi,0,RSIMAPeriod,0,MODE_EMA,0);
  return(ma);
}

double rsiVal(int shift)
{
  double rsival = iRSI(Symbol(),0,RSIPeriod,PRICE_CLOSE,shift);
  return(rsival);
}


//=============== function: bands1 (gets BB value on the RSI array for recently closed bar)
double bands1()
{
  double rsi[];
  ArrayResize(rsi, Bars);
  ArraySetAsSeries(rsi,true);
  for(int i=Bars; i>=0; i--)
  {
  rsi[i]=iRSI(Symbol(),0, RSIPeriod, PRICE_CLOSE,i+0);   
  }
  double ma = iMAOnArray(rsi,0,BandsPeriod,0,MODE_SMA,0);
  return(ma);
  //double bb = iBandsOnArray(rsi,0,BandsPeriod,BandsDeviations,0,MODE_MAIN,0);
}

//=============== function: getInitSL (returns Prev Bar Low / High +/- cusion amount)
double getInitSL(int direction, double price)
{
 double initSL;

 if(direction == 0)  // if going LONG is what we're aiming for
  {
    if(Use_ATR_Stop) initSL=price-getATR()-(Init_Stop_Cushion*Point);
    else initSL = iLow(Symbol(), 0, 1)-(Init_Stop_Cushion*Point);
  }
  else if(direction == 1)  // if going SHORT is what we're aiming for
  {
    if(Use_ATR_Stop) initSL=price+getATR()+(Init_Stop_Cushion*Point);
    else initSL = iHigh(Symbol(), 0, 1)+(Init_Stop_Cushion*Point);
  }
 return(initSL);
}


//=============== function: checkOpenTrade (Checks to see if a system trade is open.)
int checkOpenTrade()
{
  int totalorders = OrdersTotal(); // Calls a function to get all the open orders.
  bool orderFound;
  for(int j=0; j<totalorders;j++)
  {    
    OrderSelect(j, SELECT_BY_POS, MODE_TRADES);
    if(OrderMagicNumber() == magic && OrderSymbol() == Symbol())
    {
      orderFound=1;
      break;
    } 
    else
    {
      orderFound=0;
    } 
      
   }
   return(orderFound);
    //if(orderFound==1) return(1);
    //else return(0);
   // return(1);
}
   
   
//=============== function: okToCheck (Start trade at 00:00)
bool okToCheck()
{
//If Daily_Only is true, then trade at 00 GMT. This, however, prevents lower
//timeframes from being tested and traded.

if(Use_00_GMT)
  {
   if(Hour() == 0 && (Minute() >= 0 && Minute() <= 2))
   {
     return(true);
     alertme=0;
   }
   return(false);
  }
  else
  {
   bool barOK;
     if (lastBars != Bars && checkOpenTrade()==0) 
     {
     barOK = true;
     alertme=0;
     }
     else barOK = false;

     return(barOK);
  }

}
//=============== function: getSignal (Indicates whether a valid signal has occurred)
int getSignal()
{
  if(okToCheck())
  {
    bool signal;
    signal = 0;
    
    //Checks to see where the rsi is relative the ma on the previous bar
    bool previous;
    if(rsiVal(2) > rsiMAVal(2)) previous=0;   //rsi above ma, bull signal
    else previous = 1;                  //rsi below ma, bear signal
    
    //Checks to see where the rsi is relative the ma on the last bar
    bool last;
    if(rsiVal(1) > rsiMAVal(1)) last=0;     //rsi above ma, bull signal
    else last = 1;                    //rsi below ma, bear signal
    
    // This checks to see where the RSI and MA lines are relative to the BB median line.
    // 0 = the ma and rsi are below the bb median line
    // 10 = the ma and rsi are above the bb median line
    // 5 = the ma and rsi are mixed - above and below the bb median line
    int checkBB=5;
    if(rsiMAVal(1) < bands1()) checkBB=0;          //ma below bands, bull signal only - no bears
    else if(rsiMAVal(1) > bands1()) checkBB = 10;  //ma above bands, bear signal only - no bulls
  
    //Checks if a new cross occurred, set the signal to 1.
    if(previous != last) signal=1;
    else signal = 0;
    
    
    //If a new cross occurred, handle remaining signal criteria and place trade.
    if(signal)
    {
      if(Use_BB_Filter == false) //ignore BB median line criteria
      {
        // If a new crossing below occured, sell trade
        if(last==1) 
        {
          openTrade(1);
          sendAlert(1);
        }
        // If a new crossing above occured, buy trade
        else if(last==0) 
        {
          openTrade(0);
          sendAlert(0);
        }
      }
      else
      {
        // If a new crossing above occured with MA and RSI below the median BB line, buy trade
        if(last==1 && checkBB == 10) 
        {
          openTrade(1);
          sendAlert(1);
        }
        // If a new crossing above occured with MA and RSI above the median BB line, sell trade
        else if(last==0 && checkBB == 0) 
        {
          openTrade(0);
          sendAlert(0);
        }
      }
      
    }
    
  }
  return(signal);
}
   


//=============== function: 0penTrade (Open 00:00 GMT candle, if criteria met)
bool openTrade(int direction)
{
 int ticket = -1;

 if(direction == 0 && Trade_Live == true) //Buy
   ticket = OrderSend(Symbol(), direction, Lots, Ask, Slippage, getInitSL(direction, Bid), Ask+TakeProfit*Point, EA_comment, magic);

 else
   if(direction == 1 && Trade_Live == true) //Sell
     ticket = OrderSend(Symbol(), direction, Lots, Bid, Slippage, getInitSL(direction, Ask), Bid-TakeProfit*Point, EA_comment, magic);

 if(ticket >= 0) // if order opened sucessfully
 {
   Print("Order sucessfully opened!");
   return(true);
 }
 else
 {
   Print("ERROR: <OrderSend> "+GetLastError());
   return(false);
 }
}


//--------------- function: trailing  (should be included in start() right at the beginning
int trailing()
{
//----------------- CHECK CLOSE/TRAILING STOP ORDERS
 int total = OrdersTotal();
 for(int cnt = 0; cnt < total; cnt++)
 {
   OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);

   if( (OrderType() <= OP_SELL) && (OrderSymbol() == Symbol()) && (OrderMagicNumber() == magic) )
   {
     double orderProfit = -1;

     if(OrderType() == OP_BUY)
     {
       orderProfit = (Bid - OrderOpenPrice()) / Point;
       if(Take_Partial_Profit != 0 && orderProfit >= Take_Partial_Profit && OrderLots() == Lots)
       {        
        OrderClose(OrderTicket(),Take_Partial_Profit_Lots, Bid, 0, LimeGreen);        
       }
            
       
       if(OrderStopLoss() < OrderOpenPrice())
       {
         // moving stop to B/E if profit > Start_BE

         if(orderProfit >= Start_BE)
           OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice(), OrderOpenPrice()+(TakeProfit*Point), 0, Green);
         

       }

       if(TrailingStop)
       {
         if((Bid-OrderOpenPrice()) > (Point*TrailingAct))  // if you are 'TrailingAct' or higer in Profit
         {
           if((OrderStopLoss()) < (Bid-Point*TrailingStep))  // if S/L is lower than Bid-'TrailingStep'
           {
             OrderModify(OrderTicket(), OrderOpenPrice() ,Bid-Point*TrailingStep, OrderOpenPrice()+(TakeProfit*Point), 0, GreenYellow);
             return(0);
           }
         }
       }
     }

     if(OrderType() == OP_SELL)
     {
       orderProfit = (OrderOpenPrice() - Ask) / Point;
       if(Take_Partial_Profit != 0 && orderProfit >= Take_Partial_Profit && OrderLots() == Lots)
       {        
        OrderClose(OrderTicket(),Take_Partial_Profit_Lots, Ask, 0, LimeGreen);       
       }
       if(OrderStopLoss() > OrderOpenPrice())
       {
         // moving stop to B/E if profit > Start_BE         
         if(orderProfit >= Start_BE)
           OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice(), OrderOpenPrice()-(TakeProfit*Point), 0, Green);
       }

       if(TrailingStop)
       {
         if(OrderOpenPrice()-Ask>Point*TrailingAct)
         {
           if(OrderStopLoss()>Ask+Point*TrailingStep)
           {
             OrderModify(OrderTicket(), OrderOpenPrice(), Ask+Point*TrailingStep, OrderOpenPrice()-(TakeProfit*Point), 0, Red);
             return(0);
           }
         }
       }
     }
   }
 }


 return(0);
}


//=============== function: sendAlert
bool sendAlert(bool direction)
{
  if(Alert_Me == true && alertme == 0)
  {
  string signalTime = TimeToStr(LocalTime(),TIME_MINUTES);
  if(direction==1)
    SendMail("Fozzy Alert", "A bearish fozzy cross has occurred at "+signalTime+" on "+Symbol());
  else
    SendMail("Fozzy Alert", "A bullish fozzy cross has occurred at "+signalTime+" on "+Symbol());
  
  alertme=1;
  return(1);
  }
  else return(0);
  
     
}



//=============== function: deinit
int deinit()
  {
   return(0);
  }
  
  
//=============== function: start
int start()
  {
  if(Test_Info)
  {
      Comment("Last RSI: ", rsiVal(1), 
    "\nRSI Vals: ", rsiVal(0),", ",rsiVal(1), 
    "\nRSIMA Vals: ", rsiMAVal(0),", ",rsiMAVal(1),
    "\nBands: ",bands1(),
    "\nOpenTrade: ",checkOpenTrade(),
    "\nStop by ATR Val: ",getATR());
  }

  trailing();

  
  
  if(checkOpenTrade() == 0) getSignal();
  else return(0);
  }





Sample





Analysis



Market Information Used:

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
Relative strength index
Moving average indicator


Custom Indicators Used:

Order Management characteristics:
Checks for the total of open orders

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

Other Features:

It issuies visual alerts to the screen
It sends emails

BackTest : USDJPY on H1

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

BackTest : USDCHF 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-12-01 to 2010-01-17 Profit Factor:0.00 Total Net Profit:0.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.00 Total Net Profit:0.00

BackTest : GBPUSD on H1

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

BackTest : EURUSD on H1

From 2010-04-01 to 2010-04-30 Profit Factor:0.00 Total Net Profit:0.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 fozzy_2-2[1]


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

Pair: Period: