//+------------------------------------------------------------------+ //| MultiHedgeEA.mq4 | //| Copyright © 2006, ForexForums.org| //+------------------------------------------------------------------+ //v1.1 solve Closing Problem: bodshyipmonitor. #property copyright "Copyright © 2006, ForexForums.org" #property link "http://www.forexforums.org/" #include <stdlib.mqh> //---- input parameters extern string eaname = "MH-V1.3"; // Expert Name and first part of comment line extern int Magic = 6464; // Magic Number ( 0 - for All positions) extern bool Autotrade = true; // Set to false to prevent an entry after an exit extern string Symbol1 = "USDCHF"; extern bool Symbol1isLong = false; // Set to true to put long orders on the second pair extern double Ratio1 = 1; extern string Symbol2 = "USDJPY"; extern bool Symbol2isLong = false; // Set to true to put long orders on the second pair extern double Ratio2 = 1; extern string Symbol3 = "EURUSD"; extern bool Symbol3isLong = false; // Set to true to put long orders on the second pair extern double Ratio3 = 1; extern string Symbol4 = "GBPUSD"; extern bool Symbol4isLong = false; // Set to true to put long orders on the second pair extern double Ratio4 = 1; extern double Slippage = 3; extern string Lotsizes = "Set Ratio to 1 to use equal"; extern double Lots = 1; // Lots for first pair if MM is turned off extern bool UseAutoRatio = true; extern double SMA_Value_for_Range = 200; extern string Data = " Input Data "; extern bool StopManageAcc = false; // Stop of Manage Account switch(Close All Trades) extern double MaxLoss = 0; // Maximum total loss in pips or USD // extern string Data2 = "Correlation Settings"; // extern bool UseCorrelation = true; // Set to true if you want to use correlation as an entry signal extern int cPeriod = 20; // If the correlation is used to check before put new Orders // extern double MinCorrelation = 0.8; // extern double MaxCorrelation = 1.0; extern string Data4 = "SWAP Settings"; extern bool UseSwap = true; // Select true if you want to use swap on profit calculation extern string Data5 = "Money Management"; bool AccountIsMicro = false; // Set true if you use a micro account extern double ProfitTarget = 50; // Profit target in pips or U bool UsePips = false; extern bool MoneyManagement = true; extern double Risk = 20; // Risk extern bool AutoProfit = true; // When the price of Bolliner pair passes the Upper Bollinger close all trades extern double AutoProfitRatio = 1; extern bool EmailReport = false; string comment = ""; string eBody = ""; string eSubject = ""; string TradeSymbol =""; int totalPips=0; double totalProfits=0; double BandsLower = 0; double BandsUpper = 0; bool CloseSignal=false; bool signal1=true; bool signal2=true; double valueswap = 0; double Correlation; double Bands; double OrderLots1,OrderLots2,OrderLots3,OrderLots4; double AccountSize; double Total_Lots; int ticket1=0 ,ticket2=0 ,Symbol1SP ,Symbol2SP ,Order1=0 ,Order2=0 ,Order3=0 ,Order4=0 ,c1=0 ,c2=0 ,Symbol1OP ,Symbol2OP ,Symbol3OP ,Symbol4OP ,Symbol1Mode ,Symbol2Mode ,Symbol3Mode ,Symbol4Mode ,numords=0 ; string USD = "USD"; // Added so that PipCost could handle InterbankFx Mini accounts //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- if(Symbol1isLong){ Symbol1OP=OP_BUY; Symbol1Mode=MODE_ASK; } else { Symbol1OP=OP_SELL; Symbol1Mode=MODE_BID; } if(Symbol2isLong){ Symbol2OP=OP_BUY; Symbol2Mode=MODE_ASK; } else { Symbol2OP=OP_SELL; Symbol2Mode=MODE_BID; } if(Symbol3isLong){ Symbol3OP=OP_BUY; Symbol3Mode=MODE_ASK; } else { Symbol3OP=OP_SELL; Symbol3Mode=MODE_BID; } if(Symbol4isLong){ Symbol4OP=OP_BUY; Symbol4Mode=MODE_ASK; } else { Symbol4OP=OP_SELL; Symbol4Mode=MODE_BID; } if (StringLen(Symbol())== 7 ) { Symbol1 = Symbol1 + "m"; Symbol2 = Symbol2 + "m"; Symbol3 = Symbol3 + "m"; Symbol4 = Symbol4 + "m"; USD = USD + "m"; } if (MarketInfo(Symbol(),MODE_LOTSTEP) == 0.01) { AccountIsMicro = true; } else { AccountIsMicro = false; } //CloseSignal=false; //---- return(0); } // ---- Scan Open Trades int ScanOpenTrades() { Order1=0;Order2=0;Order3=0;Order4=0; int total = OrdersTotal(); int numords = 0; for(int cnt=0; cnt<=total-1; cnt++) { OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES); if(Magic > 0) if(OrderMagicNumber() == Magic) numords++; { if(OrderType()==OP_SELL && OrderMagicNumber() == Magic && OrderSymbol()==Symbol1)Order1 += 1; if(OrderType()==OP_SELL && OrderMagicNumber() == Magic && OrderSymbol()==Symbol2)Order2 += 1; if(OrderType()==OP_SELL && OrderMagicNumber() == Magic && OrderSymbol()==Symbol3)Order3 += 1; if(OrderType()==OP_SELL && OrderMagicNumber() == Magic && OrderSymbol()==Symbol4)Order4 += 1; if(OrderType()==OP_BUY && OrderMagicNumber() == Magic && OrderSymbol()==Symbol1)Order1 += 1; if(OrderType()==OP_BUY && OrderMagicNumber() == Magic && OrderSymbol()==Symbol2)Order2 += 1; if(OrderType()==OP_BUY && OrderMagicNumber() == Magic && OrderSymbol()==Symbol3)Order3 += 1; if(OrderType()==OP_BUY && OrderMagicNumber() == Magic && OrderSymbol()==Symbol4)Order4 += 1; } } return(numords); } //+--------- --------- --------- --------- --------- --------- ----+ //+ Calculate cost in USD of 1pip of given symbol //+--------- --------- --------- --------- --------- --------- ----+ double PipCost (string TradeSymbol) { double Base, Cost; string TS_13, TS_46, TS_4L; TS_13 = StringSubstr (TradeSymbol, 0, 3); TS_46 = StringSubstr (TradeSymbol, 3, 3); TS_4L = StringSubstr (TradeSymbol, 3, StringLen(TradeSymbol)-3); Base = MarketInfo (TradeSymbol, MODE_LOTSIZE) * MarketInfo (TradeSymbol, MODE_POINT); if ( TS_46 == "USD" ) Cost = Base; else if ( TS_13 == "USD" ) Cost = Base / MarketInfo (TradeSymbol, MODE_BID); else if ( PairExists ("USD"+TS_4L) ) Cost = Base / MarketInfo ("USD"+TS_4L, MODE_BID); else Cost = Base * MarketInfo (TS_46+"USD" , MODE_BID); return(Cost) ; } //+--------- --------- --------- --------- --------- --------- ----+ //+ Returns true if given symbol exists //+--------- --------- --------- --------- --------- --------- ----+ bool PairExists (string TradeSymbol) { return ( MarketInfo (TradeSymbol, MODE_LOTSIZE) > 0 ); } // Generate Comment on OrderSend string GenerateComment(string eaname, int Magic) { return (StringConcatenate(eaname, "-", Magic)); } // Closing of Open Orders void OpenOrdClose() { int total=OrdersTotal(); for (int cnt=0;cnt<total;cnt++) { OrderSelect(cnt, SELECT_BY_POS); int mode=OrderType(); bool res = false; bool condition = false; if ( Magic>0 && OrderMagicNumber()==Magic ) condition = true; else if ( Magic==0 ) condition = true; if (condition && ( mode==OP_BUY || mode==OP_SELL )) { if (EmailReport) SendMail(eSubject,eBody); // - BUY Orders if(mode==OP_BUY) { res = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3,Yellow); if( !res ) { Print(" BUY: OrderClose failed with error #",GetLastError()); Print(" Ticket=",OrderTicket()); Sleep(3000); } break; } else // - SELL Orders if( mode == OP_SELL) { res = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),3,White); if( !res ) { Print(" SELL: OrderClose failed with error #",GetLastError()); Print(" Ticket=",OrderTicket()); Sleep(3000); } break; } } } } void TotalProfit() { int total=OrdersTotal(); totalPips = 0; totalProfits = 0; for (int cnt=0;cnt<total;cnt++) { OrderSelect(cnt, SELECT_BY_POS); int mode=OrderType(); bool condition = false; if ( Magic>0 && OrderMagicNumber()==Magic ) condition = true; else if ( Magic==0 ) condition = true; if (condition) { switch (mode) { case OP_BUY: totalPips += MathRound((MarketInfo(OrderSymbol(),MODE_BID)-OrderOpenPrice())/MarketInfo(OrderSymbol(),MODE_POINT)); totalProfits += OrderProfit(); break; case OP_SELL: totalPips += MathRound((OrderOpenPrice()-MarketInfo(OrderSymbol(),MODE_ASK))/MarketInfo(OrderSymbol(),MODE_POINT)); totalProfits += OrderProfit(); break; } } } } void SwapProfit() { int total=OrdersTotal(); valueswap = 0; for (int cnt=0;cnt<total;cnt++) { OrderSelect(cnt, SELECT_BY_POS); int mode=OrderType(); bool condition = false; if ( Magic>0 && OrderMagicNumber()==Magic ) condition = true; else if ( Magic==0 ) condition = true; if (condition) { if (UsePips){ valueswap = valueswap + OrderSwap()/PipCost(OrderSymbol()); } else { valueswap = valueswap + OrderSwap(); } } } } void ChartComment() { string sComment = ""; string sp = "****************************\n"; string NL = "\n"; sComment = sp; sComment = sComment + "Open Positions = " + ScanOpenTrades() + NL; // sComment = sComment + "Current Ratio = " + DoubleToStr(Ratio,2) + NL; //Add in by bodshyipmonitor@forex-tsd to show the lots. Will only show when there are no trades open. :) if (OrdersTotal()<1){ sComment = sComment + "Total Lots : = " + Total_Lots + NL; sComment = sComment + Symbol1+ " Lots : = " + DoubleToStr(OrderLots1,AccountSize) + NL; sComment = sComment + Symbol2+ " Lots : = " + DoubleToStr(OrderLots2,AccountSize) + NL; sComment = sComment + Symbol3+ " Lots : = " + DoubleToStr(OrderLots3,AccountSize) + NL; sComment = sComment + Symbol4+ " Lots : = " + DoubleToStr(OrderLots4,AccountSize) + NL; sComment = sComment + NL; } if (UsePips) { sComment = sComment + "Current Profit(Pip)= " + totalPips + NL; } else { sComment = sComment + "Current Profit(USD) = " + DoubleToStr(totalProfits,2) + NL + NL; } sComment = NL + sComment + "Profit Target (USD) = " + DoubleToStr(ProfitTarget,0) + NL; if(UseSwap){ if (UsePips) { sComment = sComment + "SWAP Value (Pip) = " + DoubleToStr(valueswap,2) + NL; } else { sComment = sComment + "SWAP Value (USD) = " + DoubleToStr(valueswap,2) + NL; } } if (UsePips) { sComment = NL + sComment + "Net Value (Pip) = " + DoubleToStr(totalPips+valueswap,2) + NL; } else { sComment = NL + sComment + "Net Value (USD) = " + DoubleToStr(totalProfits+valueswap,2) + NL; } sComment = sComment + NL + sp; eSubject = "MultiHedge Profit:" + DoubleToStr(totalProfits+valueswap,2); eBody = "MultiHedgeEA Report" + NL + sComment; Comment(sComment); } double CorrelationIND(string Symbol1,string Symbol2,int CorrelationShift=0){ double Correlation[],DiffBuffer1[],DiffBuffer2[],PowDiff1[],PowDiff2[]; ArrayResize(Correlation,cPeriod*2);ArrayResize(DiffBuffer1,cPeriod*2); ArrayResize(DiffBuffer2,cPeriod*2);ArrayResize(PowDiff1,cPeriod*2);ArrayResize(PowDiff2,cPeriod*2); for( int shift=cPeriod+1; shift>=0; shift--){ DiffBuffer1[shift]=iClose(Symbol1,0,shift)-iMA(Symbol1,0,cPeriod,0,MODE_SMA,PRICE_CLOSE,shift); DiffBuffer2[shift]=iClose(Symbol2,0,shift)-iMA(Symbol2,0,cPeriod,0,MODE_SMA,PRICE_CLOSE,shift); PowDiff1[shift]=MathPow(DiffBuffer1[shift],2); PowDiff2[shift]=MathPow(DiffBuffer2[shift],2); double u=0,l=0,s=0; for( int i = cPeriod-1 ;i >= 0 ;i--){ u += DiffBuffer1[shift+i]*DiffBuffer2[shift+i]; l += PowDiff1[shift+i]; s += PowDiff2[shift+i]; } if(l*s >0)Correlation[shift]=u/MathSqrt(l*s); } return(Correlation[CorrelationShift]); return(-1); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { // while(true){ // Sleep(100); // RefreshRates(); Correlation= CorrelationIND(Symbol1,Symbol2,0); //added Bollinger Filter // Bands=iCustom(Bollinger_Symbol,Bollinger_Period,"Bands",20,0,2,0,0,0); // Old Bollinger // BandsLower = iBands(Bollinger_Symbol,Bollinger_TF,Bollinger_Period,Bollinger_Dev,0,0,2,0); // Lower Bollinger // BandsUpper = iBands(Bollinger_Symbol,Bollinger_TF,Bollinger_Period,Bollinger_Dev,0,0,1,0); // Upper Bollinger // Bands = (BandsLower + BandsUpper) / 2; // Middle Bollinger // if(ScanOpenTrades()==0) CloseSignal=false; Order1=0; Order2=0; // if(ScanOpenTrades()==2) Order1=1; Order2=1; TotalProfit(); SwapProfit(); if (UseAutoRatio) { double Symbol1_Range= (iMA(Symbol1,0,SMA_Value_for_Range,0,MODE_SMA,PRICE_HIGH,0)-iMA(Symbol1,0,SMA_Value_for_Range,0,MODE_SMA,PRICE_LOW,0))/MarketInfo(Symbol1,MODE_POINT); double Symbol2_Range= (iMA(Symbol2,0,SMA_Value_for_Range,0,MODE_SMA,PRICE_HIGH,0)-iMA(Symbol2,0,SMA_Value_for_Range,0,MODE_SMA,PRICE_LOW,0))/MarketInfo(Symbol2,MODE_POINT); double Symbol3_Range= (iMA(Symbol3,0,SMA_Value_for_Range,0,MODE_SMA,PRICE_HIGH,0)-iMA(Symbol3,0,SMA_Value_for_Range,0,MODE_SMA,PRICE_LOW,0))/MarketInfo(Symbol3,MODE_POINT); double Symbol4_Range= (iMA(Symbol4,0,SMA_Value_for_Range,0,MODE_SMA,PRICE_HIGH,0)-iMA(Symbol4,0,SMA_Value_for_Range,0,MODE_SMA,PRICE_LOW,0))/MarketInfo(Symbol4,MODE_POINT); double TotalRange = Symbol1_Range + Symbol2_Range + Symbol3_Range + Symbol4_Range; Ratio1 = (1 / PipCost(Symbol1))* (Symbol1_Range / TotalRange) / MarketInfo(Symbol1,MODE_LOTSIZE); Ratio2 = (1 / PipCost(Symbol2))* (Symbol2_Range / TotalRange) / MarketInfo(Symbol2,MODE_LOTSIZE); Ratio3 = (1 / PipCost(Symbol3))* (Symbol3_Range / TotalRange) / MarketInfo(Symbol3,MODE_LOTSIZE); Ratio4 = (1 / PipCost(Symbol4))* (Symbol4_Range / TotalRange) / MarketInfo(Symbol4,MODE_LOTSIZE); } if (UseSwap) { if (UsePips) { totalProfits = totalPips + valueswap; } else { totalProfits = totalProfits + valueswap; } } if (AutoProfit) ProfitTarget = NormalizeDouble(((OrderLots1 * PipCost(Symbol1) + OrderLots2 * PipCost(Symbol2) +OrderLots3*PipCost(Symbol3) + OrderLots4*PipCost(Symbol4) )/4) * Risk / AutoProfitRatio,0); if (!StopManageAcc){ if(ScanOpenTrades() > 0 && !CloseSignal && (ProfitTarget>0 || MaxLoss>0)) { if(ProfitTarget > 0 && totalProfits>=ProfitTarget) CloseSignal=true; if(MaxLoss > 0 && totalProfits <= -MaxLoss) CloseSignal=true; } }else{ if (ScanOpenTrades() > 0) CloseSignal=true;} if( CloseSignal ) OpenOrdClose(); if (Order1==0 && Order2==0 && Order3==0 && Order4==0) CloseSignal=false; comment = GenerateComment(eaname, Magic); if(AccountIsMicro) {AccountSize=2;} else {AccountSize=1;} if(MoneyManagement) { Total_Lots = AccountFreeMargin()*Risk*0.01 *AccountLeverage(); // Print(Total_Lots); OrderLots1 = NormalizeDouble(Total_Lots * Ratio1,AccountSize); OrderLots2 = NormalizeDouble(Total_Lots * Ratio2,AccountSize); OrderLots3 = NormalizeDouble(Total_Lots * Ratio3,AccountSize); OrderLots4 = NormalizeDouble(Total_Lots * Ratio4,AccountSize); } else { OrderLots1 = NormalizeDouble(Lots * Ratio1,AccountSize); OrderLots2 = NormalizeDouble(Lots * Ratio2,AccountSize); OrderLots3 = NormalizeDouble(Lots * Ratio3,AccountSize); OrderLots4 = NormalizeDouble(Lots * Ratio4,AccountSize); } //Print(OrderLots1," ",OrderLots2," ",OrderLots3," ",OrderLots4); ChartComment(); signal1 = true; signal2 = true; // * * * * * * * * * * Placing Orders * * * * * * * * * * if(!StopManageAcc && signal1 && signal2 && Autotrade && !CloseSignal){ CloseSignal=false; // Order1 if (Order1==0) { OrderSend(Symbol1,Symbol1OP,OrderLots1,MarketInfo(Symbol1,Symbol1Mode),Slippage,0,0,comment,Magic,0,Blue); if (GetLastError()==0) {Order1=1;} } // Order2 if (Order2==0) { OrderSend(Symbol2,Symbol2OP,OrderLots2,MarketInfo(Symbol2,Symbol2Mode),Slippage,0,0,comment,Magic,0,Blue); if (GetLastError()==0) {Order2=1;} } // Order3 if (Order3==0) { OrderSend(Symbol3,Symbol3OP,OrderLots3,MarketInfo(Symbol3,Symbol3Mode),Slippage,0,0,comment,Magic,0,Blue); if (GetLastError()==0) {Order3=1;} } // Order4 if (Order4==0) { OrderSend(Symbol4,Symbol4OP,OrderLots4,MarketInfo(Symbol4,Symbol4Mode),Slippage,0,0,comment,Magic,0,Blue); if (GetLastError()==0) {Order4=1;} } } // } //Final Cycle } // EA Close
Sample
Analysis
Market Information Used:
Series array that contains close prices for each bar
Indicator Curves created:
Indicators Used:
Moving average indicator
Custom Indicators Used:
Order Management characteristics:
Checks for the total of open orders
It Closes Orders by itself
It automatically opens orders when conditions are reached
Other Features:
It sends emails