306 lines
20 KiB
MQL5
306 lines
20 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| ProjectName |
|
|
//| Copyright 2020, CompanyName |
|
|
//| http://www.companyname.net |
|
|
//+------------------------------------------------------------------+
|
|
#include <Trade\Trade.mqh>
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
class Strategy
|
|
{
|
|
protected:
|
|
CTrade trade;
|
|
|
|
int pos;
|
|
|
|
string symbol, comm;
|
|
|
|
ENUM_POSITION_TYPE type;
|
|
|
|
double position_price, border, lastPrice, position_size, TakeProfit, StopLoss, DrawDown, PNL, Start;
|
|
|
|
datetime timeLast;
|
|
|
|
public:
|
|
ulong ID[];
|
|
|
|
void Updater(string INDEX, string comment, int arrSize)
|
|
{
|
|
if(PositionsTotal() != pos || PositionsTotal() > 0)
|
|
{
|
|
ulong copyID[];
|
|
for(int i=PositionsTotal() ; i>=0; i--)
|
|
{
|
|
ulong marker = PositionGetTicket(i);
|
|
PositionSelectByTicket(marker);
|
|
string var = PositionGetString(POSITION_COMMENT);
|
|
string sym = PositionGetString(POSITION_SYMBOL);
|
|
int conditionComment = StringCompare(var, comment, false);
|
|
int conditionSymbol = StringCompare(sym, INDEX, false);
|
|
if(conditionComment == 0 && conditionSymbol == 0)
|
|
{
|
|
if(arrSize == 0)
|
|
{
|
|
arrSize = arrSize + 1;
|
|
ArrayResize(ID, arrSize, 0);
|
|
ID[arrSize-1] = marker;
|
|
}
|
|
else
|
|
{
|
|
ArraySort(ID);
|
|
int search = ArrayBsearch(ID, marker);
|
|
if(ID[search] != marker)
|
|
{
|
|
arrSize = arrSize + 1;
|
|
ArrayResize(ID, arrSize, 0);
|
|
ID[arrSize-1] = marker;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ArrayCopy(copyID, ID, 0, 0, WHOLE_ARRAY);
|
|
for(int i=0; i<ArraySize(ID); i++)
|
|
{
|
|
ulong ticket = ID[i];
|
|
for(int y=PositionsTotal() ; y>=0; y--)
|
|
{
|
|
ulong tickettmp = PositionGetTicket(y);
|
|
if(ticket == tickettmp)
|
|
{
|
|
copyID[i] = 0;
|
|
}
|
|
}
|
|
}
|
|
ArraySort(copyID);
|
|
ArrayReverse(copyID, 0, WHOLE_ARRAY);
|
|
|
|
for(int i=0; i<ArraySize(copyID); i++)
|
|
{
|
|
if(copyID[i] == 0)
|
|
{
|
|
ArrayRemove(copyID, i, WHOLE_ARRAY);
|
|
}
|
|
}
|
|
|
|
if(ArraySize(copyID) > 0)
|
|
{
|
|
ArraySort(copyID);
|
|
for(int i=0; i<ArraySize(copyID); i++)
|
|
{
|
|
for(int y=0; y<ArraySize(ID); y++)
|
|
{
|
|
if(copyID[i] == ID[y])
|
|
{
|
|
ID[y] = 0;
|
|
}
|
|
}
|
|
}
|
|
ArraySort(ID);
|
|
ArrayReverse(ID);
|
|
for(int i=0; i<ArraySize(ID); i++)
|
|
{
|
|
if(ID[i] == 0)
|
|
{
|
|
ArrayRemove(ID, i, WHOLE_ARRAY);
|
|
}
|
|
}
|
|
ArrayFree(copyID);
|
|
}
|
|
|
|
ArraySort(ID);
|
|
for(int i=0; i<ArraySize(ID); i++)
|
|
{
|
|
PositionSelectByTicket(ID[i]);
|
|
if(i == 0)
|
|
{
|
|
timeLast = (datetime)PositionGetInteger(POSITION_TIME);
|
|
symbol = INDEX;
|
|
comm = comment;
|
|
type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
|
|
position_price = PositionGetDouble(POSITION_PRICE_OPEN)*PositionGetDouble(POSITION_VOLUME);
|
|
position_size = PositionGetDouble(POSITION_VOLUME);
|
|
PNL = PositionGetDouble(POSITION_PROFIT);
|
|
lastPrice = PositionGetDouble(POSITION_PRICE_OPEN);
|
|
if(type == POSITION_TYPE_BUY)
|
|
{
|
|
//Изза НУЛа при 0 позиций, может быть баг с первым входом, если проводится проверка по бордеру
|
|
border = PositionGetDouble(POSITION_PRICE_OPEN)*(1 - 0.005);//trend "+"
|
|
}
|
|
else
|
|
{
|
|
border = PositionGetDouble(POSITION_PRICE_OPEN)*(1 + 0.005);//trend "-"
|
|
}
|
|
}
|
|
if(i > 0)
|
|
{
|
|
timeLast = (datetime)PositionGetInteger(POSITION_TIME);
|
|
position_price = position_price + PositionGetDouble(POSITION_PRICE_OPEN)*PositionGetDouble(POSITION_VOLUME);
|
|
position_size = TotalSize() + PositionGetDouble(POSITION_VOLUME);
|
|
PNL = getPNL() + PositionGetDouble(POSITION_PROFIT);
|
|
border = 2*PositionGetDouble(POSITION_PRICE_OPEN) - lastPrice;
|
|
lastPrice = PositionGetDouble(POSITION_PRICE_OPEN);
|
|
}
|
|
}
|
|
if(TotalSize() > 0)
|
|
{
|
|
position_price = NormalizeDouble(position_price/TotalSize(), _Digits);
|
|
}
|
|
|
|
pos = PositionsTotal();
|
|
if(ArraySize(ID) > 0)
|
|
{
|
|
Print(INDEX, " ==> ", (PosType() == 0 ? "BUY ==> " : "SELL ==> "), comment, " ==> ", TotalSize(), " ==> ", getPNL(), " (((Average Price: ", AvgPrice(), " Last Price: ", LastPrice(), " Border: ", Border(), " SL: ", (getSL() > 0 ? DoubleToString(getSL()) : ""),")))");
|
|
ArrayPrint(ID);
|
|
}
|
|
}
|
|
}
|
|
|
|
void StrategyClear()
|
|
{
|
|
Print("Closing ", symbol, " side ", comm, " profit ", PNL);
|
|
while(ArraySize(ID) > 0)
|
|
{
|
|
for(int i=PositionsTotal() ; i>=0; i--)
|
|
{
|
|
ulong marker = PositionGetTicket(i);
|
|
PositionSelectByTicket(marker);
|
|
string var = PositionGetString(POSITION_COMMENT);
|
|
string sym = PositionGetString(POSITION_SYMBOL);
|
|
int conditionComment = StringCompare(var, comm, false);
|
|
int conditionSymbol = StringCompare(sym, symbol, false);
|
|
if(conditionComment == 0 && conditionSymbol == 0)
|
|
{
|
|
trade.PositionClose(marker);
|
|
}
|
|
}
|
|
timeLast = NULL;
|
|
symbol = NULL;
|
|
comm = NULL;
|
|
type = NULL;
|
|
position_price = NULL;
|
|
position_size = 0;
|
|
border = NULL;
|
|
lastPrice = NULL;
|
|
TakeProfit= NULL;
|
|
StopLoss= NULL;
|
|
Start= NULL;
|
|
PNL= NULL;
|
|
ArrayFree(ID);
|
|
}
|
|
|
|
if(ArraySize(ID) == 0)
|
|
{
|
|
Print("Success");
|
|
}
|
|
else
|
|
{
|
|
Print("Failed to Close ", symbol, " Position ", comm);
|
|
StrategyClear();
|
|
}
|
|
}
|
|
|
|
void StrategyClosePosition()
|
|
{
|
|
if(ArraySize(ID) > 0)
|
|
{
|
|
Print("Closing ", symbol, " Position ", comm);
|
|
int posNumber = ArraySize(ID) - 1;
|
|
ulong marker = ID[posNumber];
|
|
trade.PositionClose(marker);
|
|
}
|
|
|
|
if(ArraySize(ID) == 0)
|
|
{
|
|
Print("Array Is Clear");
|
|
}
|
|
}
|
|
|
|
|
|
void StrategyReset()
|
|
{
|
|
timeLast = NULL;
|
|
pos = NULL;
|
|
symbol = NULL;
|
|
comm = NULL;
|
|
type = NULL;
|
|
position_price = NULL;
|
|
position_size = 0;
|
|
border = NULL;
|
|
lastPrice = NULL;
|
|
TakeProfit= NULL;
|
|
StopLoss= NULL;
|
|
Start= NULL;
|
|
PNL= NULL;
|
|
ArrayFree(ID);
|
|
}
|
|
|
|
void setStart(double price)
|
|
{
|
|
Start = price;
|
|
}
|
|
|
|
//void setPNL(double price)
|
|
// {
|
|
// if(getPNL() > 0)
|
|
// {
|
|
// PNL = getPNL() + price;
|
|
// }
|
|
// else
|
|
// {
|
|
// PNL = price;
|
|
// }
|
|
// }
|
|
|
|
void setTP(double price)
|
|
{
|
|
if(PosType() == POSITION_TYPE_BUY)
|
|
{
|
|
TakeProfit = 1 + price;
|
|
}
|
|
if(PosType() == POSITION_TYPE_SELL)
|
|
{
|
|
TakeProfit = 1 - price;
|
|
}
|
|
|
|
}
|
|
|
|
void setSL(double price)
|
|
{
|
|
StopLoss = price;
|
|
}
|
|
|
|
void Drawdown(double price)
|
|
{
|
|
if(PosType() == POSITION_TYPE_BUY && price < AvgPrice())
|
|
{
|
|
DrawDown = (AvgPrice() - price)*TotalSize();
|
|
}
|
|
else
|
|
if(PosType() == POSITION_TYPE_SELL && price > AvgPrice())
|
|
{
|
|
DrawDown = (price - AvgPrice())*TotalSize();
|
|
}
|
|
else
|
|
{
|
|
DrawDown = 0;
|
|
}
|
|
}
|
|
|
|
datetime getTime() {return(timeLast);}
|
|
double getTP() {return(TakeProfit);}
|
|
double getSL() {return(StopLoss);}
|
|
double getStart() {return(Start);}
|
|
double getDrawDown() {return(DrawDown);}
|
|
double getPNL() {return(PNL);}
|
|
ENUM_POSITION_TYPE PosType() {return(type);}
|
|
string Pair() {return(symbol);}
|
|
double AvgPrice() {return(position_price);}
|
|
double TotalSize() {return(position_size);}
|
|
double Border() {return(border);}
|
|
double LastPrice() {return(lastPrice);}
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//+------------------------------------------------------------------+
|