//+------------------------------------------------------------------+ //| 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); } //+------------------------------------------------------------------+