//+------------------------------------------------------------------+ //| TrueHedge.mq4 | //| by Hartono Setiono | //+------------------------------------------------------------------+ #property copyright "Copyright © 2007, Hartono Setiono" #property link "http://www.mitrakom.com" #include #include extern double LotSize=2; extern int Slippage=3; extern double StopLoss=0; extern double TakeProfit=100; extern int GMTShift=0; extern int OpenPosHandler=0; extern int MinInitialOrderProfit=500; /* OpenPosHandler: 0:never close till positif at the end of the day 1:check everytime for takeProfit Level 2:wait till next end of the day and close */ int ticket; int OpenBuyOrders = 0; int OpenSellOrders = 0; int LastMN=0; //Last Magic Number int TodayMN=0; //Today Magic Number; int maxloop=25; // maximum number of attempts to handle errors int MNFactor=100000; int MagicNumber=123; string EAName="TrueHedge 0.1"; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { switch (OpenPosHandler) { case 0: case 1: case 2: break; default:OpenPosHandler=0; } return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { TodayMN = MagicNumber*MNFactor+ (Year() % 100)*10000 + Month()*100 + Day(); if(DayOfWeek()==0 || DayOfWeek()==6) return(0); if(Hour()+GMTShift==23 && Minute()==00) { if (OpenPosHandler==0) HandleOpenPositions(3); if (OpenPosHandler==2) HandleOpenPositions(4); HandleOpenPositions(2); } LastMN=GetLastMN(); if(Hour()+GMTShift==0 && Minute()==0 && LastMN==0) { OpenOrder(OP_BUY,LotSize,Ask,Slippage,0,0,EAName,TodayMN,0,Blue); OpenOrder(OP_SELL,LotSize,Bid,Slippage,0,0,EAName,TodayMN,0,Red); LastMN=TodayMN; } if (OpenPosHandler==1) HandleOpenPositions(1); return(0); } //+------------------------------------------------------------------+ int HandleOpenPositions(int id) { int cnt, OrderMN; double lotsi; for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES); lotsi=OrderLots(); OrderMN=OrderMagicNumber(); if ( OrderSymbol() != Symbol()) continue; if ( OrderMN/MNFactor != MagicNumber) continue; if (id==1) if (OrderMN != LastMN) { if (MNProfit(OrderMN)>TakeProfit) { CloseLongs(OrderMN); CloseShorts(OrderMN); } } if (id==2) { if (OrderMN==LastMN) { if (OrderType() == OP_BUY && OrderProfit()>MinInitialOrderProfit) { OrderClose(OrderTicket(),lotsi,Bid,Slippage,Blue); CloseShorts(OrderMN, lotsi/2); } if (OrderType() == OP_SELL && OrderProfit()>MinInitialOrderProfit) { OrderClose(OrderTicket(),lotsi,Ask,Slippage,Red); CloseLongs(OrderMN, lotsi/2); } } } if (id==3) if (OrderMN != LastMN) { if (MNProfit(OrderMN)>TakeProfit) { CloseLongs(OrderMN); CloseShorts(OrderMN); } } if (id==4) if (OrderMN != LastMN) { CloseLongs(OrderMN); CloseShorts(OrderMN); } } return(0); } double MNProfit(int MagicNumber) { int cnt; double profit=0; for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES); if ( OrderSymbol() != Symbol()) continue; if ( OrderMagicNumber() != MagicNumber) continue; profit=profit+OrderProfit(); } return(profit); } double MNDirection(int MagicNumber) { int cnt; double lotsi=0; 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 ) lotsi=lotsi+OrderLots(); if ( OrderType()==OP_SELL ) lotsi=lotsi-OrderLots(); } return(lotsi); } int GetLastMN() { int cnt, OrderMN, LastMN=0; double lotsi; for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES); OrderMN=OrderMagicNumber(); if ( OrderSymbol() != Symbol()) continue; if (OrderMN/MNFactor != MagicNumber) continue; lotsi=MNDirection(OrderMN); if (lotsi==0) { LastMN=OrderMN; break;} } return(LastMN); } int OpenOrder(int pType,double pLots,double pLevel,int sp, int sl, int tp,string pComment,int pMagic,datetime pExpiration,color pColor) { int ticket=0; int err=0; int c = 0; int NumberOfTries = 10; switch (pType) { case OP_BUY: for(c = 0 ; c < NumberOfTries ; c++) { RefreshRates(); ticket=OrderSend(Symbol(),OP_BUY,pLots,Ask,sp,StopLong(Bid,sl),TakeLong(Bid,tp),pComment,pMagic,pExpiration,pColor); if (ticket > 0) break; err=GetLastError(); if(err==0) { break; } else { if(err==4 || err==137 ||err==146 || err==136) //Busy errors { Sleep(5000); continue; } else //normal error { Print("Error Code= ", err); break; } } } break; case OP_SELL: for(c = 0 ; c < NumberOfTries ; c++) { RefreshRates(); ticket=OrderSend(Symbol(),OP_SELL,pLots,Bid,sp,StopShort(Ask,sl),TakeShort(Ask,tp),pComment,pMagic,pExpiration,pColor); if (ticket > 0) break; err=GetLastError(); if(err==0) { break; } else { if(err==4 || err==137 ||err==146 || err==136) //Busy errors { Sleep(5000); continue; } else //normal error { Print("Error Code= ", err); break; } } } break; } return(ticket); } void CloseLongs(int MagicNumber, double clots=0) { int trade; double olots; for(trade=OrdersTotal()-1;trade>=0;trade--) { if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES)==false) continue; if(OrderSymbol()!=Symbol()||OrderMagicNumber()!=MagicNumber) continue; if(OrderType()!=OP_BUY) continue; olots=OrderLots(); if (clots==0) clots=olots; OrderClose(OrderTicket(),clots,Bid,Slippage,Blue); if(olots!=clots && StopLoss !=0) ModifyStopLoss(OrderTicket(),StopLong(Bid,StopLoss)); }//for } void CloseShorts(int MagicNumber, double clots=0) { int trade; double olots; for(trade=OrdersTotal()-1;trade>=0;trade--) { if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES)==false) continue; if(OrderSymbol()!=Symbol()||OrderMagicNumber()!=MagicNumber) continue; if(OrderType()!=OP_SELL) continue; olots=OrderLots(); if (clots==0) clots=olots; OrderClose(OrderTicket(),clots,Ask,Slippage,Red); if(olots!=clots && StopLoss !=0) ModifyStopLoss(OrderTicket(),StopShort(Ask,StopLoss)); }//for } double StopLong(double price,int stop) { if(stop==0) return(0); else return(price-(stop*Point)); } double StopShort(double price,int stop) { if(stop==0) return(0); else return(price+(stop*Point)); } double TakeLong(double price,int take) { if(take==0) return(0); else return(price+(take*Point)); } double TakeShort(double price,int take) { if(take==0) return(0); else return(price-(take*Point)); } int HandleTrailingStop(int type, int ticket, double open_price, double cur_sl, int TrailingStopType, int TrailingStop) { 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); } 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++; } } }