//+------------------------------------------------------------------+ //| OrdersEA.mq5 | //| Garfield Heron | //| https://fetcherpay.com| //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Garfield Heron" #property link "http://www.fetcherpay.com" #define VERSION "Version 1.1 gh" // WinAPI include removed - using native MT5 functions // web.mq5 include removed - license check disabled #define MAX_TRADES 600 #define MAX_LOG_TRADES 1200 //---- input parameters extern string Email= "garfield@fetcherpay.com"; extern int MagicNum= 333; extern double HIGH= 0; extern double LOW= 0; extern double Lots=0.1; extern double Entry= 1; extern double TP= 0.5; extern int StopLoss=0; extern int TRADE_RANGE= 50; extern double LongLimit= 0; extern double ShortLimit= 0; extern string GetOut= "N"; extern string OpenNewTrades="Y"; extern bool Opposite= false; extern int TakeProfitLevelPercent= 50; extern int TakeProfitLevelDollarAmount= 2000; extern bool Restart= true; extern int EquityFactorPercent= 0; extern int LotsFactorPercent= 0; //extern string VACCodeT= ""; //extern string VACCodeH= ""; extern string HoldingAccount= ""; extern int BaseEquity= 10000; extern bool Master= false; extern string Version_4.1.1.beta=""; extern bool DiagnosticModeOn= false; extern double moveRangeTrigger = 0.0; int initialCycleEquity= 0; int longs, shorts; int longsTicket[MAX_TRADES]; int shortsTicket[MAX_TRADES]; int logTickets[MAX_LOG_TRADES]; int logTicketsTime[MAX_LOG_TRADES]; int logTicketsCounter; int Levels; double price[MAX_TRADES]; //The bid price of every order int stoplevel; bool bFirstTick= false; int logId; bool bEnableLongs; bool bEnableShorts; double tickValue; int MaximalLoss; int lastTicketSentOpen= 0, lastTicketSentClose= 0; double longAvgPrice= 0, longAvgLots= 0; double shortAvgPrice= 0, shortAvgLots= 0; double longProfit= 0; double shortProfit= 0; bool bOpposite; bool bInit= false; int TakeProfit=0; bool AboveHigh; bool BelowLow; int tradeLogId; double closeOnProfit; bool bGetOutOK, bOpenNewTradesOK; int initEquity; int lotDigits; bool bWithdrawMailSent= false; bool bGetOutHandled; // handles the first GetOut in the start and not in the init due to time limitations int PingTimeMinutes= 240; bool bValidSettings; string errMsg; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CalcLots() { double tmp= (AccountEquity()-initEquity); double a= EquityFactorPercent; double b= LotsFactorPercent; double lots; if(0==EquityFactorPercent || 0==LotsFactorPercent) lots= Lots; else { a=initEquity*a/100; b=b/100; if(tmp>0) tmp= MathPow(1+b,(tmp/a)); else if(tmp<0) tmp= MathPow(1-b,MathAbs(tmp/a)); else tmp= 1; Log("DBG tmp="+tmp+",a="+a+",b="+b+",AccountEquity()="+AccountEquity()); //double lots= NormalizeDouble(Lots*AccountEquity()/initEquity,1); lots= NormalizeDouble(Lots*tmp,lotDigits); if(lots=0) { FileWrite(logId, TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS) + ": " + st); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CancelPendings(int op_type) { for(int cnt=OrdersTotal()-1; cnt>=0; cnt--) { OrderSelect(cnt, SELECT_BY_POS); if(OrderMagicNumber()==MagicNum && OrderSymbol()==Symbol()) { if((op_type==OP_BUY) && ((OrderType()==OP_BUYLIMIT)||(OrderType()==OP_BUYSTOP))) { OrderDelete(OrderTicket()); } if((op_type==OP_SELL) && ((OrderType()==OP_SELLLIMIT)||(OrderType()==OP_SELLSTOP))) { OrderDelete(OrderTicket()); } } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseAllTrades(int cmd) { for(int cnt=OrdersTotal()-1; cnt>=0; cnt--) { OrderSelect(cnt, SELECT_BY_POS); if(OrderMagicNumber()==MagicNum && OrderType()==cmd) // OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), slippage(), White); MqlTradeResult result= {}; MqlTradeRequest request= {}; request.order=OrderTicket(); request.price=OrderClosePrice(); request.volume=OrderLots(); request.action=TRADE_ACTION_CLOSE_BY; OrderSend(request,result); //--- write the server reply to log Print("Close result: ") ; } CancelPendings(cmd); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CalcSpread() { //--- obtain spread from the symbol properties bool spreadfloat=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD_FLOAT); string comm=StringFormat("Spread %s = %I64d points\r\n", spreadfloat?"floating":"fixed", SymbolInfoInteger(Symbol(),SYMBOL_SPREAD)); //--- now let's calculate the spread by ourselves double ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK); double bid=SymbolInfoDouble(Symbol(),SYMBOL_BID); double spread=ask-bid; int spread_points=(int)MathRound(spread/SymbolInfoDouble(Symbol(),SYMBOL_POINT)); comm=comm+"Calculated spread = "+(string)spread_points+" points"; Comment(comm); return spread_points; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int slippage() { return CalcSpread(); //return(MarketInfo(Symbol(), MODE_SPREAD)); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int init() { double levels; int cnt; AboveHigh= false; BelowLow= false; bFirstTick= false; bInit= false; //int rc= IDYES; double tmp; int MaxProfit= 0; // bConfirmed removed - always confirmed int MargReq; bValidSettings= false; if(Lots0) { errMsg= "Illegal Entry!"; //Alert(errMsg); return(0); } if(TP0) { errMsg= "Illegal TakeProfitShort!"; //Alert(errMsg); return(0); } if(StopLoss0) { errMsg= "Illegal StopLoss!"; //Alert(errMsg); return(0); } bValidSettings= true; // License check removed - web.mq5 no longer used bool bAccess = true; // Always allow access bGetOutHandled= false; if(DiagnosticModeOn) logId= FileOpen(WindowExpertName()+MagicNum+"_"+TimeCurrent()+".log",FILE_WRITE); Log("Version="+VERSION); initialCycleEquity= BaseEquity; tickValue= MarketInfo(Symbol(), MODE_TICKVALUE); Log("Master="+Master+",Restart="+Restart); if(TP==0) TakeProfit= MathPow(10, Digits)*(Entry+Point/2); else TakeProfit= MathPow(10, Digits)*(TP+Point/2); Print("TakeProfit="+TakeProfit); levels= (HIGH-LOW)/Entry; MaxProfit= TakeProfit*tickValue*Lots*levels; Log("Digits="+Digits+",Bid="+Bid+",MODE_MARGINREQUIRED="+MarketInfo(Symbol(), MODE_MARGINREQUIRED)+",MODE_MARGINCALCMODE="+MarketInfo(Symbol(), MODE_MARGINCALCMODE)); Print("MODE_TICKVALUE="+MarketInfo(Symbol(),MODE_TICKVALUE)); if(MarketInfo(Symbol(), MODE_MARGINCALCMODE)==0) { MargReq= Lots*MarketInfo(Symbol(), MODE_MARGINREQUIRED); } else MargReq= Lots*(levels+1)*(((HIGH-LOW)/2)+LOW)*MarketInfo(Symbol(), MODE_MARGINREQUIRED)/Bid; Print("MargReq="+MargReq); Log("levels="+levels+",Entry="+Entry); levels= levels*Entry*(levels+1); //The maximal loss in points sum=n*(a1+an)/2 Log("levels="+levels+",tickValue="+tickValue+",Lots="+Lots); MaximalLoss= (levels/Point)*tickValue*Lots/2; if(!IsOptimization()) { //newParamString= HIGH+","+LOW+","+Entry+","+Lots; bool bSame= false; if(GlobalVariableCheck("initialCycleEquity_"+MagicNum)) { initialCycleEquity= GlobalVariableGet("initialCycleEquity_"+MagicNum); Log("initialCycleEquity loaded: " + initialCycleEquity); } if(GlobalVariableCheck("High_"+MagicNum)) if(GlobalVariableCheck("Low_"+MagicNum)) if(GlobalVariableCheck("Entry_"+MagicNum)) if(GlobalVariableCheck("Lots_"+MagicNum)) { if(GlobalVariableGet("High_"+MagicNum)==HIGH) if(GlobalVariableGet("Low_"+MagicNum)==LOW) if(GlobalVariableGet("Entry_"+MagicNum)==Entry) if(GlobalVariableGet("Lots_"+MagicNum)==Lots) bSame= true; Log("Values: "+bSame); Log(GlobalVariableGet("High_"+MagicNum)+","+HIGH); Log(GlobalVariableGet("Low_"+MagicNum)+","+LOW); Log(GlobalVariableGet("Entry_"+MagicNum)+","+Entry); Log(GlobalVariableGet("Lots_"+MagicNum)+","+Lots); } if(!bSame) { int MinReq= MaximalLoss+MargReq-MaxProfit; // Replaced MessageBox with Print - check logs for margin requirements Print("MARGIN INFO - Total Margin Required: ("+MargReq+")"+ " Max Potential Loss: ("+MaximalLoss + ")"+ " Max Potential Profit: " + MaxProfit+ " Minimum Funds Required: "+MinReq); //Log("Msgbox: "+MaximalLoss+",rc="+rc); // if(rc==IDYES) // { GlobalVariableSet("High_"+MagicNum, HIGH); GlobalVariableSet("Low_"+MagicNum, LOW); GlobalVariableSet("Entry_"+MagicNum, Entry); GlobalVariableSet("Lots_"+MagicNum, Lots); Log("Vars saved"); // } } } closeOnProfit= TakeProfitLevelPercent*AccountEquity()/100; initEquity= BaseEquity; //AccountEquity(); if(GlobalVariableCheck(MagicNum+"_withdraw")) { tmp= GlobalVariableGet(MagicNum+"_withdraw"); if(tmp==0) bWithdrawMailSent= false; else bWithdrawMailSent= true; } //if(IDYES==rc) // { for(int i=0; i0) { tradeLogId= FileOpen("TradesLog_"+TimeToStr(TimeCurrent(),TIME_DATE | TIME_MINUTES)+".txt", FILE_WRITE); for(int i=0; i=TRADE_RANGE*Point) { Print("CreateLongTrade failed. tradePrice="+tradePrice+",Bid="+Bid+",TRADE_RANGE="+TRADE_RANGE+",Point="+Point); Log("CreateLongTrade failed. tradePrice="+tradePrice+",Bid="+Bid+",TRADE_RANGE="+TRADE_RANGE+",Point="+Point); return(rc); } if((tradePrice<=LongLimit)|| LongLimit==0) if(bEnableLongs) { if(tradePrice==Bid) { cmd= OP_BUY; price= Ask; } else if(tradePrice<=Bid-stoplevel*Point) { cmd= OP_BUYLIMIT; price= tradePrice+slippage()*Point; } else if(tradePrice>=Bid+stoplevel*Point) { cmd= OP_BUYSTOP; price= tradePrice+slippage()*Point; } else { Print("CreateLongTrade ERROR tradePrice="+tradePrice+",Bid="+Bid); Log("CreateLongTrade ERROR tradePrice="+tradePrice+",Bid="+Bid); } if(cmd!=-1) { if(TakeProfit>0) tp= price+TakeProfit*Point; if(StopLoss>0) sl= price-StopLoss*Point; if(isOkToBUY(OrdersTotal(), price)) { rc= OrderSend(Symbol(),cmd,lots,price,slippage(),sl,tp,WindowExpertName()+MagicNum,MagicNum,0,Blue); //Sleep(3000);//sleep 3 seconds if(-1==rc) { Log("Error= "+ GetLastError() + ", price="+price+",sl="+sl+",tp="+tp+",cmd="+cmd+",lots="+lots+",Bid="+Bid); Print("error>> " + GetLastError()); //Alert("error>> " + GetLastError()); } else { Log("LONG ticket=" + rc +",price="+price+",sl="+sl+",tp="+tp+",cmd="+cmd+",tradePrice="+tradePrice+",Bid="+Bid); } } } } return(rc); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CreateShortTrade(double tradePrice, double lots) { int rc= -1; int cmd= -1; double price; double sl= 0; double tp= 0; if(MathAbs(tradePrice-Bid)>=TRADE_RANGE*Point) { Log("CreateShortTrade failed. tradePrice="+tradePrice+",Bid="+Bid+",TRADE_RANGE="+TRADE_RANGE+",Point="+Point); return(rc); } if(tradePrice>=ShortLimit) if(bEnableShorts) { if(tradePrice==Bid) { cmd= OP_SELL; price= Bid; } else if(tradePrice>=Bid+stoplevel*Point) { cmd= OP_SELLLIMIT; price= tradePrice; } else if(tradePrice<=Bid-stoplevel*Point) { cmd= OP_SELLSTOP; price= tradePrice; } else Log("CreateShortTrade ERROR tradePrice="+tradePrice+",Bid="+Bid); if(cmd!=-1) { if(TakeProfit>0) tp= price-TakeProfit*Point; if(StopLoss>0) sl= price+StopLoss*Point; if(isOkToSELL(OrdersTotal(), price)) { rc= OrderSend(Symbol(),cmd,lots,price,slippage(),sl,tp,WindowExpertName()+MagicNum,MagicNum,0,Red); //Sleep(3000);//sleep 3 seconds if(-1==rc) { Log("SHORT Error= "+ GetLastError() + ", price="+price+",sl="+sl+",tp="+tp+",cmd="+cmd+",lots="+lots+",Bid="+Bid); Print("error>> " + GetLastError()); //Alert("error>> " + GetLastError()); } else Log("SHORT ticket="+rc+",price="+price+",sl="+sl+",tp="+tp+",cmd="+cmd+",Bid="+Bid); } } } return(rc); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool IsPricesEqual(double price1, double price2) { int intPrice1= MathPow(10, Digits)*(price1+Point/2); int intPrice2= MathPow(10, Digits)*(price2+Point/2); //Log("intPrice1="+intPrice1+",intPrice2="+intPrice2); return(intPrice1==intPrice2); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void RestoreTrades() { double tradePrice; int idx= 0; for(tradePrice= LOW; tradePrice<=HIGH; tradePrice+= Entry, idx++) { for(int cnt=0; cnt0) longAvgPrice= (longAvgPrice/longAvgLots); if(shortAvgLots>0) shortAvgPrice= shortAvgPrice/shortAvgLots; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double CalcProfit(int MagicNumber) { int cnt; double sum; longProfit= 0; shortProfit= 0; string updateSt= ""; bool bUpdate; int ticket= lastTicketSentOpen; for(cnt=0; cnt=0; cnt--) { OrderSelect(cnt, SELECT_BY_POS); if(OrderMagicNumber()==MagicNum && OrderSymbol()==Symbol()) { if((OrderType()==OP_BUY && getOutLongs && (OrderProfit()>0 || GetOut=="X" || GetOut=="x")) || (OrderType()==OP_SELL && getOutShorts && (OrderProfit()>0 || GetOut=="X" || GetOut=="x"))) OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), MarketInfo(Symbol(),MODE_SPREAD), Purple); if((GetOut=="X" || GetOut=="x") && OrderType()!=OP_BUY && OrderType()!=OP_SELL) OrderDelete(OrderTicket()); } } } if(GetOut!="N") CalcProfit(MagicNum); if(getOutLongs) { if(longProfit>=0) CloseAllTrades(OP_BUY); } else if(getOutShorts) { if(shortProfit>=0) CloseAllTrades(OP_SELL); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool HandleOpposite() { int idx=-1; int interval= Entry*MathPow(10,Digits); double price; double lots; int s=0, l=0; bool rc= true; Log("Levels= "+Levels); for(int i=0; i=0; cnt--) if(OrderSelect(cnt, SELECT_BY_POS)) { if(OrderType()==OP_BUY || OrderType()==OP_SELL) OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), MarketInfo(Symbol(), MODE_SPREAD), White); else OrderDelete(OrderTicket()); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void SendEmailToBroker(int profit) { string st= ""; st= "Hello,\n"+AccountName()+" here, Trading A/c " + AccountNumber() + ".\n"; st=st+"Would you kindly transfer $" + profit + " to my a/c # " + HoldingAccount + " as soon as possible?\n\n"; st=st+"Many thanks!\n\nRegards\n\n"+AccountName(); Print("Transfer Funds Request: " + st); SendNotification("Transfer Funds Request: " + st); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int start() { string breakevenString; string stRange= ""; int idx= 0; int interval= Entry*MathPow(10,Digits); double profit= CalcProfit(MagicNum); static datetime lastPingTime= 0; //Report.php handle if((TimeCurrent()-lastPingTime)>=PingTimeMinutes*60) { string answer= "0"; if(IsDemo()) { Print("http://letyourcomputertrade.com/php/report.php?email="+Email+"&Dacc="+AccountNumber()+"&bal="+AccountBalance()+"&equity="+AccountEquity()); if(GrabWeb("http://letyourcomputertrade.com/php/report.php?email="+Email+"&Dacc="+AccountNumber()+"&bal="+AccountBalance()+"&equity="+AccountEquity(), answer)) { lastPingTime= TimeCurrent(); } } else { Print("http://letyourcomputertrade.com/php/report.php?email="+Email+"&Dacc="+AccountNumber()+"&bal="+AccountBalance()+"&equity="+AccountEquity()); if(GrabWeb("http://letyourcomputertrade.com/php/report.php?email="+Email+"&Lacc="+AccountNumber()+"&bal="+AccountBalance()+"&equity="+AccountEquity(), answer)) { lastPingTime= TimeCurrent(); } } } // Handle tp=0 for(int i=0; iOrderClosePrice() && OrderType()==OP_SELL)) { rc= OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), MarketInfo(Symbol(), MODE_SPREAD), White); Log("Close Ticket #"+OrderTicket()+" modified tp to " + tp+ " res="+rc+",err="+GetLastError()); } else { rc= OrderModify(OrderTicket(), 0, OrderStopLoss(), tp, 0, White); Log("Ticket #"+OrderTicket()+" modified tp to " + tp+ " res="+rc+",err="+GetLastError()); } } double deltaToLong = LongLimit - (TRADE_RANGE/2); double diffLongdelta = Ask - deltaToLong; if(deltaToLong < Ask && diffLongdelta > moveRangeTrigger) { LongLimit = LongLimit - diffLongdelta; } double deltaToShort = ShortLimit + (TRADE_RANGE/2); double diffShortdelta = deltaToShort - Bid; if(deltaToShort > Bid && diffShortdelta > moveRangeTrigger) { ShortLimit = ShortLimit + diffLongdelta; } if(!bGetOutOK) { Comment("GetOut has an invalid value!"); Log("GetOut has an invalid value!"); return(0); } if(!bGetOutHandled) { bGetOutHandled= true; HandleGetOut(true); } if(!bOpenNewTradesOK) { Comment("OpenNewTrades has an invalid value!"); Log("OpenNewTrades has an invalid value!"); return(0); } if(TakeProfitLevelPercent>0) { if(AccountEquity()>=(initialCycleEquity+closeOnProfit) || (AccountEquity() >= (TakeProfitLevelDollarAmount + initialCycleEquity)&& TakeProfitLevelDollarAmount >0)) { bInit= false; Log("TakeProfitLevel condition filled. Equity="+AccountEquity()+",profit="+profit); if(Master) { GlobalCloseAllTrades(); //CloseAllTrades(OP_SELL); //CloseAllTrades(OP_BUY); if(!bWithdrawMailSent) { SendEmailToBroker(closeOnProfit); bWithdrawMailSent= true; } } } else bWithdrawMailSent= false; } if(!bInit) { Log("BInit=false"); int cnt= 0; idx= 0; for(cnt=0; cntEntry*Point) isSellOpen = true; else { isSellOpen = false; break; } } } } isSellOpen = CheckTradeContext(); doTrade = isSellOpen ; return(doTrade); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool isOkToBUY(int totOrds, double orderPrice) { bool doTrade = true; bool isBuyOpen = true; for(int cnt=0; cntEntry*Point) isBuyOpen = true; else { isBuyOpen = false; break; } } } } isBuyOpen = CheckTradeContext(); doTrade = isBuyOpen ; return(doTrade); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CheckTradeContext() { // check whether the trade context is free if(!IsTradeAllowed()) { Print("Trade context is busy! Wait until it is free..."); // infinite loop while(true) { // if the expert was stopped by the user, stop operation if(IsStopped()) { Print("The expert was stopped by the user!"); return(-1); } // if trade context has become free, terminate the loop and start trading if(IsTradeAllowed()) { Print("Trade context has become free!"); break; } // if no loop breaking condition has been met, "wait" for 0.1 sec // and restart checking Sleep(100); } } return(true); } //+------------------------------------------------------------------+