//+------------------------------------------------------------------+ //| OverHedgeV2.mq4 | //| Copyright © 2006, | //| | //| Written by MrPip (Robert Hill) for kmrunner | //| 3/7/06 Added check of direction for first trade Buy or Sell | //+------------------------------------------------------------------+ #property copyright "Copyright © 2005" #property link "http://www.strategtbuilderfx.com" #include extern bool Debug = false; extern string TradeLog = "TradeLog"; extern int MagicNumber = 11111; extern double Lots = 0.1; extern double HedgeBase = 2.0; extern int Slippage = 5; extern bool shutdownGrid = false; extern int TunnelWidth=20; extern double profitTarget = 100; // if > 0, will close out all positions once the pip target has been met extern int EMAShortPeriod=8; // original was 7, change based on new optimization Mar06 extern int EMALongPeriod=21; // original was 16, change based on new optimization Mar06 extern int PauseSeconds = 6; // Number of seconds to "sleep" before closing the next winning trade extern int MillisPerSec = 1000; // DO NOT CHANGE - Standard multiplier to convert seconds to milliseconds double TunnelSize; string setup; double startBuyRate, startSellRate; int currentOpen; int NumBuyTrades, NumSellTrades; // Number of buy and sell trades in this symbol bool myWantLongs; double lotMM; double Profit; bool OK2Buy,OK2Sell, FirstDirSell; //+------------------------------------------------------------------+ //| CheckDirection | //| Check direction for trade | //| return 1 for up, -1 for down, 0 for flat | //+------------------------------------------------------------------+ int CheckDirection() { double SlowEMA, FastEMA; double Dif; FastEMA = iMA(NULL,0,EMAShortPeriod,0,MODE_EMA,PRICE_CLOSE,1); SlowEMA = iMA(NULL,0,EMALongPeriod,0,MODE_EMA,PRICE_CLOSE,1); Dif = FastEMA-SlowEMA; if(Dif > 0 ) return(1); if(Dif < 0 ) return(-1); return(0); } //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- setup = StringConcatenate( "OverHedgeV2-", Symbol(),"-",MagicNumber ); int err, handle; string filename=Symbol()+ TradeLog + ".txt"; //---- if (Debug) { GlobalVariableSet("MyHandle",0); if (!GlobalVariableCheck("MyHandle")) { err = GetLastError(); Print("Error creating Global Variable MyHandle: (" + err + ") " + ErrorDescription(err)); return(0); } handle = FileOpen(filename,FILE_CSV|FILE_WRITE,"\t"); GlobalVariableSet("MyHandle",handle); } return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { int handle; if (Debug) { if (GlobalVariableCheck("MyHandle")) { handle = GlobalVariableGet("MyHandle"); FileFlush(handle); FileClose(handle); GlobalVariableDel("MyHandle"); } } return(0); } //+------------------------------------------------------------------+ //| Write - writes string to debug file | //+------------------------------------------------------------------+ int Write(string str) { int handle; if (GlobalVariableCheck("MyHandle")) { handle = GlobalVariableGet("MyHandle"); FileWrite(handle,str + " Time " + TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS)); } } //+------------------------------------------------------------------+ //| Close Open Positions | //| Close all open positions | //+------------------------------------------------------------------+ void CloseOpenPositions() { int cnt, err; // First close losing trades for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS,MODE_TRADES); // if ( OrderSelect (cnt, SELECT_BY_POS) == false ) // { // err = GetLastError(); // if (Debug) Write("OrderSelect failed error : (" + err + ") " + ErrorDescription(err)); // continue; // } if ( OrderSymbol() != Symbol()) continue; if ( OrderMagicNumber() != MagicNumber) continue; if(OrderType() == OP_BUY && OrderProfit() < 0) { if (OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Violet)) { if (Debug) Write("Buy Order closed for " + Symbol() + " at " + Bid + "."); } else { err=GetLastError(); Print("Error closing order : (", err , ") " + ErrorDescription(err)); if (Debug) { Write("Error closing order : (" + err + ") " + ErrorDescription(err)); } } } if(OrderType() == OP_SELL && OrderProfit() < 0) { if (OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Violet)) { if (Debug) Write("Sell Order closed for " + Symbol() + " at " + Ask + "."); } else { err=GetLastError(); Print("Error closing order : (", err , ") " + ErrorDescription(err)); if (Debug) { Write("Error closing order : (" + err + ") " + ErrorDescription(err)); } } } } // Then close winning trades for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS,MODE_TRADES); // if ( OrderSelect (cnt, SELECT_BY_POS) == false ) // { // err = GetLastError(); // if (Debug) Write("OrderSelect failed error : (" + err + ") " + ErrorDescription(err)); // continue; // } if ( OrderSymbol() != Symbol()) continue; if ( OrderMagicNumber() != MagicNumber) continue; if(OrderType() == OP_BUY && OrderProfit() > 0) { Sleep(PauseSeconds*MillisPerSec); if (OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Gold)) { if (Debug) Write("Buy Order closed for " + Symbol() + " at " + Bid + "."); } else { err=GetLastError(); Print("Error closing order : (", err , ") " + ErrorDescription(err)); if (Debug) { Write("Error closing order : (" + err + ") " + ErrorDescription(err)); } } } if(OrderType() == OP_SELL && OrderProfit() > 0) { Sleep(PauseSeconds*MillisPerSec); if (OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Gold)) { if (Debug) Write("Sell Order closed for " + Symbol() + " at " + Ask + "."); } else { err=GetLastError(); Print(" Error closing order : (", err , ") " + ErrorDescription(err)); if (Debug) { Write(" Error closing order : (" + err + ") " + ErrorDescription(err)); } } } } } //+------------------------------------------------------------------------+ //| counts the number of open positions | //| type BUY returns number of long positions | //| type SELL returns number of short positions | //| type BOTH returns number of long and short positions | //+------------------------------------------------------------------------+ int CheckOpenPositions(string type) { int cnt, NumPositions; int NumBuyTrades, NumSellTrades; // Number of buy and sell trades in this symbol NumBuyTrades = 0; NumSellTrades = 0; for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES); // if ( OrderSelect (cnt, SELECT_BY_POS) == false ) continue; if ( OrderSymbol() != Symbol()) continue; if ( OrderMagicNumber() != MagicNumber) continue; if(OrderType() == OP_BUY ) { NumBuyTrades++; } else if(OrderType() == OP_SELL) { NumSellTrades++; } } NumPositions = NumBuyTrades + NumSellTrades; if (type == "BUY") return (NumBuyTrades); if (type == "SELL") return (NumSellTrades); return (NumPositions); } //+------------------------------------------------------------------+ //| GetProfit | //| Return Open Profit from all open positions | //+------------------------------------------------------------------+ double GetProfit( ) { int i; double openProfit = 0; openProfit = 0; for(i=OrdersTotal()-1;i>=0;i--) { OrderSelect(i, SELECT_BY_POS ); if ( OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber ) { openProfit = openProfit + MathRound(OrderProfit()/MarketInfo(Symbol(),MODE_TICKVALUE)*10); } } return (openProfit); } //+------------------------------------------------------------------+ //| OpenBuyOrder | //+------------------------------------------------------------------+ void OpenBuyOrder(double lotM, string SetupStr) { int err; int ticket; ticket = OrderSend(Symbol(),OP_BUY,lotM,Ask,Slippage,0,0,SetupStr,MagicNumber,0,Blue); if (Debug) { Write ("OpenBuy " + Symbol() + " for " + DoubleToStr(Ask,4)); } if(ticket<=0) { err = GetLastError(); Print("Error opening BUY order [" + SetupStr + "]: (" + err + ") " + ErrorDescription(err)); if (Debug) Write("Error opening BUY order [" + SetupStr + "]: (" + err + ") " + ErrorDescription(err)); } } //+------------------------------------------------------------------+ //| OpenSellOrder | //+------------------------------------------------------------------+ void OpenSellOrder(double lotM, string SetupStr) { int err; int ticket; ticket = OrderSend(Symbol(),OP_SELL,lotM,Bid,Slippage,0,0,SetupStr,MagicNumber,0,Red); if(Debug) { Write ("OpenSell " + Symbol() + " for " + DoubleToStr(Bid,4)); } if(ticket<=0) { err = GetLastError(); Print("Error opening Sell order [" + SetupStr + "]: (" + err + ") " + ErrorDescription(err)); if (Debug) Write("Error opening Sell order [" + SetupStr + "]: (" + err + ") " + ErrorDescription(err)); } } //+-------------------------------------------+ //| DoTrades module cut from start | //| No real changes | //+-------------------------------------------+ void DoTrades(string OrdText, string SetupStr,double lotM) { if(OrdText == "BUY") { OpenBuyOrder(lotM,SetupStr); } else if(OrdText == "SELL") { OpenSellOrder(lotM,SetupStr); } } //+------------------------------------------------------------------+ //| Check Profit | //| Output comment showing progit, longs, shorts, etc | //| If profit target is reached close all open positions | //+------------------------------------------------------------------+ void CheckProfit() { double Profit; int openLongs,openShorts; Profit = GetProfit(); if ( Profit >= profitTarget ) { if (Debug) Write("Closing positions due to profit target"); CloseOpenPositions(); } // else // { // openLongs = CheckOpenPositions("BUY"); // openShorts = CheckOpenPositions("SELL"); // Comment(" Server time is ",TimeToStr(CurTime()), // "\n", // "\n"," Open p&l = ",Profit, // "\n"," Long = ",openLongs, // "\n"," Short = ",openShorts, // "\n", // "\n"," Balance = ",AccountBalance(), // "\n"," Equity = ",AccountEquity(), // "\n"," Margin = ",AccountMargin(), // "\n"," Free mrg = ",AccountFreeMargin()); // } } //+------------------------------------------------------------------+ //| script program start function | //+------------------------------------------------------------------+ int start() { //---- //---- test if we want to shutdown if (shutdownGrid ) // close all orders. then exit.. there is nothing more to do { CloseOpenPositions(); return(0); } TunnelSize = ((2*(Ask-Bid)/Point)+TunnelWidth); // Check for new trade cycle // First check if profit target is reached // If yes then there will be no open positions // So a new trade cycle will begin CheckProfit(); currentOpen = CheckOpenPositions("BOTH"); if (currentOpen == 0) { // Start trades based on confirmation direction, was daily if (CheckDirection() == 0) return(0); if (CheckDirection() == 1) { OK2Buy = true; OK2Sell = false; FirstDirSell = false; } if (CheckDirection() == -1) { OK2Buy = false; OK2Sell = true; FirstDirSell = true; } if (OK2Buy) { startBuyRate = Bid ; if (Debug) Write("Start Buys : " + startBuyRate); startSellRate = Bid - TunnelSize*Point; if (Debug) Write("Start Sells : " + startSellRate); } if (OK2Sell) { startSellRate = Bid ; if (Debug) Write("Start Sells : " + startSellRate); startBuyRate = Bid + TunnelSize*Point; if (Debug) Write("Start Buys : " + startBuyRate); } } else { OK2Buy = true; OK2Sell = true; } // Determine how many lots for next trade based on current number of open positions lotMM = Lots * MathPow(HedgeBase,currentOpen); if (lotMM == 0) return (0); // Determine if next trade should be long or short based on current number of open positions myWantLongs = true; if (MathMod(currentOpen,2) > 0.1) myWantLongs = false; if (FirstDirSell) myWantLongs = !myWantLongs; // added to match starting trade direction if (myWantLongs) { // if (Debug) Write ("Looking for Longs at " + startBuyRate + " with Lots = " + lotMM); if (Ask >=startBuyRate ) { // if (Debug) Write ("Long at : " + Ask + " with start buy rate at " + startBuyRate); DoTrades("BUY",setup,lotMM); } } else { // if (Debug) Write ("Looking for Shorts at " + startSellRate + " with Lots = " + lotMM); if (Ask <= startSellRate) { // if (Debug) Write ("Short at : " + Bid + " with start sell rate at " + startSellRate); DoTrades("SELL",setup,lotMM); } } return(0); }