Отражение прибыли и убытки

Во многих торговых стратегиях существуют правила, которые не позволяют открывать новые сделки в случае, если есть хоть одна из них находится без установленного уровня StopLoss. Также часто встречаются торговые системы, в которых открытие новых сделок невозможно до тех пор, пока есть хотя бы одна открытая сделка, по стоп-ордеру которой может быть получен убыток. Т.е. пока «стопы» или отсутствуют, или находятся в отрицательной зоне по конкретным, или по всем сделкам суммарно.

Оценить подобное развитие событий (величина прибыли/убытка, которая будет получена в случае закрытия сделок по ценам StopLoss) не представляется сложным в случае, если число открытых сделок относительно невелико. В случае большого числа открытых сделок подобный учёт является ощутимой проблемой. Вполне разумно переложить подсчёт данной величины на плечи бездушных машин, в нашем случае — на MQL-робота.

Ниже представлены два варианта функции, которая позволяют решить данную задачу.

Вариант функции для торговых роботов

Первый вариант функции рассчитан на использование в торговых роботах. Функция возвращает double значение. Оно показывает суммарную величину прибыли/убытка, которая будет получена в случае закрытия всех сделок по текущим уровням StopLoss. В случае если есть хотя бы одна сделка с незаданным уровнем StopLoss, функция возвращает значение —1.1111. Функция имеет два входных параметра: magic (магическое число; 0 — обработка ордеров с любым магическим числом) и symbol (символ; NONE — обработка ордеров любых символов).

Код функции:

double profit_from_sl(int magic, string symbol) {
/* Возвращает величину прибыли, которая будет получена в случае, если сделки закроются по текущим уровням StopLoss. Если есть хоть один ордер с невыставленным стопом, возвращает -1.1111
magic — магическое число (0 — обработка сделок с любым MagicNumber)
symbol — символ (NONE — обработка всех символов)  */
int    i  = 0,
r_digits = 0;
double profit   = 0.0;

for(i=OrdersTotal()-1; i>=0; i—) {
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) break;
if(OrderStopLoss()==0) // если есть сделка с не заданным уровнем SL, вовзращаем -1.1111
{ return(-1.1111);
break;
} //end

if(OrderStopLoss()==0)
if(((OrderMagicNumber()==magic)||(magic==0)) && ((OrderSymbol()==symbol)||(symbol==»NONE»))) {
r_digits  = MarketInfo(OrderSymbol(),MODE_DIGITS);
if(OrderType()==OP_SELL)
profit += (NormalizeDouble((OrderOpenPrice()-OrderStopLoss()),r_digits)
/
MarketInfo(OrderSymbol(),MODE_POINT)*OrderLots())*MarketInfo(OrderSymbol(),MODE_TICKVALUE)
+
OrderSwap();

if(OrderType()==OP_BUY)
profit += (NormalizeDouble((OrderStopLoss()-OrderOpenPrice()),r_digits)
/
MarketInfo(OrderSymbol(),MODE_POINT)*OrderLots())*MarketInfo(OrderSymbol(),MODE_TICKVALUE)
+
OrderSwap();  } //end
if(((OrderMagicNumber()==magic)||(magic==0)) && ((OrderSymbol()==symbol)||(symbol==»NONE»)))  } //end
for(i=OrdersTotal()-1; i>=0; i—)

return(NormalizeDouble(profit,2)); } //end
profit_from_sl(int magic, string symbol)

Таким образом, значения, которые получаются на выходе, можно использовать в торговых роботах для анализа величины прибыли/убытка, которые будут получены при закрытии сделок по текущим уровням StopLoss.

Функция для визуального отображения прибыли/убытка при текущих стоп-ордерах

Второй вариант функции рассчитан на визуальное отображение величин прибыли/убытка, которые будут получены по текущим стоп-ордерам. Функция возвращает значение string: развернутый или краткий комментарий. Она имеет три входных параметра: magic (магическое число; 0 — обработка ордеров с любым магическим числом), symbol (символ; NONE — обработка ордеров любых символов) и mode (режим вывода: 1 — краткий, 2 — полный).

Код функции:

string profit_from_sl(int magic, string symbol, int mode)
{
/*     Возвращает величину прибыли/убытка, которая будет получена в случае, если сделки закроются по текущим уровням StopLoss.
magic — магическое число (0 — обработка сделок с любым MagicNumber);
symbol — символ (NONE -обработка всех символов);
mode — (режим вывода: 1 — краткий, 2 — полный). */
int i  = 0,
r_digits = 0;
double profit = 0.0,
profit_this = 0.0;
string text = «»,
text_full = «»;

for(i=OrdersTotal()-1; i>=0; i—)
{
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
if(OrderStopLoss()==0) // если найдена хотя бы одна сделка без стоп-ордера, то оценить прибыль/убыток невозможно.
{
text=»величина прибыли/убытка не может быть определена, т.к. Stop Loss по »
+OrderSymbol()+» (тикет: «+OrderTicket()+») не установлен»;
text_full=text;
break;  } //end

if(OrderStopLoss()==0)
if(((OrderMagicNumber()==magic)||(magic==0)) && ((OrderSymbol()==symbol)||(symbol==»NONE»)))
{
r_digits  = MarketInfo(OrderSymbol(),MODE_DIGITS);
if(OrderType()==OP_SELL)
profit_this = (NormalizeDouble((OrderOpenPrice()-OrderStopLoss()),r_digits)
/
MarketInfo(OrderSymbol(),MODE_POINT)*OrderLots())*MarketInfo(OrderSymbol(),MODE_TICKVALUE)
+
OrderSwap();

if(OrderType()==OP_BUY)
profit_this = (NormalizeDouble((OrderStopLoss()-OrderOpenPrice()),r_digits)
/
MarketInfo(OrderSymbol(),MODE_POINT)*OrderLots())*MarketInfo(OrderSymbol(),MODE_TICKVALUE)
+
OrderSwap();

text_full=text_full+»\n»+»Прибыль(убыток) по «+OrderSymbol()+» (тикет: «+OrderTicket()+») составит »
+DoubleToStr(profit_this,2);
profit += profit_this; } //end

if(((OrderMagicNumber()==magic)||(magic==0)) && ((OrderSymbol()==symbol)||(symbol==»NONE»)))
} //end

for(i=OrdersTotal()-1; i>=0; i—)
if(text==»») text=»Суммарная прибыль/убыток составит»+DoubleToStr(profit,2);
/* if(profit!=profit_this) */
text_full = text_full+»\n»+»Суммарная прибыль/убыток составит «+DoubleToStr(profit,2);
if(mode==1) return(text);
if(mode==2) return(text_full); } //end

string profit_from_sl(int magic, string symbol, int mode)

Простейшее применение второй функции сводится к выводу результата её работы в Comment();.Это будет выглядеть приблизительно так:

int init()
{  return(0); } //end

int init()
int deinit()
{  return(0); } //end

int deinit()
string profit_from_sl(int magic, string symbol, int mode)
{
/*     Возвращает величину прибыли/убытка, которая будет получена в случае, если сделки закроются по текущим уровням StopLoss.
magic — магическое число (0 — обработка сделок с любым MagicNumber);
symbol — символ (NONE -обработка всех символов);
mode — (режим вывода: 1 — краткий, 2 — полный).  */
int i = 0,
r_digits = 0;
double profit = 0.0,
profit_this = 0.0;
string text = «»,
text_full = «»;

for(i=OrdersTotal()-1; i>=0; i—)
{
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
if(OrderStopLoss()==0) //если найдена хотя бы одна сделка без стоп-ордера, то оценить прибыль/убыток невозможно.
{
text=»величина прибыли(убытка) не может быть определена, т.к. Stop Loss по »
+OrderSymbol()+» (тикет: «+OrderTicket()+») не установлен»;
text_full=text;
break;
} //end

if(OrderStopLoss()==0)
if(((OrderMagicNumber()==magic)||(magic==0)) && ((OrderSymbol()==symbol)||(symbol==»NONE»))) {
r_digits  = MarketInfo(OrderSymbol(),MODE_DIGITS);

if(OrderType()==OP_SELL)
profit_this = (NormalizeDouble((OrderOpenPrice()-OrderStopLoss()),r_digits)
/
MarketInfo(OrderSymbol(),MODE_POINT)*OrderLots())*MarketInfo(OrderSymbol(),MODE_TICKVALUE)
+
OrderSwap();

if(OrderType()==OP_BUY)
profit_this = (NormalizeDouble((OrderStopLoss()-OrderOpenPrice()),r_digits)
/
MarketInfo(OrderSymbol(),MODE_POINT)*OrderLots())*MarketInfo(OrderSymbol(),MODE_TICKVALUE)
+
OrderSwap();
text_full=text_full+»\n»+»Прибыль/убыток по «+OrderSymbol()+» (тикет: «+OrderTicket()+») составит »
+DoubleToStr(profit_this,2);
profit += profit_this;
} //end

if(((OrderMagicNumber()==magic)||(magic==0)) && ((OrderSymbol()==symbol)||(symbol==»NONE»)))
} //end

for(i=OrdersTotal()-1; i>=0; i—)
if(text==»») text=»Суммарная прибыль(убыток) составит»+DoubleToStr(profit,2);
/*if(profit!=profit_this) */
text_full = text_full+»\n»+»Суммарная прибыль(убыток) составит «+DoubleToStr(profit,2);
if(mode==1) return(text);
if(mode==2) return(text_full);
} //end

string profit_from_sl(int magic, string symbol, int mode)
int start() {
Comment(profit_from_sl(0,»NONE»,2));
return(0);
} //end

int start()
//+——————————————————————+

Безусловно, данная функция является лишь общим случаем реализации поставленной задачи. В реальных условиях может возникнуть потребность в несколько иной оценке уровней StopLoss у открытых сделок. Данные коды можно взять за основу решений необходимых задач.

Добавить комментарий

Кнопка возврата к началу