//+------------------------------------------------------------------+ //| TriplePlay.mq4 | //| Copyright © 2006 | //| Written by Robert Hill | //| Based on idea posted by Ignace BIENVILLE | //| Uses entry rule from MACD Sample to place triple trades | //| Added many ideas for entering, filtering and exiting trades | //| Default values worked best on backtest from Aug 20, 2006 | //| Includes string prompts to better understand inputs | //+------------------------------------------------------------------+ #property copyright "Copyright © 2006, Robert Hill" #include #include #define NO 0 #define YES 1 // Additional modes for Moving average #define MODE_LSMA 4 #define MODE_ITREND 5 #define MODE_HMA 6 // Entry methods // MACD as supplied by MT4 using SMA for signal line smoothing // MACD_EMA uses EMA for signal line smoothing // MACD_LSMA uses LSMA instead of EMA and EMA for smoothing #define MACD 0 #define MACD_EMA 1 #define MACD_LSMA 2 // MACD crosses use histogram crossing zero line #define MACD_CROSS 3 #define MACD_EMA_CROSS 4 #define MACD_LSMA_CROSS 5 // Moving averages used for trend #define SMA 6 #define EMA 7 #define SMMA 8 #define LWMA 9 #define LSMA 10 #define ITREND 11 #define HMA 12 // MACD trend Filters #define NO_FILTER 0 #define SMA_FILTER 1 #define EMA_FILTER 2 #define SMMA_FILTER 3 #define LWMA_FILTER 4 #define LSMA_FILTER 5 #define ITREND_FILTER 6 #define HMA_FILTER 7 //exit methods #define MACD_EXIT 0 #define MACD_EMA_EXIT 1 #define MACD_LSMA_EXIT 2 #define MACD_CROSS_EXIT 3 #define MACD_EMACROSS_EXIT 4 #define MACD_LSMACROSS_EXIT 5 #define SMA_EXIT 6 #define EMA_EXIT 7 #define SMMA_EXIT 8 #define LWMA_EXIT 9 #define LSMA_EXIT 10 #define ITREND_EXIT 11 #define HMA_EXIT 12 //+---------------------------------------------------+ //|Account functions | //+---------------------------------------------------+ extern bool AccountIsMini = true; // Change to true if trading mini account //+---------------------------------------------------+ //|Money Management | //+---------------------------------------------------+ extern bool MoneyManagement = true; // Change to false to shutdown money management controls. extern string str1 = " TradeSizePersent <= 5"; extern double TradeSizePercent = 5; // Change to whatever percent of equity you wish to risk. extern double Lots = 0.1; // standard lot size. double MaxLots = 100; //+---------------------------------------------------+ //|Profit controls | //+---------------------------------------------------+ extern double StopLoss = 70; // Maximum pips willing to lose per position. extern int FirstLevel = 10; extern int SecondLevel = 20; extern double TakeProfit1 = 30; extern double TakeProfit2 = 20; extern double TakeProfit3 = 10; extern string str2 = " TrailingStopType"; extern string str3 = " 1 - Trail immediately"; extern string str4 = " 2 - Wait til TrailingStop"; extern string str5 = " is reached to trail"; extern bool UseTrailingStop = false; extern int TrailingStopType = 2; extern double TrailingStop = 5; double Margincutoff = 800; // Expert will stop trading if equity level decreases to that level. int Slippage = 10; // Possible fix for not getting filled or closed //+---------------------------------------------------+ //|Indicator Variables | //| Change these to try your own system | //| or add more if you like | //+---------------------------------------------------+ extern string estr1 = "Entry Methods"; extern string estr2 = " 0 = MACD"; extern string estr3 = " 1 = MACD-EMA"; extern string estr4 = " 2 = MACD-LSMA"; extern string estr5 = " 3 = MACD Cross"; extern string estr6 = " 4 = MACD EMA Cross"; extern string estr7 = " 5 = MACD LSMA Cross"; extern string estr8 = " 6 = SMA"; extern string estr9 = " 7 = EMA"; extern string estr10 = " 8 = SMMA"; extern string estr11 = " 9 = LWMA"; extern string estr12 = " 10 = LSMA"; extern string estr13 = " 11 = ITREND"; extern string estr14 = " 12 = HMA"; extern int EntryMethod = 1; extern string estr15 = " MACD_LSMA - FastEMA = 20, slowEMA = 38"; extern int FastEMA=12; extern int SlowEMA=26; extern int SignalEMA=9; extern double MACD_OpenLevel=5; extern double MACD_CloseLevel=1; extern int MACD_TimeFrame = 0; extern int MA_EntryPeriod=14; extern int LSMA_EntryPeriod=18; extern int iTrend_EntryPeriod=26; extern int HMA_EntryPeriod = 16; extern int TrendEntry_TimeFrame = 0; extern string fstr1 = "MACD Filter Methods"; extern string fstr2 = " 0 = No Filter"; extern string fstr3 = " 1 = SMA"; extern string fstr4 = " 2 = EMA"; extern string fstr5 = " 3 = SMMA"; extern string fstr6 = " 4 = LWMA"; extern string fstr7 = " 5 = LSMA"; extern string fstr8 = " 6 = iTrend"; extern string fstr9 = " 7 = HMA"; extern int FilterMethod = 2; extern int MA_FilterPeriod=21; extern int LSMA_FilterPeriod=18; extern int iTrend_FilterPeriod=26; extern int HMA_FilterPeriod = 16; extern int TrendFilter_TimeFrame = 0; extern int SignalCandle = 1; extern bool UseDST = false; extern int StartHour = 1; // Start trades after time extern int StopHour = 13; // Stop trading after time extern string xstr1 = "Exit Methods"; extern string xstr2 = " 0 = MACD"; extern string xstr3 = " 1 = MACD EMA"; extern string xstr4 = " 2 = MACD LSMA"; extern string xstr5 = " 3 = MACD Cross"; extern string xstr6 = " 4 = MACD EMA Cross"; extern string xstr7 = " 5 = MACD LSMA Cross"; extern string xstr8 = " 6 = SMA"; extern string xstr9 = " 7 = EMA"; extern string xstr10 = " 8 = SMMA"; extern string xstr11 = " 9 = LWMA"; extern string xstr12 = " 10 = LSMA"; extern string xstr13 = " 11 = iTrend"; extern string xstr14 = " 12 = HMA"; extern int ExitMethod = 4; extern int MA_ExitPeriod=14; extern int LSMA_ExitPeriod=18; extern int iTrend_ExitPeriod=26; extern int HMA_ExitPeriod = 16; extern int TrendExit_TimeFrame = 0; bool Debug = false; int StartTime2; // Start trades after time int StopTime2; // Stop trading after time double MacdCurrent, MacdPrevious; double SignalCurrent, SignalPrevious; double MACurrent, MAPrevious; //+---------------------------------------------------+ //|General controls | //+---------------------------------------------------+ string setup; double lotMM; int TradesInThisSymbol; int MagicNumber; bool YesStop; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { MagicNumber = 4000 + func_Symbol2Val(Symbol())*100 + func_TimeFrame_Const2Val(Period()); setup="TriplePlay" + Symbol() + "_" + func_TimeFrame_Val2String(func_TimeFrame_Const2Val(Period())); //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { return(0); } //+------------------------------------------------------------------+ //| Custom Indicators | //+------------------------------------------------------------------+ //+------------------------------------------------------------------------+ //| LSMA - Least Squares Moving Average function calculation | //| LSMA_In_Color Indicator plots the end of the linear regression line | //+------------------------------------------------------------------------+ double fLSMA(int LSMA_TimeFrame, int myRperiod, int shift) { int i; double sum; int length; double lengthvar; double tmp; double wt; length = myRperiod; sum = 0; for(i = length; i >= 1 ; i--) { lengthvar = length + 1; lengthvar /= 3; tmp = 0; tmp = ( i - lengthvar)*iClose(Symbol(),LSMA_TimeFrame, length-i+shift); sum+=tmp; } wt = sum*6/(length*(length+1)); // wt = MathFloor(sum*6/(length*(length+1))/Point)*Point; return(wt); } //+------------------------------------------------------------------------+ //| MACD Exits | //| Get the MACD values from different MACD indicators | //| Test for exit code from MACD_Sample | //+------------------------------------------------------------------------+ bool MACD_Exits(int method, int cmd) { switch (method) { case MACD_EXIT : GetMACD(TrendExit_TimeFrame,MODE_SMA); break; case MACD_EMA_EXIT : GetMACD(TrendExit_TimeFrame,MODE_EMA); break; case MACD_LSMA_EXIT : GetMACD(TrendExit_TimeFrame,MODE_LSMA); } switch (cmd) { case OP_BUY : if(MacdCurrent>0 && MacdCurrentSignalPrevious && MacdCurrent>(MACD_CloseLevel*Point)) { return(true); } return(false); break; case OP_SELL : if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious(MACD_CloseLevel*Point)) { return(true); } return(false); } return(false); } //+------------------------------------------------------------------------+ //| MACD Cross Exits | //| Get the MACD values from different MACD indicators | //| Test for exit uses check for histogram cross of zero line | //+------------------------------------------------------------------------+ bool MACD_CrossExits(int method, int cmd) { switch (method) { case MACD_CROSS_EXIT : GetMACD(TrendExit_TimeFrame,MODE_SMA); break; case MACD_EMACROSS_EXIT : GetMACD(TrendExit_TimeFrame,MODE_EMA); break; case MACD_LSMACROSS_EXIT : GetMACD(TrendExit_TimeFrame,MODE_LSMA); break; } switch (cmd) { case OP_BUY : if( SignalCurrent - MacdCurrent > MACD_CloseLevel*Point) { return(true); } return(false); break; case OP_SELL : if(MacdCurrent - SignalCurrent > MACD_CloseLevel * Point) { return(true); } return(false); } return(false); } //+------------------------------------------------------------------------+ //| Trend Exits | //| Get the Moving average values using different MA indicators | //| Test for exit using change of direction | //+------------------------------------------------------------------------+ bool Trend_Exits(int method, int cmd) { switch (method) { case SMA_EXIT : GetMA(TrendExit_TimeFrame,MA_ExitPeriod,MODE_SMA); break; case EMA_EXIT : GetMA(TrendExit_TimeFrame,MA_ExitPeriod,MODE_EMA); break; case SMMA_EXIT : GetMA(TrendExit_TimeFrame,MA_ExitPeriod,MODE_SMMA); break; case LWMA_EXIT : GetMA(TrendExit_TimeFrame,MA_ExitPeriod,MODE_LWMA); break; case LSMA_EXIT : GetMA(TrendExit_TimeFrame,LSMA_ExitPeriod,MODE_LSMA); break; case ITREND_EXIT : GetMA(TrendExit_TimeFrame,iTrend_ExitPeriod,MODE_ITREND); break; case HMA_EXIT : GetMA(TrendExit_TimeFrame,HMA_ExitPeriod,MODE_HMA); } switch (cmd) { case OP_BUY : if (MACurrent < MAPrevious) return(true); return (false); break; case OP_SELL : if(MACurrent > MAPrevious) return(true); return (false); } return(false); } //+------------------------------------------------------------------+ //| CheckExitCondition | //| Check which exit method to test | //+------------------------------------------------------------------+ bool CheckExitCondition(int cmd) { bool ExitTrade; ExitTrade = false; if (ExitMethod < MACD_CROSS_EXIT) { ExitTrade = MACD_Exits(ExitMethod, cmd); return(ExitTrade); } if (ExitMethod < SMA_EXIT) { ExitTrade = MACD_CrossExits(ExitMethod, cmd); return(ExitTrade); } ExitTrade = Trend_Exits(ExitMethod, cmd); return (ExitTrade); } //+------------------------------------------------------------------------+ //| MACD Entries | //| Get the MACD values from different MACD indicators | //| Test for entry code from MACD_Sample | //+------------------------------------------------------------------------+ bool MACD_Entries(int method, int cmd) { bool filter; switch (method) { case MACD : GetMACD(MACD_TimeFrame,MODE_SMA); break; case MACD_EMA : GetMACD(MACD_TimeFrame,MODE_EMA); break; case MACD_LSMA : GetMACD(MACD_TimeFrame,MODE_LSMA); } filter = CheckFilter(cmd); switch (cmd) { case OP_BUY : if(MacdCurrent<0 && MacdCurrent>SignalCurrent && MacdPrevious(MACD_OpenLevel*Point)) { return(filter); } break; case OP_SELL : if(MacdCurrent>0 && MacdCurrentSignalPrevious && MacdCurrent>(MACD_OpenLevel*Point)) { return(filter); } } return(false); } //+------------------------------------------------------------------------+ //| MACD Cross Entries | //| Get the MACD values from different MACD indicators | //| Test for entry uses check for histogram cross of zero line | //+------------------------------------------------------------------------+ bool MACD_CrossEntries(int method, int cmd) { int filter; switch (method) { case MACD_CROSS : GetMACD(MACD_TimeFrame,MODE_SMA); break; case MACD_EMA_CROSS : GetMACD(MACD_TimeFrame,MODE_EMA); break; case MACD_LSMA_CROSS : GetMACD(MACD_TimeFrame,MODE_LSMA); break; } filter = CheckFilter(cmd); switch (cmd) { case OP_BUY : if( MacdCurrent - SignalCurrent > MACD_OpenLevel*Point) { return(filter); } break; case OP_SELL : if(SignalCurrent - MacdCurrent > MACD_OpenLevel * Point) { return(filter); } } return(false); } //+------------------------------------------------------------------------+ //| Trend Entries | //| Get the Moving average values using different MA indicators | //| Test for entry using direction of MA | //+------------------------------------------------------------------------+ bool Trend_Entries(int method, int cmd) { switch (method) { case SMA : GetMA(TrendEntry_TimeFrame,MA_EntryPeriod,MODE_SMA); break; case EMA : GetMA(TrendEntry_TimeFrame,MA_EntryPeriod,MODE_EMA); break; case SMMA : GetMA(TrendEntry_TimeFrame,MA_EntryPeriod,MODE_SMMA); break; case LWMA : GetMA(TrendEntry_TimeFrame,MA_EntryPeriod,MODE_LWMA); break; case LSMA : GetMA(TrendEntry_TimeFrame,LSMA_EntryPeriod,MODE_LSMA); break; case ITREND : GetMA(TrendEntry_TimeFrame,iTrend_EntryPeriod,MODE_ITREND); break; case HMA : GetMA(TrendEntry_TimeFrame,HMA_EntryPeriod,MODE_HMA); } switch (cmd) { case OP_BUY : if (MACurrent > MAPrevious) return(true); return (false); break; case OP_SELL : if(MACurrent < MAPrevious) return(true); return (false); } return(false); } //+------------------------------------------------------------------+ //| CheckEntryCondition | //| Check which entry method to test | //+------------------------------------------------------------------+ bool CheckEntryCondition(int cmd) { bool EnterTrade; EnterTrade = false; if (EntryMethod < MACD_CROSS) { EnterTrade = MACD_Entries(EntryMethod, cmd); return(EnterTrade); } if (EntryMethod < SMA) { EnterTrade = MACD_CrossEntries(EntryMethod, cmd); return(EnterTrade); } EnterTrade = Trend_Entries(EntryMethod, cmd); return (EnterTrade); } //+------------------------------------------------------------------+ //| Get MACD using one of 3 different MACD indicators | //| Places values in global variable | //+------------------------------------------------------------------+ void GetMACD(int TimeFrame, int MACD_Method) { switch (MACD_Method) { case MACD_EMA : MacdCurrent=iCustom(NULL,TimeFrame,"MACD_EMA",FastEMA,SlowEMA,SignalEMA,MODE_MAIN,1); MacdPrevious=iCustom(NULL,TimeFrame,"MACD_EMA",FastEMA,SlowEMA,SignalEMA,MODE_MAIN,2); SignalCurrent=iCustom(NULL,TimeFrame,"MACD_EMA",FastEMA,SlowEMA,SignalEMA,MODE_SIGNAL,1); SignalPrevious=iCustom(NULL,TimeFrame,"MACD_EMA",FastEMA,SlowEMA,SignalEMA,MODE_SIGNAL,2); break; case MACD_LSMA : MacdCurrent=iCustom(NULL,MACD_TimeFrame,"MACD_LSMA",FastEMA,SlowEMA,SignalEMA,MODE_MAIN,1); MacdPrevious=iCustom(NULL,MACD_TimeFrame,"MACD_LSMA",FastEMA,SlowEMA,SignalEMA,MODE_MAIN,2); SignalCurrent=iCustom(NULL,MACD_TimeFrame,"MACD_LSMA",FastEMA,SlowEMA,SignalEMA,MODE_SIGNAL,1); SignalPrevious=iCustom(NULL,MACD_TimeFrame,"MACD_LSMA",FastEMA,SlowEMA,SignalEMA,MODE_SIGNAL,2); break; default : MacdCurrent=iMACD(NULL,MACD_TimeFrame,FastEMA,SlowEMA,SignalEMA,PRICE_CLOSE,MODE_MAIN,1); MacdPrevious=iMACD(NULL,MACD_TimeFrame,FastEMA,SlowEMA,SignalEMA,PRICE_CLOSE,MODE_MAIN,2); SignalCurrent=iMACD(NULL,MACD_TimeFrame,FastEMA,SlowEMA,SignalEMA,PRICE_CLOSE,MODE_SIGNAL,1); SignalPrevious=iMACD(NULL,MACD_TimeFrame,FastEMA,SlowEMA,SignalEMA,PRICE_CLOSE,MODE_SIGNAL,2); break; } } //+------------------------------------------------------------------+ //| Get Moving Average using one of 7 different MA indicators | //| Places values in global variable | //+------------------------------------------------------------------+ void GetMA(int TimeFrame, int MAPeriod, int mode) { if (mode < MODE_LSMA) { MACurrent=iMA(NULL,TimeFrame,MAPeriod,0,mode,PRICE_CLOSE,1); MAPrevious=iMA(NULL,TimeFrame,MAPeriod,0,mode,PRICE_CLOSE,2); } else { switch (mode) { case MODE_LSMA : MACurrent=fLSMA(TimeFrame,MAPeriod,1); MAPrevious=fLSMA(TimeFrame,MAPeriod,2); break; case MODE_ITREND : MACurrent=iCustom(NULL,TimeFrame,"Ehlers_iTrend",MAPeriod,0,1); MAPrevious=iCustom(NULL,TimeFrame,"Ehlers_iTrend",MAPeriod,0,2); break; case MODE_HMA : MACurrent=iCustom(NULL,TimeFrame,"HMA2",MAPeriod,0,1); MAPrevious=iCustom(NULL,TimeFrame,"HMA2",MAPeriod,0,2); } } } //+------------------------------------------------------------------+ //| Check Filter | //| Uses the filter idea from MACD_Sample | //| Get Moving Average using one of 7 different MA indicators | //| Returns true if filter allows trade | //+------------------------------------------------------------------+ bool CheckFilter (int cmd) { bool filter = false; int myFilterMAPeriod, myFilterMode; filter = false; if (FilterMethod == NO_FILTER) filter = true; else { if (FilterMethod < LSMA_FILTER) { myFilterMAPeriod = MA_FilterPeriod; myFilterMode = FilterMethod - 1; } else { switch(FilterMethod) { case LSMA_FILTER : myFilterMAPeriod = LSMA_FilterPeriod; myFilterMode = MODE_LSMA; break; case ITREND_FILTER : myFilterMAPeriod = iTrend_FilterPeriod; myFilterMode = MODE_ITREND; break; case HMA_FILTER : myFilterMAPeriod = HMA_FilterPeriod; myFilterMode = MODE_HMA; break; } } GetMA(TrendFilter_TimeFrame, myFilterMAPeriod, myFilterMode); filter = false; switch (cmd) { case OP_BUY : if (MACurrent > MAPrevious) filter = true; break; case OP_SELL : if (MACurrent < MAPrevious) filter = true; } } return (filter); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---- /* if (Period() != 60) { Alert("60 Minute Chart Only."); return(0); } */ //+------------------------------------------------------------------+ //| Check for Open Position | //+------------------------------------------------------------------+ HandleOpenPositions(); // Check if any open positions were not closed TradesInThisSymbol = CheckOpenPositions(); //+------------------------------------------------------------------+ //| Check if OK to make new trades | //+------------------------------------------------------------------+ if(AccountFreeMargin() < Margincutoff) { return(0);} // Only allow 1 trade per Symbol if(TradesInThisSymbol > 0) { return(0);} // setup times to trade based on Day Light Savings Time if (UseDST) { StartTime2 = StartHour - 1; if (StartTime2 < 0) StartTime2 = 0; StopTime2 = StopHour - 1; } else { StartTime2 = StartHour; StopTime2 = StopHour; } if (Hour() > StopTime2) return(0); if (Hour() < StartTime2) return(0); lotMM = GetLots(); // if(CheckEntryConditionBUY() && !CheckExitConditionBUY()) if(CheckEntryCondition(OP_BUY) ) { CloseOpenOrders(OP_SELL); // This also deletes pending orders OpenBuyOrders(); return(0); } // if(CheckEntryConditionSELL() && !CheckExitConditionSELL()) if(CheckEntryCondition(OP_SELL) ) { CloseOpenOrders(OP_BUY); // This also deletes pending orders OpenSellOrders(); } //---- return(0); } //+------------------------------------------------------------------+ //| OpenBuyOrder | //| If Stop Loss or TakeProfit are used the values are calculated | //| for each trade | //| place 3 orders : //| - 1 st order , 1 lot TARGET 30 pips //| - 2 nd order , 2 lot placed first order price +10 pips TARGET 20 pips //| - 3 nd order , 3 lot placed first order price +20 pips TARGET 10 pips //+------------------------------------------------------------------+ void OpenBuyOrders( ) { int ticket, digits, err; double myPrice, myStopLoss, myTakeProfit; myPrice = MarketInfo(Symbol( ), MODE_ASK); myStopLoss = 0; if ( StopLoss > 0 ) myStopLoss = myPrice - StopLoss * Point ; myTakeProfit = myPrice + TakeProfit1 * Point; // Normalize all price / stoploss / takeprofit to the proper # of digits. digits = MarketInfo(Symbol( ), MODE_DIGITS) ; if (digits > 0) { myPrice = NormalizeDouble( myPrice, digits); myStopLoss = NormalizeDouble( myStopLoss, digits); myTakeProfit = NormalizeDouble( myTakeProfit, digits); } ticket=OrderSend( Symbol(), OP_BUY, lotMM, myPrice, Slippage, myStopLoss, myTakeProfit, "FirstBuy", MagicNumber, 0, Green); if (ticket > 0) { if (OrderSelect( ticket,SELECT_BY_TICKET, MODE_TRADES) ) { if (Debug) Print("BUY order opened : ", OrderOpenPrice( )); myPrice = OrderOpenPrice() + FirstLevel*Point; myStopLoss = 0; if ( StopLoss > 0 ) myStopLoss = myPrice - StopLoss * Point ; myTakeProfit = myPrice + TakeProfit2*Point; if (digits > 0) { myPrice = NormalizeDouble( myPrice, digits); myStopLoss = NormalizeDouble( myStopLoss, digits); myTakeProfit = NormalizeDouble( myTakeProfit, digits); } ticket=OrderSend( Symbol(), OP_BUYSTOP, 2*lotMM, myPrice, Slippage, myStopLoss, myTakeProfit, "Second Buy", MagicNumber, 0, Green); myPrice = OrderOpenPrice() + SecondLevel*Point; myStopLoss = 0; if ( StopLoss > 0 ) myStopLoss = myPrice - StopLoss * Point ; myTakeProfit = myPrice + TakeProfit3*Point; if (digits > 0) { myPrice = NormalizeDouble( myPrice, digits); myStopLoss = NormalizeDouble( myStopLoss, digits); myTakeProfit = NormalizeDouble( myTakeProfit, digits); } ticket=OrderSend( Symbol(), OP_BUYSTOP, 3*lotMM, myPrice, Slippage, myStopLoss, myTakeProfit, "Third Buy", MagicNumber, 0 ,Green); } } else { err = GetLastError(); Print("Error opening BUY order : (" + err + ") " + ErrorDescription( err) ); } } //+------------------------------------------------------------------+ //| OpenSellOrder | //| If Stop Loss or TakeProfit are used the values are calculated | //| for each trade | //| - 1 st order , 1 lot TARGET 30 pips //| - 2 nd order , 2 lot placed first order price +10 pips TARGET 20 pips //| - 3 nd order , 3 lot placed first order price +20 pips TARGET 10 pips //+------------------------------------------------------------------+ void OpenSellOrders( ) { int ticket, digits, err; double myPrice, myStopLoss, myTakeProfit; myPrice = MarketInfo(Symbol( ), MODE_BID); myStopLoss = 0; if ( StopLoss > 0 ) myStopLoss = myPrice + StopLoss * Point ; myTakeProfit = myPrice - TakeProfit1 * Point; // Normalize all price / stoploss / takeprofit to the proper # of digits. digits = MarketInfo(Symbol( ), MODE_DIGITS) ; if (digits > 0) { myPrice = NormalizeDouble( myPrice, digits); myStopLoss = NormalizeDouble( myStopLoss, digits); myTakeProfit = NormalizeDouble( myTakeProfit, digits); } ticket=OrderSend( Symbol(), OP_SELL, lotMM, myPrice, Slippage, myStopLoss ,myTakeProfit, "First Sell", MagicNumber, 0, Red); if (ticket > 0) { if (OrderSelect( ticket,SELECT_BY_TICKET, MODE_TRADES) ) { if (Debug) Print("Sell order opened : ", OrderOpenPrice()); myPrice = OrderOpenPrice() - FirstLevel*Point; myStopLoss = 0; if ( StopLoss > 0 ) myStopLoss = myPrice + StopLoss * Point ; myTakeProfit = myPrice - TakeProfit2*Point; if (digits > 0) { myPrice = NormalizeDouble( myPrice, digits); myStopLoss = NormalizeDouble( myStopLoss, digits); myTakeProfit = NormalizeDouble( myTakeProfit, digits); } ticket=OrderSend( Symbol(), OP_SELLSTOP, 2*lotMM, myPrice, Slippage, myStopLoss, myTakeProfit, "Second Sell", MagicNumber, 0, Red); myPrice = OrderOpenPrice() - SecondLevel*Point; myStopLoss = 0; if ( StopLoss > 0 ) myStopLoss = myPrice + StopLoss * Point ; myTakeProfit = myPrice - TakeProfit3*Point; if (digits > 0) { myPrice = NormalizeDouble( myPrice, digits); myStopLoss = NormalizeDouble( myStopLoss, digits); myTakeProfit = NormalizeDouble( myTakeProfit, digits); } ticket=OrderSend( Symbol(), OP_SELLSTOP, 3*lotMM, myPrice, Slippage, myStopLoss, myTakeProfit, "Third Sell", MagicNumber, 0, Red); } } else { err = GetLastError(); Print("Error opening Sell order : (" + err + ") " + ErrorDescription( err) ); } } //+------------------------------------------------------------------+ //| Check Open Position Controls | //+------------------------------------------------------------------+ int CheckOpenPositions() { int cnt, total, NumPositions; NumPositions = 0; total=OrdersTotal(); for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES); if ( OrderSymbol() != Symbol()) continue; if ( OrderMagicNumber() != MagicNumber) continue; if(OrderType() == OP_BUY ) NumPositions++; if(OrderType() == OP_SELL ) NumPositions++; } return (NumPositions); } //+------------------------------------------------------------------+ //| Close Open Position Controls | //| Try to close position 3 times | //+------------------------------------------------------------------+ int CloseOrder(int ticket,double numLots,int type) { int CloseCnt, err; double close_price; // try to close 3 Times CloseCnt = 0; while (CloseCnt < 3) { switch (type) { case OP_BUY : close_price = MarketInfo(Symbol(),MODE_BID); break; case OP_SELL : close_price = MarketInfo(Symbol(),MODE_ASK); } if (!OrderClose(ticket,numLots,close_price,Slippage,Violet)) { err=GetLastError(); Print(CloseCnt," Error closing order : (", err , ") " + ErrorDescription(err)); if (err > 0) CloseCnt++; } else { CloseCnt = 3; } } } int ModifyStopLoss(int ticket, double stoploss) { int Cnt, digits, err; string symbol; double myStopLoss; OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES); symbol = OrderSymbol(); digits = MarketInfo(symbol,MODE_DIGITS); if (digits > 0) { myStopLoss = NormalizeDouble(stoploss,digits); } Cnt=0; while (Cnt < 3) { if (OrderModify(ticket,OrderOpenPrice(),myStopLoss,OrderTakeProfit(),0,Aqua)) { Cnt = 3; } else { err=GetLastError(); Print(Cnt," Error modifying order : (", err , ") " + ErrorDescription(err)); if (err>0) Cnt++; } } } //+------------------------------------------------------------------+ //| Handle Open Positions | //| Check if any open positions need to be closed or modified | //+------------------------------------------------------------------+ int HandleOpenPositions() { int cnt; bool YesClose; double pt; for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES); if ( OrderSymbol() != Symbol()) continue; if ( OrderMagicNumber() != MagicNumber) continue; if(OrderType() == OP_BUY) { if (CheckExitCondition(OP_BUY)) { CloseOrder(OrderTicket(),OrderLots(),OP_BUY); DeletePendingOrders(); return(0); } if (UseTrailingStop) // Handle mods to trailing stop HandleTrailingStop(OrderType(), OrderTicket(), OrderOpenPrice(), OrderStopLoss()); } if(OrderType() == OP_SELL) { if (CheckExitCondition(OP_SELL)) { CloseOrder(OrderTicket(),OrderLots(),OP_SELL); DeletePendingOrders(); return(0); } if (UseTrailingStop) // Handle mods to trailing stop HandleTrailingStop(OrderType(), OrderTicket(), OrderOpenPrice(), OrderStopLoss()); } } return(0); } //============================================================================= // // HandleTrailingStop() // // Type 1 moves the stoploss without delay. // // Type 2 waits for price to move the amount of the trailStop // before moving stop loss then moves like type 1 // // // PARAMETERS: // // type: OP_BUY or OP_SELL // ticket: the ticket number // open_price: the order's open price // cur_sl: the order's current StopLoss value // // RETURN VALUE: // zero for now // // Calling example // HandleTrailingStop(OP_BUY,OrderTicket(),OrderOpenPrice(),OrderStopLoss()); // //============================================================================= int HandleTrailingStop(int type, int ticket, double open_price, double cur_sl) { double pt, TS = 0, myAsk, myBid; if (type == OP_BUY) { myBid = MarketInfo(Symbol(),MODE_BID); switch (TrailingStopType) { case 1: pt = Point * StopLoss; if (myBid - cur_sl > pt) ModifyStopLoss(ticket, myBid - pt); break; case 2: pt = Point * TrailingStop; if (myBid - open_price > pt && (cur_sl < myBid - pt || cur_sl == 0)) ModifyStopLoss(ticket, myBid - pt); break; } return(0); } else if (type == OP_SELL) { myAsk = MarketInfo(Symbol(),MODE_ASK); switch (TrailingStopType) { case 1: pt = Point * StopLoss; if (cur_sl - myAsk > pt) ModifyStopLoss(ticket, myAsk+pt); break; case 2: pt = Point * TrailingStop; if (open_price - myAsk > pt && (cur_sl > myAsk + pt || cur_sl == 0)) ModifyStopLoss(ticket, myAsk+pt); break; } } return(0); } //+------------------------------------------------------------------+ //| Close Open Orders | //| Check if any open positions need to be closed or modified | //+------------------------------------------------------------------+ int CloseOpenOrders(int cmd) { int cnt; bool YesClose; double pt; for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES); if ( OrderSymbol() != Symbol()) continue; if ( OrderMagicNumber() != MagicNumber) continue; if(OrderType() == OP_BUY) { if (cmd == OP_BUY) { CloseOrder(OrderTicket(),OrderLots(),Bid); DeletePendingOrders(); } } if(OrderType() == OP_SELL) { if (cmd == OP_SELL) { CloseOrder(OrderTicket(),OrderLots(),Ask); DeletePendingOrders(); } } } } //+------------------------------------------------------------------+ int DeletePendingOrders() { int i, ticket; //Check Orders for (i=OrdersTotal()-1;i>0;i--){ OrderSelect(i,SELECT_BY_POS,MODE_TRADES); if(OrderSymbol()!=Symbol()) continue; if (OrderMagicNumber() != MagicNumber) continue; if( OrderType()==OP_BUYSTOP) OrderDelete(OrderTicket()); if( OrderType()==OP_SELLSTOP) OrderDelete(OrderTicket()); } } //+------------------------------------------------------------------+ //| Get number of lots for this trade | //+------------------------------------------------------------------+ double GetLots() { double lot; if(MoneyManagement) { lot = LotsOptimized(); } else { lot = Lots; } if(AccountIsMini) { if (lot < 0.1) lot = 0.1; } else { if (lot >= 1.0) lot = MathFloor(lot); else lot = 1.0; } if (lot > MaxLots) lot = MaxLots; return(lot); } //+------------------------------------------------------------------+ //| Calculate optimal lot size | //+------------------------------------------------------------------+ double LotsOptimized() { double lot=Lots; int TradePercent; TradePercent = TradeSizePercent; if (TradeSizePercent > 5) TradePercent = 5; //---- select lot size lot=NormalizeDouble(MathFloor(AccountFreeMargin()*TradePercent/10000)/10,1); // lot at this point is number of standard lots // if (Debug) Print ("Lots in LotsOptimized : ",lot); // Check if mini or standard Account if(AccountIsMini) { lot = MathFloor(lot*10)/10; } return(lot); } //+------------------------------------------------------------------+ //| Time frame interval appropriation function | //+------------------------------------------------------------------+ int func_TimeFrame_Const2Val(int Constant ) { switch(Constant) { case 1: // M1 return(1); case 5: // M5 return(2); case 15: return(3); case 30: return(4); case 60: return(5); case 240: return(6); case 1440: return(7); case 10080: return(8); case 43200: return(9); } } //+------------------------------------------------------------------+ //| Time frame string appropriation function | //+------------------------------------------------------------------+ string func_TimeFrame_Val2String(int Value ) { switch(Value) { case 1: // M1 return("PERIOD_M1"); case 2: // M1 return("PERIOD_M5"); case 3: return("PERIOD_M15"); case 4: return("PERIOD_M30"); case 5: return("PERIOD_H1"); case 6: return("PERIOD_H4"); case 7: return("PERIOD_D1"); case 8: return("PERIOD_W1"); case 9: return("PERIOD_MN1"); default: return("undefined " + Value); } } int func_Symbol2Val(string symbol) { if(symbol=="AUDCAD") { return(1); } else if(symbol=="AUDJPY") { return(2); } else if(symbol=="AUDNZD") { return(3); } else if(symbol=="AUDUSD") { return(4); } else if(symbol=="CHFJPY") { return(5); } else if(symbol=="EURAUD") { return(6); } else if(symbol=="EURCAD") { return(7); } else if(symbol=="EURCHF") { return(8); } else if(symbol=="EURGBP") { return(9); } else if(symbol=="EURJPY") { return(10); } else if(symbol=="EURUSD") { return(11); } else if(symbol=="GBPCHF") { return(12); } else if(symbol=="GBPJPY") { return(13); } else if(symbol=="GBPUSD") { return(14); } else if(symbol=="NZDUSD") { return(15); } else if(symbol=="USDCAD") { return(16); } else if(symbol=="USDCHF") { return(17); } else if(symbol=="USDJPY") { return(18); } else { Comment("unexpected Symbol"); return(0); } }