2026-03-05 02:33:18 +03:00
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Trader.mq5 |
|
|
|
|
|
//| Copyright 2026, MasterOfPuppets |
|
|
|
|
|
//| https://forge.mql5.io/masterofpuppets/mql5 |
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
#ifndef MASTER_OF_PUPPETS_LIB_TRADER_MQ5
|
|
|
|
|
#define MASTER_OF_PUPPETS_LIB_TRADER_MQ5
|
|
|
|
|
|
|
|
|
|
#include <MasterOfPuppetsLib\Trader.mqh>
|
|
|
|
|
|
|
|
|
|
#property copyright "Copyright 2026, MasterOfPuppets"
|
|
|
|
|
#property link "https://forge.mql5.io/masterofpuppets/mql5"
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
|
|
|
//| Trader initialization function |
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-03-06 07:29:22 +03:00
|
|
|
void Trader::Init(const TradeContext *srcTradeContext, const TraderContext *srcTraderContext)
|
2026-03-05 02:33:18 +03:00
|
|
|
{
|
2026-03-06 07:29:22 +03:00
|
|
|
m_tradeContext = srcTradeContext;
|
|
|
|
|
m_traderContext = srcTraderContext;
|
2026-03-05 02:33:18 +03:00
|
|
|
}
|
|
|
|
|
|
2026-03-06 09:09:20 +03:00
|
|
|
//+------------------------------------------------------------------+
|
2026-03-06 19:04:08 +03:00
|
|
|
//| Log function |
|
2026-03-06 09:09:20 +03:00
|
|
|
//+------------------------------------------------------------------+
|
2026-03-06 12:04:18 +03:00
|
|
|
void Trader::Log(const string message) const
|
2026-03-06 09:09:20 +03:00
|
|
|
{
|
|
|
|
|
Print(message);
|
|
|
|
|
PlaySoundFile(m_traderContext.GetSoundEnabled(), m_traderContext.GetSoundFileName());
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-05 02:33:18 +03:00
|
|
|
//+------------------------------------------------------------------+
|
2026-03-06 19:04:08 +03:00
|
|
|
//| Delete orders function |
|
2026-03-05 02:33:18 +03:00
|
|
|
//+------------------------------------------------------------------+
|
2026-03-06 12:04:18 +03:00
|
|
|
void Trader::DeleteOrders(const string message, const bool allOrders) const
|
2026-03-05 02:33:18 +03:00
|
|
|
{
|
|
|
|
|
for(int i = OrdersTotal() - 1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
if(m_tradeContext.GetOrderInfo().SelectByIndex(i))
|
|
|
|
|
{
|
2026-03-06 19:04:08 +03:00
|
|
|
if(allOrders || (m_tradeContext.GetOrderInfo().Magic() == m_traderContext.GetMagic()))
|
2026-03-05 02:33:18 +03:00
|
|
|
{
|
|
|
|
|
m_tradeContext.GetTrade().OrderDelete(m_tradeContext.GetOrderInfo().Ticket());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-03-06 09:09:20 +03:00
|
|
|
Log(message);
|
2026-03-05 02:33:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-03-06 19:04:08 +03:00
|
|
|
//| Modify function |
|
2026-03-05 02:33:18 +03:00
|
|
|
//+------------------------------------------------------------------+
|
2026-03-12 12:12:59 +03:00
|
|
|
void Trader::Modify(const string message, const IModifier* modifier) const
|
2026-03-05 02:33:18 +03:00
|
|
|
{
|
|
|
|
|
ModifyPositions(modifier);
|
2026-03-06 09:09:20 +03:00
|
|
|
Log(message);
|
2026-03-05 02:33:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-03-06 19:04:08 +03:00
|
|
|
//| Modify positions function |
|
2026-03-05 02:33:18 +03:00
|
|
|
//+------------------------------------------------------------------+
|
2026-03-12 12:12:59 +03:00
|
|
|
void Trader::ModifyPositions(const IModifier* modifier) const
|
2026-03-05 02:33:18 +03:00
|
|
|
{
|
|
|
|
|
for(int i = PositionsTotal() - 1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
if(m_tradeContext.GetPositionInfo().SelectByIndex(i))
|
|
|
|
|
{
|
|
|
|
|
modifier.Modify();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-03-06 19:04:08 +03:00
|
|
|
//| Order open function |
|
2026-03-05 02:33:18 +03:00
|
|
|
//+------------------------------------------------------------------+
|
2026-03-06 12:04:18 +03:00
|
|
|
void Trader::OrderOpen(const string message, const TradeAction tradeAction) const
|
2026-03-05 02:33:18 +03:00
|
|
|
{
|
|
|
|
|
ENUM_ORDER_TYPE orderType;
|
|
|
|
|
double price;
|
|
|
|
|
double deltaStopLoss;
|
|
|
|
|
double deltaTakeProfit;
|
|
|
|
|
m_tradeContext.GetSymbolInfo().RefreshRates();
|
|
|
|
|
switch(tradeAction)
|
|
|
|
|
{
|
2026-03-05 23:40:04 +03:00
|
|
|
case TradeAction::TRADE_ACTION_BUY_LIMIT:
|
2026-03-05 02:33:18 +03:00
|
|
|
orderType = ENUM_ORDER_TYPE::ORDER_TYPE_BUY_LIMIT;
|
2026-03-06 03:27:39 +03:00
|
|
|
price = m_tradeContext.GetSymbolInfo().Ask() - m_traderContext.GetStopLoss();
|
|
|
|
|
deltaStopLoss = -m_traderContext.GetStopLoss();
|
|
|
|
|
deltaTakeProfit = m_traderContext.GetTakeProfit();
|
2026-03-05 02:33:18 +03:00
|
|
|
break;
|
2026-03-05 23:40:04 +03:00
|
|
|
case TradeAction::TRADE_ACTION_BUY_STOP:
|
2026-03-05 02:33:18 +03:00
|
|
|
orderType = ENUM_ORDER_TYPE::ORDER_TYPE_BUY_STOP;
|
2026-03-06 03:27:39 +03:00
|
|
|
price = m_tradeContext.GetSymbolInfo().Ask() + m_traderContext.GetStopLoss();
|
|
|
|
|
deltaStopLoss = -m_traderContext.GetStopLoss();
|
|
|
|
|
deltaTakeProfit = m_traderContext.GetTakeProfit();
|
2026-03-05 02:33:18 +03:00
|
|
|
break;
|
2026-03-05 23:40:04 +03:00
|
|
|
case TradeAction::TRADE_ACTION_SELL_LIMIT:
|
2026-03-05 02:33:18 +03:00
|
|
|
orderType = ENUM_ORDER_TYPE::ORDER_TYPE_SELL_LIMIT;
|
2026-03-06 03:27:39 +03:00
|
|
|
price = m_tradeContext.GetSymbolInfo().Bid() + m_traderContext.GetStopLoss();
|
|
|
|
|
deltaStopLoss = m_traderContext.GetStopLoss();
|
|
|
|
|
deltaTakeProfit = -m_traderContext.GetTakeProfit();
|
2026-03-05 02:33:18 +03:00
|
|
|
break;
|
2026-03-05 23:40:04 +03:00
|
|
|
case TradeAction::TRADE_ACTION_SELL_STOP:
|
2026-03-05 02:33:18 +03:00
|
|
|
orderType = ENUM_ORDER_TYPE::ORDER_TYPE_SELL_STOP;
|
2026-03-06 03:27:39 +03:00
|
|
|
price = m_tradeContext.GetSymbolInfo().Bid() - m_traderContext.GetStopLoss();
|
|
|
|
|
deltaStopLoss = m_traderContext.GetStopLoss();
|
|
|
|
|
deltaTakeProfit = -m_traderContext.GetTakeProfit();
|
2026-03-05 02:33:18 +03:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-03-06 03:27:39 +03:00
|
|
|
double stopLoss = IsZero(m_traderContext.GetStopLoss())
|
|
|
|
|
? 0.0 : m_tradeContext.GetSymbolInfo().NormalizePrice(price + deltaStopLoss);
|
|
|
|
|
double takeProfit = IsZero(m_traderContext.GetTakeProfit())
|
|
|
|
|
? 0.0 : m_tradeContext.GetSymbolInfo().NormalizePrice(price + deltaTakeProfit);
|
|
|
|
|
m_tradeContext.GetTrade().OrderOpen(
|
|
|
|
|
_Symbol, orderType, m_traderContext.GetContracts(), price, price, stopLoss, takeProfit);
|
2026-03-06 09:09:20 +03:00
|
|
|
Log(message);
|
2026-03-05 02:33:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-03-06 19:04:08 +03:00
|
|
|
//| Position open function |
|
2026-03-05 02:33:18 +03:00
|
|
|
//+------------------------------------------------------------------+
|
2026-03-05 23:55:48 +03:00
|
|
|
void Trader::PositionOpen(const string message, const TradeAction tradeAction)
|
2026-03-05 02:33:18 +03:00
|
|
|
{
|
|
|
|
|
ENUM_ORDER_TYPE orderType;
|
|
|
|
|
double price;
|
|
|
|
|
double deltaStopLoss;
|
|
|
|
|
double deltaTakeProfit;
|
|
|
|
|
m_tradeContext.GetSymbolInfo().RefreshRates();
|
|
|
|
|
switch(tradeAction)
|
|
|
|
|
{
|
2026-03-05 23:40:04 +03:00
|
|
|
case TradeAction::TRADE_ACTION_BUY:
|
2026-03-05 02:33:18 +03:00
|
|
|
orderType = ENUM_ORDER_TYPE::ORDER_TYPE_BUY;
|
|
|
|
|
price = m_tradeContext.GetSymbolInfo().Ask();
|
|
|
|
|
m_buyPyramidPriceOpen = price;
|
2026-03-06 03:27:39 +03:00
|
|
|
deltaStopLoss = -m_traderContext.GetStopLoss();
|
|
|
|
|
deltaTakeProfit = m_traderContext.GetTakeProfit();
|
2026-03-05 02:33:18 +03:00
|
|
|
break;
|
2026-03-05 23:40:04 +03:00
|
|
|
case TradeAction::TRADE_ACTION_SELL:
|
2026-03-05 02:33:18 +03:00
|
|
|
orderType = ENUM_ORDER_TYPE::ORDER_TYPE_SELL;
|
|
|
|
|
price = m_tradeContext.GetSymbolInfo().Bid();
|
|
|
|
|
m_sellPyramidPriceOpen = price;
|
2026-03-06 03:27:39 +03:00
|
|
|
deltaStopLoss = m_traderContext.GetStopLoss();
|
|
|
|
|
deltaTakeProfit = -m_traderContext.GetTakeProfit();
|
2026-03-05 02:33:18 +03:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-03-06 03:27:39 +03:00
|
|
|
double stopLoss = IsZero(m_traderContext.GetStopLoss())
|
|
|
|
|
? 0.0 : m_tradeContext.GetSymbolInfo().NormalizePrice(price + deltaStopLoss);
|
|
|
|
|
double takeProfit = IsZero(m_traderContext.GetTakeProfit())
|
|
|
|
|
? 0.0 : m_tradeContext.GetSymbolInfo().NormalizePrice(price + deltaTakeProfit);
|
|
|
|
|
m_tradeContext.GetTrade().PositionOpen(
|
|
|
|
|
_Symbol, orderType, m_traderContext.GetContracts(), price, stopLoss, takeProfit);
|
2026-03-06 09:09:20 +03:00
|
|
|
Log(message);
|
2026-03-05 02:33:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-03-06 19:04:08 +03:00
|
|
|
//| Get buy pyramid price open function |
|
2026-03-05 02:33:18 +03:00
|
|
|
//+------------------------------------------------------------------+
|
2026-03-06 03:09:30 +03:00
|
|
|
const double Trader::GetBuyPyramidPriceOpen() const
|
2026-03-05 02:33:18 +03:00
|
|
|
{
|
|
|
|
|
return m_buyPyramidPriceOpen;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
2026-03-06 19:04:08 +03:00
|
|
|
//| Get sell pyramid price open function |
|
2026-03-05 02:33:18 +03:00
|
|
|
//+------------------------------------------------------------------+
|
2026-03-06 03:09:30 +03:00
|
|
|
const double Trader::GetSellPyramidPriceOpen() const
|
2026-03-05 02:33:18 +03:00
|
|
|
{
|
|
|
|
|
return m_sellPyramidPriceOpen;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
//+------------------------------------------------------------------+
|