//+------------------------------------------------------------------+ //| PlaceOrders.mqh | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #include #include #include "..\\Includes\\CalculateBreakeven.mqh" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class OrderManager { private: public: int recoveryOrdersSell; int recoveryOrdersBuy; CPositionInfo m_position; CTrade m_trade; OrderManager(); ~OrderManager(); void CloseTrades(long MagicNumber,bool buy,bool sell,double profit=0,double parttoclose=0); void TrailTrades(long MagicNumber,bool buy,bool sell,double profit,double parttoclose, double iTrailingStart, double iTrailStep,double iTrailingStop); int HedgePositions(long MagicNumber); void FirstOrder(long Mymagic,double Volume); bool PlaceOrder(ENUM_POSITION_TYPE TypeOrder, double Volume, int magic, string Comment); double RelativeProfitOnMagic(long MyMagic,double lots,double min,double lotstobreakdown,datetime hedge,bool proces,bool forcerecover); double RelativeProfitOnMagic2(long MyMagic,double lots,double min,double lotstobreakdown,datetime hedge,bool proces,bool forcerecover); double TrallB ; double LastOrderProfit(); long GetDirectionOfTheLastProfitTrade(int mtype, string symbol, int magicx); void CloseAll(); int PositionTotalOnThis(); bool ToMuchMagic(); int GetHighestMagic(); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ OrderManager::OrderManager() { m_trade.SetTypeFillingBySymbol(m_position.Symbol()); TrallB = 0; recoveryOrdersSell=0; recoveryOrdersBuy=0; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ OrderManager::~OrderManager() { } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OrderManager::FirstOrder(long Mymagic,double Volume) { MqlRates rates[]; CopyRates(Symbol(),PERIOD_M15,0,2,rates); MqlTick tick; if(!SymbolInfoTick(Symbol(),tick)) Print("SymbolInfoTick() failed, error = ",GetLastError()); if(GetDirectionOfTheLastProfitTrade(-99, _Symbol, -1)== DEAL_TYPE_BUY) { if(!PlaceOrder(POSITION_TYPE_SELL,Volume,Mymagic,NULL)) printf("error"); } else { if(!PlaceOrder(POSITION_TYPE_BUY,Volume,Mymagic,NULL)) printf("error"); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ long OrderManager::GetDirectionOfTheLastProfitTrade(int mtype, string symbol, int magicx) { ulong ticket=0; int cta=0; HistorySelect(0,TimeCurrent()); for(int i=HistoryOrdersTotal(); i>=0; i--) { if((ticket=HistoryDealGetTicket(i))>0) { if(HistoryDealGetInteger(ticket,DEAL_ENTRY) == DEAL_ENTRY_OUT) { string s= HistoryDealGetString(ticket,DEAL_SYMBOL); if(s==symbol || symbol=="ALL") { long type =HistoryDealGetInteger(ticket,DEAL_TYPE); if(type==mtype || mtype==-99) { long m =HistoryDealGetInteger(ticket, DEAL_MAGIC); if(m==magicx || magicx==-1) { double profit=HistoryDealGetDouble(ticket, DEAL_PROFIT); if(profit>0) return type; } } } } } } return 0; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double OrderManager::LastOrderProfit() { int totalPositions = PositionsTotal(); double lastPositionProfit = 0.0; for (int i = totalPositions - 1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if (PositionSelectByTicket(ticket)) { if (PositionGetString(POSITION_SYMBOL) == _Symbol) { lastPositionProfit = PositionGetDouble(POSITION_PROFIT); break; } } } return lastPositionProfit; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double OrderManager::RelativeProfitOnMagic(long MyMagic,double lots,double min,double lotstobreakdown,datetime hedge,bool proces,bool forcerecover) { MqlDateTime rightNow; TimeCurrent(rightNow); CalculateBreakeven breakEven; m_trade.SetMarginMode(); BreakEvenInput breakEvenInput; breakEvenInput.Buys=true; breakEvenInput.Sells=true; breakEvenInput.MagicNumber=MyMagic; breakEvenInput.ProfitInMoney=0; breakEvenInput.HedgeToBreakDownLots=lotstobreakdown; BreakEvenResult breakevenResult=breakEven.GetBreakEven(breakEvenInput); // if((NormalizeDouble(breakevenResult.Net_Lots,2)==0) && proces && breakevenResult.Net_Trades>0 ) { FirstOrder(MyMagic, lots); FirstOrder(MyMagic, lots); FirstOrder(MyMagic, lots); FirstOrder(MyMagic, lots); recoveryOrdersBuy=0; recoveryOrdersSell=0; } //&&(hedge+=0* PeriodSeconds(PERIOD_H1))0 ) { if(recoveryOrdersBuy<(MyMagic>1?2:3)) { PlaceOrder(POSITION_TYPE_BUY,lots,MyMagic,MyMagic); recoveryOrdersBuy=recoveryOrdersBuy+1; recoveryOrdersSell=0; } } if((LastOrderProfit()1?2:3)) { PlaceOrder(POSITION_TYPE_SELL,lots,MyMagic,MyMagic); recoveryOrdersBuy=0; recoveryOrdersSell=recoveryOrdersSell+1; } } return breakevenResult.Net_Result; } double OrderManager::RelativeProfitOnMagic2(long MyMagic,double lots,double min,double lotstobreakdown,datetime hedge,bool proces,bool forcerecover) { MqlDateTime rightNow; TimeCurrent(rightNow); CalculateBreakeven breakEven; m_trade.SetMarginMode(); BreakEvenInput breakEvenInput; breakEvenInput.Buys=true; breakEvenInput.Sells=true; breakEvenInput.MagicNumber=MyMagic; breakEvenInput.ProfitInMoney=0; breakEvenInput.HedgeToBreakDownLots=lotstobreakdown; BreakEvenResult breakevenResult=breakEven.GetBreakEven(breakEvenInput); // // if(((NormalizeDouble(breakevenResult.Net_Lots,2)==0)&&(hedge+=0* PeriodSeconds(PERIOD_H1))0 && rightNow.hour>10)||forcerecover) // FirstOrder(MyMagic, lots); /* double relativ= (breakevenResult.Net_Result*MathAbs(lots/(breakevenResult.Net_Lots==0?lots:breakevenResult.Net_Lots))); if((LastOrderProfit()0 && proces){ if (recoveryOrdersBuy<4){ PlaceOrder(POSITION_TYPE_BUY,lots,MyMagic,NULL); recoveryOrdersBuy=recoveryOrdersBuy+1; recoveryOrdersSell=0;} } if((LastOrderProfit()=0; i--) // returns the number of current positions if(m_position.SelectByIndex(i)) { m_trade.PositionClose(m_position.Ticket()); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OrderManager::PositionTotalOnThis() { int total=0; for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of current positions if(m_position.SelectByIndex(i)) { if(m_position.Symbol()==_Symbol) total=total+1; } return total; } bool OrderManager::ToMuchMagic() { MqlDateTime SDateTime; TimeToStruct(TimeCurrent(),SDateTime); SDateTime.hour=0; SDateTime.min=0; SDateTime.sec=0; datetime from_date=StructToTime(SDateTime); // From date SDateTime.hour=10; SDateTime.min=59; SDateTime.sec=59; datetime to_date=StructToTime(SDateTime); // To date to_date-=60*60*24; return true; } int OrderManager::GetHighestMagic() { int magic=1; for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of current positions if(m_position.SelectByIndex(i)) { if(m_position.Symbol()==_Symbol) if (m_position.Magic()>magic) magic=m_position.Magic(); } return magic; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OrderManager::CloseTrades(long MagicNumber,bool buy,bool sell,double profit=0,double parttoclose=0) { CalculateBreakeven breakEven; m_trade.SetMarginMode(); BreakEvenInput breakEvenInput; breakEvenInput.Buys=true; breakEvenInput.Sells=true; breakEvenInput.MagicNumber=MagicNumber; breakEvenInput.ProfitInMoney=profit; breakEvenInput.HedgeToBreakDownLots=parttoclose; BreakEvenResult breakevenResult=breakEven.GetBreakEven(breakEvenInput); if((breakevenResult.Net_Lots>0 && SymbolInfoDouble(_Symbol, SYMBOL_BID)>=breakevenResult.Average_Price) || (breakevenResult.Net_Lots<0 && SymbolInfoDouble(_Symbol, SYMBOL_ASK)<=breakevenResult.Average_Price)|| profit==0 || MagicNumber==0) for(int i=breakevenResult.TicketsToClose.Total()-1; i>=0; i--) // returns the number of current positions if(m_position.SelectByTicket(breakevenResult.TicketsToClose.At(i))) // selects the position by index for further access to its properties { if(breakevenResult.TicketsLotSizeToClose.At(i)==0) printf("error zero volume"); m_trade.PositionClosePartial(m_position.Ticket(),breakevenResult.TicketsLotSizeToClose.At(i)); recoveryOrdersSell=0; recoveryOrdersBuy=0; } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OrderManager::TrailTrades(long MagicNumber,bool buy,bool sell,double profit,double parttoclose, double iTrailingStart, double iTrailStep,double iTrailingStop) { CalculateBreakeven breakEven; m_trade.SetMarginMode(); BreakEvenInput breakEvenInput; breakEvenInput.Buys=true; breakEvenInput.Sells=true; breakEvenInput.MagicNumber=MagicNumber; breakEvenInput.ProfitInMoney=profit; breakEvenInput.HedgeToBreakDownLots=parttoclose; BreakEvenResult breakevenResult=breakEven.GetBreakEven(breakEvenInput); double p = breakevenResult.Net_Result; if(breakevenResult.TicketsToClose.Total()==0) TrallB=0; double SL=breakevenResult.Net_Result-iTrailingStop; if(breakevenResult.Net_Result>=iTrailingStart && (TrallB==0 || TrallB+iTrailStep0)) for(int i=breakevenResult.TicketsToClose.Total()-1; i>=0; i--) if(m_position.SelectByTicket(breakevenResult.TicketsToClose.At(i))) { { m_trade.PositionClosePartial(m_position.Ticket(),breakevenResult.TicketsLotSizeToClose.At(i)); recoveryOrdersSell=0; recoveryOrdersBuy=0; } TrallB=0; } } //+------------------------------------------------------------------+ int OrderManager::HedgePositions(long MagicNumber) { CalculateBreakeven breakEven; m_trade.SetMarginMode(); BreakEvenInput breakEvenInput; breakEvenInput.Buys=true; breakEvenInput.Sells=true; BreakEvenResult breakevenResult=breakEven.GetBreakEven(breakEvenInput); if(breakevenResult.Net_Lots<0) { PlaceOrder(POSITION_TYPE_BUY,NormalizeDouble(MathAbs(breakevenResult.Net_Lots),2),MagicNumber,"HEDGE"); return 1; } if(breakevenResult.Net_Lots>0) { PlaceOrder(POSITION_TYPE_SELL,NormalizeDouble(breakevenResult.Net_Lots,2),MagicNumber,"HEDGE"); return 0; } return 0; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+