mirror of
https://github.com/rithsila/MT5-EA-Sniper-Strategy.git
synced 2026-08-16 12:18:11 +00:00
210 lines
7.7 KiB
Plaintext
210 lines
7.7 KiB
Plaintext
//+------------------------------------------------------------------+
|
|
//| SignalGrid.mqh |
|
|
//| Copyright 2021, Nkondog Anselme Venceslas |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2021, Nkondog Anselme Venceslas"
|
|
#property link "https://www.mql5.com"
|
|
// Next line assumes this file is located in .../Frameworks/Extensions/someFolder
|
|
#include "../../GridFramework.mqh"
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
class CSignalGrid : public CSignalBase
|
|
{
|
|
|
|
private:
|
|
|
|
protected: // member variables
|
|
|
|
// Place any required member variables here
|
|
int m_magic;
|
|
double lastBuyOrderPrice;
|
|
double lastSellOrderPrice;
|
|
double openedBuyPositionPrice;
|
|
double openedSellPositionPrice;
|
|
|
|
public: // constructors
|
|
|
|
// Add any required constructor arguments
|
|
// e.g. CSignalXYZ(int periods, double multiplier)
|
|
CSignalGrid()
|
|
: CSignalBase()
|
|
{ Init(); }
|
|
// Same constructor with symbol and timeframe added
|
|
CSignalGrid(string symbol, ENUM_TIMEFRAMES timeframe)
|
|
: CSignalBase(symbol, timeframe)
|
|
{ Init(); }
|
|
~CSignalGrid() { }
|
|
|
|
// Include all arguments to match the constructor
|
|
int Init();
|
|
|
|
public:
|
|
|
|
// Add this line to override the same function from the parent class
|
|
virtual void UpdateSignal();
|
|
|
|
virtual void setMmagic(int magic) {m_magic = magic;}
|
|
|
|
virtual double getLastBuyOrderPrice() {return lastBuyOrderPrice;}
|
|
virtual double getLastSellOrderPrice() {return lastSellOrderPrice;}
|
|
virtual double getOpenedBuyPositionPrice() {return openedBuyPositionPrice;}
|
|
virtual double getOpenedSellPositionPrice() {return openedSellPositionPrice;}
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
int CSignalGrid::Init()
|
|
{
|
|
|
|
// Checks if init has been set to fail by any parent class already
|
|
if(InitResult()!=INIT_SUCCEEDED)
|
|
return(InitResult());
|
|
|
|
// Assign variables and do any other initialisation here
|
|
|
|
return(INIT_SUCCEEDED);
|
|
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
void CSignalGrid::UpdateSignal()
|
|
{
|
|
|
|
// Just gather data from the indicators and
|
|
// decide on a trade direction
|
|
// This is the trade decision logic
|
|
//CSignalBase signal = new CSignalBase();
|
|
|
|
// Check the account balance equity for profit
|
|
int pCountBuy = 0, pCountSell = 0, oCountBuy = 0, oCountSell = 0, totalBuy = 0, totalSell = 0, realTotalBuy = 0, realTotalSell = 0;
|
|
int realOCountBuy = 0, realOCountSell = 0;
|
|
ulong ticket;
|
|
|
|
SetSignal(OFX_ENTRY_SIGNAL, OFX_SIGNAL_NONE);
|
|
|
|
//If there're many positions and account balance is negative
|
|
|
|
if(PositionsTotal() > 0)
|
|
{
|
|
//Count the opened positions by type
|
|
int cntP = PositionsTotal();
|
|
for(int i = cntP-1; i>=0; i--)
|
|
{
|
|
ticket = PositionGetTicket(i);
|
|
if(PositionSelectByTicket(ticket))
|
|
{
|
|
if(PositionGetString(POSITION_SYMBOL)==mSymbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY
|
|
&& PositionGetInteger(POSITION_MAGIC)==m_magic)
|
|
{
|
|
openedBuyPositionPrice = PositionGetDouble(POSITION_PRICE_OPEN);
|
|
pCountBuy += 1;
|
|
}
|
|
|
|
if(PositionGetString(POSITION_SYMBOL)==mSymbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL
|
|
&& PositionGetInteger(POSITION_MAGIC)==m_magic)
|
|
{
|
|
openedSellPositionPrice = PositionGetDouble(POSITION_PRICE_OPEN);
|
|
pCountSell += 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Print(GetLastError());
|
|
}
|
|
}
|
|
}
|
|
//Count the orders by type
|
|
|
|
int cntO = OrdersTotal();
|
|
|
|
for(int i = cntO-1; i>=0; i--)
|
|
{
|
|
|
|
ticket = OrderGetTicket(i);
|
|
if(OrderSelect(ticket))
|
|
{
|
|
if(OrderGetString(ORDER_SYMBOL)==mSymbol && OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP
|
|
&& OrderGetInteger(ORDER_MAGIC)==m_magic)
|
|
{
|
|
oCountBuy += 1;
|
|
lastBuyOrderPrice = OrderGetDouble(ORDER_PRICE_OPEN);
|
|
}
|
|
|
|
Print("ORDER_SYMBOL ", OrderGetString(ORDER_SYMBOL), " Real symbol ", mSymbol, " ORDER_TYPE ", OrderGetInteger(ORDER_TYPE), " Real type ", ORDER_TYPE_SELL_STOP, " Magic ", OrderGetInteger(ORDER_MAGIC), " Real magic ", m_magic);
|
|
if(OrderGetString(ORDER_SYMBOL)==mSymbol && OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_STOP
|
|
&& OrderGetInteger(ORDER_MAGIC)==m_magic)
|
|
{
|
|
oCountSell += 1;
|
|
lastSellOrderPrice = OrderGetDouble(ORDER_PRICE_OPEN);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Print("Last error code ", GetLastError());
|
|
}
|
|
}
|
|
|
|
double floatingProfitPercent = ((AccountInfoDouble(ACCOUNT_EQUITY) - AccountInfoDouble(ACCOUNT_BALANCE))*100)/AccountInfoDouble(ACCOUNT_BALANCE);
|
|
// Check if profit is at least the mMaxRiskPerTrade
|
|
|
|
//The number of buy pending order should be twice the opened sell positions; and vice versa
|
|
realOCountBuy = pCountSell+1;
|
|
realOCountSell = pCountBuy+1;
|
|
totalBuy = pCountBuy+oCountBuy;
|
|
totalSell = pCountSell+oCountSell;
|
|
realTotalBuy = pCountSell+1;
|
|
realTotalSell = pCountBuy+1;
|
|
|
|
Print("Signal conditions ........................................................................");
|
|
|
|
if(OrdersTotal() == 0 && PositionsTotal() == 0)
|
|
{
|
|
SetSignal(OFX_ENTRY_SIGNAL, OFX_SIGNAL_BOTH);
|
|
Print("1 - Open both position");
|
|
}
|
|
else
|
|
{
|
|
//If there's only one pending order left, close it.
|
|
if(OrdersTotal() >= 1 && PositionsTotal() == 0)
|
|
{
|
|
SetSignal(OFX_EXIT_SIGNAL, OFX_SIGNAL_ALL);
|
|
Print("2 - Exit if no opened position");
|
|
}
|
|
else
|
|
{
|
|
//When there are multiple positions, check is the account is making enough profit
|
|
if(floatingProfitPercent > mMaxRiskPerTrade)
|
|
{
|
|
SetSignal(OFX_EXIT_SIGNAL, OFX_SIGNAL_ALL);
|
|
Print("3 - Exit on profit target");
|
|
}
|
|
else
|
|
{
|
|
Print("realTotalSell ", realTotalSell, " > ", " totalSell ", totalSell," && ", " pCountBuy ",pCountBuy," > 0");
|
|
if(realTotalSell > totalSell && pCountBuy > 0)
|
|
{
|
|
SetSignal(OFX_ENTRY_SIGNAL, OFX_SIGNAL_SELL);
|
|
Print("4 - Sell order (", oCountSell, ") is less than it should be (", realOCountSell, ")");
|
|
}
|
|
else
|
|
{
|
|
if(realTotalBuy > totalBuy && pCountSell > 0)
|
|
{
|
|
SetSignal(OFX_ENTRY_SIGNAL, OFX_SIGNAL_BUY);
|
|
//mEntrySignals[0].SetSignal(OFX_ENTRY_SIGNAL, OFX_SIGNAL_BUY);
|
|
Print("5 - Buy order (", oCountBuy, ") is less than it should be (", realOCountBuy, ")");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
//+------------------------------------------------------------------+
|