IndianTrailingStopLoss/Trade.mqh
super.admin 88be02cad4 convert
2025-05-30 15:00:53 +02:00

253 lines
9.1 KiB
MQL5

//+------------------------------------------------------------------+
//| GrayMatrixTrade.mqh |
//| Jay Davis |
//| 512jay.github.io |
//+------------------------------------------------------------------+
#property copyright "Jay Davis"
#property link "512jay.github.io"
#property version "1.03"
#include "Database.mqh"
#include<Trade\Trade.mqh>
input bool RunInVirtualMode = false; // Run in virtual mode?
//+------------------------------------------------------------------+
//| Wrapper class for CTrade class |
//+------------------------------------------------------------------+
class GrayMatrixTrade : public CTrade
{
private:
protected:
public:
GrayMatrixTrade();
~GrayMatrixTrade();
virtual bool OrderSend(const MqlTradeRequest &request, MqlTradeResult &result);
bool PositionModify(const string symbol, const double sl, const double tp);
bool PositionModify(const ulong ticket, const double sl, const double tp);
virtual bool PositionClose(const ulong ticket, const ulong deviation);
virtual bool PositionClose(const string symbol, const ulong deviation);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
GrayMatrixTrade::GrayMatrixTrade()
{
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
GrayMatrixTrade::~GrayMatrixTrade()
{
}
//+------------------------------------------------------------------+
//| Send order |
//+------------------------------------------------------------------+
bool GrayMatrixTrade::OrderSend(const MqlTradeRequest &request, MqlTradeResult &result)
{
if(!MQLInfoInteger(MQL_TESTER))
{
MqlTradeRequest aRequest = request;
bool inserted = InsertMqlTradeRequest(aRequest);
if(RunInVirtualMode)
if(inserted)
return true;
else
return false;
}
bool res;
string action="";
string fmt ="";
//--- action
if(m_async_mode)
res=::OrderSendAsync(request, result);
else
res=::OrderSend(request, result);
//--- check
if(res)
{
if(m_log_level>LOG_LEVEL_ERRORS)
PrintFormat(__FUNCTION__+": %s [%s]", FormatRequest(action, request), FormatRequestResult(fmt, request, result));
}
else
{
if(m_log_level>LOG_LEVEL_NO)
PrintFormat(__FUNCTION__+": %s [%s]", FormatRequest(action, request), FormatRequestResult(fmt, request, result));
}
//--- return the result
return(res);
}
//+------------------------------------------------------------------+
//| Close specified opened position |
//+------------------------------------------------------------------+
bool GrayMatrixTrade::PositionClose(const string symbol, const ulong deviation=ULONG_MAX)
{
//Print(__FUNCTION__,__FUNCSIG__);
bool partial_close=false;
int retry_count =10;
uint retcode =TRADE_RETCODE_REJECT;
//--- check stopped
if(IsStopped(__FUNCTION__))
return(false);
//--- clean
ClearStructures();
m_request.comment ="closed"; // Set special identifying information.
//--- check filling
if(!FillingCheck(symbol))
return(false);
do
{
//--- check
if(SelectPosition(symbol))
{
if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
{
//--- prepare request for close BUY position
m_request.type =ORDER_TYPE_SELL;
m_request.price=SymbolInfoDouble(symbol, SYMBOL_BID);
}
else
{
//--- prepare request for close SELL position
m_request.type =ORDER_TYPE_BUY;
m_request.price=SymbolInfoDouble(symbol, SYMBOL_ASK);
}
}
else
{
//--- position not found
m_result.retcode=retcode;
return(false);
}
//--- setting request
m_request.action =TRADE_ACTION_DEAL;
m_request.symbol =symbol;
m_request.volume =PositionGetDouble(POSITION_VOLUME);
m_request.magic =m_magic;
m_request.deviation=(deviation==ULONG_MAX) ? m_deviation : deviation;
//--- check volume
double max_volume=SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);
if(m_request.volume>max_volume)
{
m_request.volume=max_volume;
partial_close=true;
}
else
partial_close=false;
//--- hedging? just send order
if(IsHedging())
{
m_request.position=PositionGetInteger(POSITION_TICKET);
return(OrderSend(m_request, m_result));
}
//--- order send
if(!OrderSend(m_request, m_result))
{
if(--retry_count!=0)
continue;
if(retcode==TRADE_RETCODE_DONE_PARTIAL)
m_result.retcode=retcode;
return(false);
}
//--- WARNING. If position volume exceeds the maximum volume allowed for deal,
//--- and when the asynchronous trade mode is on, for safety reasons, position is closed not completely,
//--- but partially. It is decreased by the maximum volume allowed for deal.
if(m_async_mode)
break;
retcode=TRADE_RETCODE_DONE_PARTIAL;
if(partial_close)
Sleep(1000);
}
while(partial_close);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Close specified opened position |
//+------------------------------------------------------------------+
bool GrayMatrixTrade::PositionClose(const ulong ticket, const ulong deviation=ULONG_MAX)
{
//--- check stopped
if(IsStopped(__FUNCTION__))
return(false);
//--- check position existence
if(!PositionSelectByTicket(ticket))
return(false);
string symbol=PositionGetString(POSITION_SYMBOL);
//--- clean
ClearStructures();
m_request.comment ="closed"; // Set special identifying information.
//--- check filling
if(!FillingCheck(symbol))
return(false);
//--- check
if((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
{
//--- prepare request for close BUY position
m_request.type =ORDER_TYPE_SELL;
m_request.price=SymbolInfoDouble(symbol, SYMBOL_BID);
}
else
{
//--- prepare request for close SELL position
m_request.type =ORDER_TYPE_BUY;
m_request.price=SymbolInfoDouble(symbol, SYMBOL_ASK);
}
//--- setting request
m_request.action =TRADE_ACTION_DEAL;
m_request.position =ticket;
m_request.symbol =symbol;
m_request.volume =PositionGetDouble(POSITION_VOLUME);
m_request.magic =m_magic;
m_request.deviation=(deviation==ULONG_MAX) ? m_deviation : deviation;
//--- close position
return(OrderSend(m_request, m_result));
}
//+------------------------------------------------------------------+
//| Modify specified opened position |
//+------------------------------------------------------------------+
bool GrayMatrixTrade::PositionModify(const string symbol, const double sl, const double tp)
{
//--- check stopped
if(IsStopped(__FUNCTION__))
return(false);
//--- check position existence
if(!SelectPosition(symbol))
return(false);
//--- clean
ClearStructures();
//--- setting request
m_request.action =TRADE_ACTION_SLTP;
m_request.symbol =symbol;
m_request.magic =m_magic;
m_request.sl =sl;
m_request.tp =tp;
m_request.position=PositionGetInteger(POSITION_TICKET);
//--- action and return the result
return(OrderSend(m_request, m_result));
}
//+------------------------------------------------------------------+
//| Modify specified opened position |
//+------------------------------------------------------------------+
bool GrayMatrixTrade::PositionModify(const ulong ticket, const double sl, const double tp)
{
Print(__FUNCTION__);
//--- check stopped
if(IsStopped(__FUNCTION__))
return(false);
//--- check position existence
if(!PositionSelectByTicket(ticket))
return(false);
//--- clean
ClearStructures();
//--- setting request
m_request.action =TRADE_ACTION_SLTP;
m_request.position=ticket;
m_request.symbol =PositionGetString(POSITION_SYMBOL);
m_request.magic =m_magic;
m_request.sl =sl;
m_request.tp =tp;
//--- action and return the result
return(OrderSend(m_request, m_result));
}
//+------------------------------------------------------------------+