155 lines
5.2 KiB
MQL5
155 lines
5.2 KiB
MQL5
//+------------------------------------------------------------------+
| |||
//| TradeManager.mqh |
| |||
//| Copyright 2025, MetaQuotes Ltd. |
| |||
//| https://www.mql5.com |
| |||
//+------------------------------------------------------------------+
| |||
#property copyright "Copyright 2025, MetaQuotes Ltd."
| |||
#property link "https://www.mql5.com"
| |||
#property version "1.00"
| |||
| |||
#include "../Configs/EAConfig.mqh"
| |||
#include "../Market/DataManager.mqh"
| |||
#include "TradeExecutor.mqh"
| |||
#include "../Events/Events/TradingEvents.mqh"
| |||
| |||
#include <Mql5Book\TrailingStops.mqh>
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| |
| |||
//+------------------------------------------------------------------+
| |||
class TradeManager final: public IEventListener
| |||
{
| |||
private:
| |||
EventBus* m_bus;
| |||
ITradeExecutor* m_executor;
| |||
CTrailing m_trail;
| |||
EAConfig configs;
| |||
CPositions pos;
| |||
| |||
SymbolConfig findSymbol(string symbol)
| |||
{
| |||
for(int i = 0; i < configs.tfConfigs.Size(); i++)
| |||
{
| |||
SymbolConfig data = configs.tfConfigs.At(i);
| |||
| |||
if(data.symbol == symbol)
| |||
return data;
| |||
}
| |||
SymbolConfig t;
| |||
return t;
| |||
}
| |||
| |||
public:
| |||
TradeManager() {}
| |||
~TradeManager() {}
| |||
| |||
double GetPoint(string symbol) { return SymbolInfoDouble(symbol, SYMBOL_POINT); }
| |||
void TrailingAndBreakeven(string symbol);
| |||
| |||
void Initialize(EventBus * bus, ITradeExecutor * executor, EAConfig & m_configs)
| |||
{
| |||
m_bus = bus;
| |||
m_executor = executor;
| |||
configs = m_configs;
| |||
}
| |||
| |||
virtual void OnEvent(AbstractEvent * event) override
| |||
{
| |||
if(event.GetType() == EXECUTE_MARKET_ORDER)
| |||
{
| |||
ExecuteMarketOrderEvent* e = (ExecuteMarketOrderEvent*)event;
| |||
MarketOrderRequest req;
| |||
req.symbol = e.GetSymbolName();
| |||
req.direction = e.GetDirection();
| |||
req.volume = e.GetVolume();
| |||
req.sl = e.GetSL();
| |||
req.tp = e.GetTP();
| |||
req.comment = e.GetComment();
| |||
req.magic = configs.magicNumber;
| |||
req.price = e.GetPrice();
| |||
ulong ticket = m_executor.PlaceMarketOrder(req);
| |||
if(ticket > 0)
| |||
{
| |||
| |||
PositionOpenedEvent* dpos = new PositionOpenedEvent(ticket, req.symbol, req.direction, req.volume, req.price, req.sl, req.tp, TimeCurrent());
| |||
m_bus.Push(dpos);
| |||
}
| |||
}
| |||
else
| |||
if(event.GetType() == EXECUTE_PENDING_ORDER)
| |||
{
| |||
ExecutePendingOrderEvent* pend = (ExecutePendingOrderEvent*)event;
| |||
PendingOrderRequest req;
| |||
req.symbol = pend.GetSymbolName();
| |||
req.type = pend.GetOrderType();
| |||
req.volume = pend.GetVolume();
| |||
req.price = pend.GetPrice();
| |||
req.stoplimit = pend.GetStopLimit();
| |||
req.sl = pend.GetSL();
| |||
req.tp = pend.GetTP();
| |||
req.expiration = pend.GetExpiration();
| |||
req.comment = pend.GetComment();
| |||
req.magic = configs.magicNumber;
| |||
| |||
ulong ticket = m_executor.PlacePendingOrder(req);
| |||
| |||
| |||
if(ticket > 0)
| |||
{
| |||
PendingOrderPlacedEvent* placed = new PendingOrderPlacedEvent(
| |||
ticket, req.symbol, req.type, req.volume, req.price, req.sl, req.tp,
| |||
req.expiration, req.comment);
| |||
m_bus.Push(placed);
| |||
}
| |||
}
| |||
else
| |||
if(event.GetType() == NEW_BAR)
| |||
{
| |||
TrailingAndBreakeven(event.GetSymbolName());
| |||
}
| |||
}
| |||
};
| |||
| |||
//+------------------------------------------------------------------+
| |||
//| |
| |||
//+------------------------------------------------------------------+
| |||
void TradeManager::TrailingAndBreakeven(string symbol)
| |||
{
| |||
ulong tickets[];
| |||
pos.GetTickets(configs.magicNumber, tickets);
| |||
| |||
//Print(symbol, ": ", ArraySize(tickets));
| |||
SymbolConfig c = findSymbol(symbol);
| |||
| |||
for(int i = 0; i < ArraySize(tickets); i++)
| |||
{
| |||
if(c.rmConfigs.UseTrailingStop)
| |||
m_trail.TrailingStop(tickets[i], c.rmConfigs.TrailingStop, c.rmConfigs.MinimumProfit, c.rmConfigs.Step);
| |||
| |||
if(c.rmConfigs.UseBreakEven)
| |||
m_trail.BreakEven(tickets[i], c.rmConfigs.BreakEvenProfit, c.rmConfigs.LockProfit);
| |||
| |||
if(c.rmConfigs.UseAutoClose)
| |||
{
| |||
if(PositionSelectByTicket(tickets[i]))
| |||
{
| |||
long open_time = PositionGetInteger(POSITION_TIME);
| |||
datetime current_time = TimeCurrent();
| |||
| |||
int bar_count = Bars(symbol, c.tradeTimeframe, open_time, current_time);
| |||
// Print(symbol, ": ", bar_count);
| |||
if(bar_count >= c.rmConfigs.tradeDuration)
| |||
{
| |||
Print(symbol, ":Close ", bar_count);
| |||
if(m_executor.ClosePosition(tickets[i]))
| |||
{
| |||
Print( "Closed" );
| |||
| |||
}
| |||
}
| |||
}
| |||
}
| |||
| |||
}
| |||
}
| |||
//+------------------------------------------------------------------+
|