253 lines
9.1 KiB
MQL5
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));
|
|
}
|
|
//+------------------------------------------------------------------+
|