//+------------------------------------------------------------------+ //| 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