//+------------------------------------------------------------------+ //| RHc_Bombshell.mq4 //| Copyright © 2005-2006, Lifestatic/Zap, pip_seeker, pip_hunter, autofx //| //+------------------------------------------------------------------+ #property copyright "Copyright © 2005-2006, Lifestatic/Zap, pip_seeker, pip_hunter, autofx" ///////////////////////// // External Definitions; ///////////////////////// extern double Lots = 1.0; // Number of lots to use for each trade; please keep at 1.0 extern double LotSize = 1.0; // Change this number to trade more than 1 nano lot. extern int SymbolPLFactor = 100; // This value times UseLots gives the SymbolPL dollar profit target extern int GravyFactor = 5000; // This value times UseLots gives GravyExit (gravy PL vs pair PL profit target) extern int Slippage = 4; // Slippage extern int PauseSeconds = 0; // Number of seconds to "sleep" before closing the next winning trade extern bool StopAfterNoTrades = false; // Set to true to give yourself a chance to set Lots // to a new value after existing grid closes. // Set back to false to allow a new grid to be built // after adjusting Lots value. extern bool MM = true; // Leave StopAfterNoTrades false and set MM // true to enable automatic lot size calculations // between grids. // MM == False means use Lots for actual lot size. // MM == True means use Money Management logic to calc actual lot size. extern double MinLots = 0.01; // Define minimum allowable lot size extern int MaxLots = 50; // Define maximum allowable lot size. extern double LotFactor = 3.0; extern int RockBottomEquity = 250; extern int MinEqForMinLots = 2000; // Define minimum balance required for trading smallest // allowed lot size. extern double Threshold = 20.0; // Used for Bombshell mode extern double ProfitTarget = 15.0; // Used for Bombshell mode //////////// // Variables //////////// double UseLots, BombshellLots, SymbolPL, SymbolPLExit, GravyExit; int i; int NumBuys, NumSells, BuyNewLevel, SellNewLevel; double HighestBuy, LowestBuy, HighestSell, LowestSell; bool CloseSwitch, CloseAll, WaitSwitch, ClockSwitch; int SetB, SetS, KeepBuys, KeepSells, BalGrid; int SkipMPA, EmaClock; double PointValue, EmaMin, EmaValue, EMACounter, CurValue; int StopBal, StopBalS, StopBalB; double FiveEMA_0, FiveEMA_1, TwentyEMA_0, TwentyEMA_1, HundredEMA_0, HundredEMA_1; string GravyFlag; int valueGravyFlag; string GravyProfit; double valueGravyProfit; string CurrBalance; double valueCurrBalance; double LastPrice, Anchor; // Used for Bombshell mode //+------------------------------------------------------------------+ //| Expert Initialization | //+------------------------------------------------------------------+ int init() { LastPrice = Bid; Anchor = (Ask+Bid)/2; return(0); } int start() { // Specify a name for the global gravy flag variable. GravyFlag = AccountNumber()+"_"+Symbol()+"_"+Period()+"_GravyFlag"; // Define the variable if it doesn't already exist. if (!GlobalVariableCheck(GravyFlag)) { GlobalVariableSet(GravyFlag, 0); } // Get a value. valueGravyFlag= GlobalVariableGet(GravyFlag); // Specify a name for the global variable that tracks gravy profit. GravyProfit = AccountNumber()+"_"+Symbol()+"_"+Period()+"_GravyProfit"; // Define the variable if it doesn't already exist. if (!GlobalVariableCheck(GravyProfit)) { GlobalVariableSet(GravyProfit, 0); } // Get a value. valueGravyProfit = GlobalVariableGet(GravyProfit); // Specify a name for the global variable that tracks the current balance. CurrBalance = AccountNumber()+"_"+Symbol()+"_"+Period()+"_CurrBalance"; // Define the variable if it doesn't already exist. if (!GlobalVariableCheck(CurrBalance)) { GlobalVariableSet(CurrBalance, 0); } // Get a value. valueCurrBalance = GlobalVariableGet(CurrBalance); /////////////////////////////////////////////////// // If closing switch is true, close all open trades /////////////////////////////////////////////////// if (CloseAll) { for(i = OrdersTotal()-1; i >=0; i--) { OrderSelect(i,SELECT_BY_POS,MODE_TRADES); if (OrderSymbol() == Symbol()) { if (OrderType() == OP_BUY && OrderProfit() < 0) { Comment("In grid closure mode. Closing a loser..."); OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,White); } if (OrderType() == OP_SELL && OrderProfit() < 0) { Comment("In grid closure mode. Closing a loser..."); OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,White); } } } for(i = OrdersTotal()-1; i >=0; i--) { OrderSelect(i,SELECT_BY_POS,MODE_TRADES); if (OrderSymbol() == Symbol()) { if (OrderType() == OP_BUY && OrderProfit() >= 0) { Sleep(PauseSeconds*1000); Comment("In grid closure mode. Closing a winner..."); OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,White); } if (OrderType() == OP_SELL && OrderProfit() >= 0) { Sleep(PauseSeconds*1000); Comment("In grid closure mode. Closing a winner..."); OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,White); } } } } ///////////////////////////// // Initialize Key Variables; ///////////////////////////// if (Bid > LastPrice) LastPrice = Bid; if (Ask < LastPrice) LastPrice = Ask; NumBuys = 0; NumSells = 0; SymbolPL = 0; LowestBuy = 1000; HighestSell = 0; HighestBuy = 0; LowestSell = 1000; BuyNewLevel = 0; SellNewLevel = 0; for(i = 0; i < OrdersTotal(); i++) { OrderSelect(i,SELECT_BY_POS,MODE_TRADES); if (OrderSymbol() == Symbol()) { SymbolPL += OrderProfit(); if (OrderType() == OP_BUY) { NumBuys++; if (OrderOpenPrice() < LowestBuy) LowestBuy = OrderOpenPrice(); if (OrderOpenPrice() > HighestBuy) HighestBuy = OrderOpenPrice(); if (OrderOpenPrice() == Ask) BuyNewLevel = 1; } if (OrderType() == OP_SELL) { NumSells++; if (OrderOpenPrice() > HighestSell) HighestSell = OrderOpenPrice(); if (OrderOpenPrice() < LowestSell) LowestSell = OrderOpenPrice(); if (OrderOpenPrice() == Bid) SellNewLevel = 1; } } } for(i = 0; i < OrdersTotal(); i++) { OrderSelect(i,SELECT_BY_POS,MODE_TRADES); if (OrderSymbol() == Symbol()) { //////////////////////////////////////////////////////////////////////////////////////////// // Close Profitable Orders Routine to avoid S.T.U.C.K. [Stupid Trades Unite to Cause Khaos] //////////////////////////////////////////////////////////////////////////////////////////// if ((!CloseAll || StopBal == 1) && (OrderProfit() >= PointValue)) { if (StopBalS == 1 && OrderType() == OP_BUY && LowestBuy <= Bid) { Comment("Taking RobinHood_c gravy pips..."); OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Magenta); GlobalVariableSet(GravyFlag, 1); SetS = 1; return(0); } if (StopBalB == 1 && OrderType() == OP_SELL && HighestSell >= Ask) { Comment("Taking RobinHood_c gravy pips..."); OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Yellow); GlobalVariableSet(GravyFlag, 1); SetB = 1; return(0); } if ((KeepBuys == 1 || KeepSells == 1 || BalGrid == 1) && valueGravyProfit + SymbolPL < GravyExit) { /////////////////////////////// // Enter S.T.U.C.K. Relief mode /////////////////////////////// if (KeepBuys == 1 && NumBuys < NumSells && OrderType() == OP_SELL) { Comment("Taking RobinHood_c gravy pips..."); OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Yellow); GlobalVariableSet(GravyFlag, 1); SetB = 1; return(0); } if (KeepSells == 1 && NumSells < NumBuys && OrderType() == OP_BUY) { Comment("Taking RobinHood_c gravy pips..."); OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Orange); GlobalVariableSet(GravyFlag, 1); SetS = 1; return(0); } if (BalGrid == 1 && NumSells >= 2 && NumBuys >= 2) { if (NumSells-3 < NumBuys && OrderType() == OP_BUY) { Comment("Taking RobinHood_c gravy pips..."); OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Purple); GlobalVariableSet(GravyFlag, 1); SetS = 1; return(0); } if (NumBuys-3 < NumSells && OrderType() == OP_SELL) { Comment("Taking RobinHood_c gravy pips..."); OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Purple); GlobalVariableSet(GravyFlag, 1); SetB = 1; return(0); } } } } } } //////////////////////////////////////////////////////////////////// // If no trades are open, give trader a chance to change Lots before // starting the next grid if StopAfterNoTrades is true, or initialize // the closure-related variables and calculate actual lot size to // use for trades in upcoming grid. //////////////////////////////////////////////////////////////////// if (NumBuys+NumSells == 0) { Comment("There are no trades open."); if (StopAfterNoTrades) return(0); SkipMPA = 0; EMACounter = 0; StopBal = 0; StopBalB = 0; StopBalS = 0; CloseAll = 0; CloseSwitch = false; WaitSwitch = false; ClockSwitch = false; SetS = 0; SetB = 0; valueGravyProfit = 0; } else if (NumBuys+NumSells > 0 && AccountBalance() > valueCurrBalance && valueGravyFlag == 1) { valueGravyProfit = valueGravyProfit + (AccountBalance() - valueCurrBalance); GlobalVariableSet(GravyProfit, valueGravyProfit); GlobalVariableSet(CurrBalance, AccountBalance()); GlobalVariableSet(GravyFlag, 0); } else if (valueGravyFlag == 0) { GlobalVariableSet(CurrBalance, AccountBalance()); } SymbolPLExit = SymbolPLFactor*UseLots; GravyExit = GravyFactor*UseLots; if (MM) { UseLots = MinLots*(AccountEquity()/MinEqForMinLots); UseLots = StrToDouble(DoubleToStr(UseLots, 2)); if (UseLots < MinLots) UseLots = MinLots; if (UseLots > MaxLots) UseLots = MaxLots; } else UseLots = (Lots*LotSize)/100; BombshellLots = UseLots*LotFactor; if (BombshellLots > MaxLots) BombshellLots = MaxLots; BombshellLots = StrToDouble(DoubleToStr(BombshellLots, 2)); //////////////////////////// // Print statistics to chart //////////////////////////// Comment("Symbol's total trades: ",NumBuys+NumSells,", Buy trades: ",NumBuys,", Sell trades: ",NumSells, "\nCurValue: ", CurValue, "\nGridSize: ",(HighestBuy-LowestSell)/Point," pips", "\nBalance: ",AccountBalance(),", Equity: ",AccountEquity(),", TotalProfit: ",AccountProfit(), "\nHighestBuy: ",HighestBuy,", LowestBuy: ",LowestBuy, "\nHighestSell: ",HighestSell,", LowestSell: ",LowestSell, "\nSymbol PL: ",SymbolPL, "\nPL Dollar Target: ",SymbolPLExit, "\nGravy Profit: ",valueGravyProfit, "\nGravy + SymbolPL: ",valueGravyProfit + SymbolPL, "\nGravy Dollar Target: ",GravyExit, "\nLastPrice: ",LastPrice, "\nAnchor: ",Anchor); ///////////////////////// // Indicator Calculations ///////////////////////// FiveEMA_0 = iMA(NULL,NULL, 5,0,MODE_EMA,PRICE_CLOSE,0); FiveEMA_1 = iMA(NULL,NULL, 5,0,MODE_EMA,PRICE_CLOSE,1); TwentyEMA_0 = iMA(NULL,NULL, 20,0,MODE_EMA,PRICE_CLOSE,0); TwentyEMA_1 = iMA(NULL,NULL, 20,0,MODE_EMA,PRICE_CLOSE,1); HundredEMA_0 = iMA(NULL,NULL,100,0,MODE_EMA,PRICE_CLOSE,0); HundredEMA_1 = iMA(NULL,NULL,100,0,MODE_EMA,PRICE_CLOSE,1); /////////////////////////////////////////////// // Go back to normal mode if conditions warrant /////////////////////////////////////////////// if ((StopBalB == 1 && FiveEMA_0 < HundredEMA_0) || (StopBalS == 1 && FiveEMA_0 > HundredEMA_0)) { SkipMPA = 0; EMACounter = 0; StopBal = 0; StopBalB = 0; StopBalS = 0; WaitSwitch = false; ClockSwitch = false; if (FiveEMA_0 < HundredEMA_0) SetS = 1; if (FiveEMA_0 > HundredEMA_0) SetB = 1; } ///////////////////////////////////// // Begin Market Positioning Arguments ///////////////////////////////////// if (WaitSwitch && !ClockSwitch) { EmaClock = Hour(); EmaMin = Minute(); ClockSwitch = true; } if (Hour()-EmaClock >= 1 && Minute()-EmaMin >= 0) { WaitSwitch = false; ClockSwitch = false; } if (CloseAll == 0 && SkipMPA == 0) { if (FiveEMA_0 > TwentyEMA_0 && FiveEMA_1 > TwentyEMA_1 && FiveEMA_0 > HundredEMA_0 && FiveEMA_1 > HundredEMA_1) { KeepBuys = 1; KeepSells = 0; BalGrid = 0; PointValue = UseLots*10; } if (FiveEMA_0 < TwentyEMA_0 && FiveEMA_1 < TwentyEMA_1 && FiveEMA_0 < HundredEMA_0 && FiveEMA_1 < HundredEMA_1) { KeepSells = 1; KeepBuys = 0; BalGrid = 0; PointValue = UseLots*10; } if (FiveEMA_0 < TwentyEMA_0 && FiveEMA_1 < TwentyEMA_1 && FiveEMA_0 > HundredEMA_0 && FiveEMA_1 > HundredEMA_1) { BalGrid = 1; KeepBuys = 0; KeepSells = 0; PointValue = UseLots*7; } if (FiveEMA_1 > HundredEMA_1 && FiveEMA_1 < (HundredEMA_1 + (15*Point)) && !WaitSwitch) { WaitSwitch = true; EmaValue = FiveEMA_1; EMACounter++; } if (WaitSwitch) { if (EmaValue < CurValue) CurValue = EmaValue; else if (CurValue == 0) CurValue = EmaValue; } if (FiveEMA_0 > (CurValue + (10*Point)) && EMACounter >= 4) { SkipMPA = 1; StopBal = 1; StopBalB = 1; BalGrid = 0; KeepSells = 0; KeepBuys = 0; PointValue = 0; } if (FiveEMA_0 > TwentyEMA_0 && FiveEMA_1 > TwentyEMA_1 && FiveEMA_0 < HundredEMA_0 && FiveEMA_1 < HundredEMA_1) { BalGrid = 1; KeepBuys = 0; KeepSells = 0; PointValue = UseLots*7; } if (FiveEMA_1 < HundredEMA_1 && FiveEMA_1 > (HundredEMA_1 - (15*Point)) && !WaitSwitch) { WaitSwitch = true; EmaValue = FiveEMA_1; EMACounter++; } if (WaitSwitch && EmaValue > CurValue) CurValue = EmaValue; if (FiveEMA_0 < (CurValue - (10*Point)) && EMACounter >= 4) { SkipMPA = 1; StopBal = 1; StopBalS = 1; BalGrid = 0; KeepSells = 0; KeepBuys = 0; PointValue = 0; } } ////////////////////////////////////////////////// // If Profit is positive, close all open positions ////////////////////////////////////////////////// if (!CloseSwitch && ((valueGravyProfit == 0 && SymbolPL > SymbolPLExit) || valueGravyProfit + SymbolPL > GravyExit)) { KeepBuys = 0; KeepSells = 0; BalGrid = 0; SetB = 0; SetS = 0; CloseAll = true; CloseSwitch = true; } if (AccountEquity() < RockBottomEquity) return(0); ///////////////////////////////////////////////// // If closing switch set to 0, we want new orders ///////////////////////////////////////////////// if (!CloseAll) { //////////////////// // Open First Trades //////////////////// if (NumBuys >= 0 || NumSells >= 0) { if (NumBuys == 0) { Comment("Opening the first buy trade..."); GlobalVariableSet(GravyProfit, 0); GlobalVariableSet(CurrBalance, AccountBalance()); OrderSend(Symbol(),OP_BUY,UseLots,Ask,Slippage,0,0,"RHc_Bombshell",0,0,Blue); return(0); } if (NumSells == 0) { Comment("Opening the first sell trade..."); OrderSend(Symbol(),OP_SELL,UseLots,Bid,Slippage,0,0,"RHc_Bombshell",0,0,Red); return(0); } ////////////////////////////// // Open additional grid trades ////////////////////////////// if (SetB == 1 && Ask > HighestSell && BuyNewLevel == 0 && SymbolPL < 0) { Comment("Adding a RobinHood_c buy trade..."); OrderSend(Symbol(),OP_BUY,UseLots,Ask,Slippage,0,0,"RHc_Bombshell",0,0,Blue); SetB = 0; return(0); } if (SetS == 1 && Bid < LowestBuy && SellNewLevel == 0 && SymbolPL < 0) { Comment("Adding a RobinHood_c sell trade..."); OrderSend(Symbol(),OP_SELL,UseLots,Bid,Slippage,0,0,"RHc_Bombshell",0,0,Red); SetS = 0; return(0); } if (Ask > LowestBuy && BuyNewLevel == 0 && SymbolPL < 0) { Comment("Adding a RobinHood_c buy trade..."); OrderSend(Symbol(),OP_BUY,UseLots,Ask,Slippage,0,0,"RHc_Bombshell",0,0,Blue); return(0); } if (Bid < HighestSell && SellNewLevel == 0 && SymbolPL < 0) { Comment("Adding a RobinHood_c sell trade..."); OrderSend(Symbol(),OP_SELL,UseLots,Bid,Slippage,0,0,"RHc_Bombshell",0,0,Red); return(0); } //+------------------------------------------------------------------+ //| Manage Our Open Bombshell Buy Orders | //+------------------------------------------------------------------+ for(i = 0; i < OrdersTotal(); i++) { OrderSelect(i,SELECT_BY_POS,MODE_TRADES); if (OrderLots() > UseLots*2.0 && OrderSymbol() == Symbol() && OrderType() == OP_BUY && Bid - OrderOpenPrice() >= ProfitTarget*Point) { Comment("Taking Bombshell gravy pips..."); OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,LightBlue); GlobalVariableSet(GravyFlag, 1); Print ("Errors Closing *in profit* BUY order = ",GetLastError()); return(0); } } //+------------------------------------------------------------------+ //| Manage Our Open Bombshell Sell Orders | //+------------------------------------------------------------------+ for(i = 0; i < OrdersTotal(); i++) { OrderSelect(i,SELECT_BY_POS,MODE_TRADES); if (OrderLots() > UseLots*2.0 && OrderSymbol() == Symbol() && OrderType() == OP_SELL && OrderOpenPrice() - Ask >= ProfitTarget*Point) { Comment("Taking Bombshell gravy pips..."); OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,LightPink); GlobalVariableSet(GravyFlag, 1); Print ("Errors Closing *in profit* SELL order = ",GetLastError()); return(0); } } //+------------------------------------------------------------------+ //| Price Moving Up - Open Bombshell Short | //+------------------------------------------------------------------+ if (LastPrice >= Anchor + Threshold * Point) { Anchor = LastPrice; if (Bid < LowestBuy) { Comment("Adding a Bombshell sell trade..."); OrderSend(Symbol(),OP_SELL,BombshellLots,Bid,Slippage,0,0,"RHc_Bombshell",0,0,Red); Print ("Errors opening SELL order = ",GetLastError()); return(0); } } //+------------------------------------------------------------------+ //| Price Moving Down - Open Bombshell Long | //+------------------------------------------------------------------+ if (LastPrice <= Anchor - Threshold * Point) { Anchor = LastPrice; if (Ask > HighestSell) { Comment("Adding a Bombshell buy trade..."); OrderSend(Symbol(),OP_BUY,BombshellLots,Ask,Slippage,0,0,"RHc_Bombshell",0,0,Blue); Print ("Errors opening BUY order = ",GetLastError()); return(0); } } } } }