Уровень безубытка цены для множества ордеров - страница 4

 

Расчёт уровня БУ для множества по одному инструменту:

сумма лотов = суммарная позиция (СП)

стоимость тика СП = СТ

профит СП = ПСП

Формула расчёта довольно проста:

КП = ПСП / (СТ * СП)

В которой узнаём количество пипс (КП) до уровня БУ относительно текущей цены (ТЦ) символа.

И подставив КП в формулу БУ = ТЦ - КП * Point получаем уровень цены БУ.

В зависимости от направления СП выбирается прибавлять либо отнимать от ТЦ.


// Уровень безубытка по символу
double LevelBU(){ double lbu=0, lbP=0, lbM=0;
int spr=MarketInfo(Symbol(),MODE_SPREAD);
lbP=Bid+(MathAbs(SimProfit())/(MarketInfo(Symbol(),MODE_TICKVALUE)*MathAbs(SumLot())))*Point;
lbM=Ask-(MathAbs(SimProfit())/(MarketInfo(Symbol(),MODE_TICKVALUE)*MathAbs(SumLot()))-spr)*Point;
lbu=lbP; if(SumLot()<0) lbu=lbM;
return(lbu);}

// === Сопутствующие функции ===
//--- Суммарный лот по символу
double SumLot(){
double buy=0, sell=0, sl; int y;
for(y=0;y<OrdersTotal();y++)
   {
   OrderSelect(y,SELECT_BY_POS,MODE_TRADES);
   if(OrderSymbol()==Symbol() && OrderType()==0) buy+=OrderLots();
   if(OrderSymbol()==Symbol() && OrderType()==1) sell+=OrderLots();
   }
sl=buy-sell; if(sl==0) sl=0.00000001;
return(sl);}
//--- Профит по символу
double SimProfit() {double sp=0; int i;
for(i=0; i<OrdersTotal(); i++) {
OrderSelect(i,SELECT_BY_POS,MODE_TRADES);
if(OrderSymbol()==Symbol())
{ if(OrderType()==0 || OrderType()==1)
sp+=(OrderProfit()+OrderCommission()+OrderSwap());}}
return(sp);}

Реализация пока на стадии разработки поэтому прошу не пинать...

Существенный недостаток: при отсутствии позиций либо ЛОКе

начинается громкая ругань что зеро девайс (деление на ноль)

ввиду возврата SumLot() нуля и формула КП = ПСП / (СТ * СП) получается КП = ПСП / (СТ * 0)

т.е ПСП / 0

Обманка ввиде подстановы некого минизначения лота... можно, но как-то это неправильно...

 
forte928 писал(а) >>

Вот моя реализация стоимости одного пункта

Сейчас использую другую функцию. Во всех индикаторах эквити стоИт именно она:

//+----------------------------------------------------------------------------+
//|  Определение размера контракта в валюте депозита                           |
//+----------------------------------------------------------------------------+
double LotSize(string symbol, datetime tbar)
{
double size;
string BQ,currency=AccountCurrency();
switch (MarketInfo(symbol,MODE_PROFITCALCMODE))
{
  case 0:
  {
   int sbar=iBarShift(symbol,0,tbar);
   size=MarketInfo(symbol,MODE_LOTSIZE);
   if (StringSubstr(symbol,3,3)=="USD") break;
   if (StringSubstr(symbol,0,3)=="USD") size=size/iClose(symbol,0,sbar);
   else
   {
    BQ=StringSubstr(symbol,0,3)+"USD";
    if (iClose(BQ,0,0)==0) BQ="USD"+StringSubstr(symbol,0,3);
    if (iClose(BQ,0,0)==0) break;
    int BQbar=iBarShift(BQ,0,tbar);
    if (StringSubstr(BQ,0,3)=="USD") size=size/iClose(BQ,0,BQbar)/iClose(symbol,0,sbar);
    else size=size*iClose(BQ,0,BQbar)/iClose(symbol,0,sbar);
   }
  } break;
  case 1: size=MarketInfo(symbol,MODE_LOTSIZE); break;
  case 2: size=MarketInfo(symbol,MODE_TICKVALUE)/MarketInfo(symbol,MODE_TICKSIZE);
}
if (currency!="USD")
{
  BQ=currency+"USD";
  if (iClose(BQ,0,0)==0)
  {
   BQ="USD"+currency;
   size*=iClose(BQ,0,iBarShift(BQ,0,tbar));
  }
  else size/=iClose(BQ,0,iBarShift(BQ,0,tbar));
}
return(size);
}

Соответсвенно чтобы найти стоимость одного пунтка нужно:

double Lot=1.0;
double tickvalue=Point*Lot*LotSize(Symbol(),Time[0]);

Сомневаюсь, что Ваша функция будет работать, если депозит в рублях к примеру.

Насчёт ролловера - не заморачивался на эту тему, т.к. нет необходимости.

 
Valery V. Chesnokov:

Прошу уважаемых форумчан подсказать, писал ли кто-нибудь MQL код, рассчитывающий для произвольного множества ордеров одного типа (только BUY, или только SELL), с разной ценой открытия и разными лотами, уровень безубыточной цены, т.е. такой уровень, закрытие на котором ордеров заданного множества приведёт к нулевому изменению баланса?

Опираться нужно, как я понимаю, на OrderProfit, OrderCommission, OrderSwap(), но они дадут по формуле: NormalizeDouble( OrderProfit() + OrderCommission() + OrderSwap(), 2);
общий текущий профит со знаком для каждого ордера, для текущей цены, а как получить уровень безубытка для всего множества?

((ЦБ1 * ЛБ1 + ЦБ2 * ЛБ2 + ... + ЦБi * ЛБi) - (ЦС1 * ЛС1 + ЦС2 * ЛС2 + ... + ЦСi * ЛБi)) / (ЛБ1 + ЛБ2 + ... + ЛБi) - (ЛС1 + ЛС2 + ... + ЛСi) , где ЦБi - цена открытия i-го длинного ордера, ЛБi - лот открытия i-го длинного ордера, ЦСi и ЛСi - соответственно i-го короткого ордера.

Важно помнить два момента:

1. При нахождении точки безубытка направления СЕЛЛ ниже точки безубытка направления БАЙ общий безубыток имеет место при любых ценах, т.к. это лок. Это соответствует делению на ноль в указанной формуле. Ставьте проверку перед расчётом общего безубытка.

2. Поскольку ордера по разным направлениям открываются по разным типам цен (BID и ASK), полученное значение цены является приблизительным (из-за колебаний спреда), но со вполне достаточной точностью годным для решения прикладных задач.
 
Оссильяновец:

((ЦБ1 * ЛБ1 + ЦБ2 * ЛБ2 + ... + ЦБi * ЛБi) - (ЦС1 * ЛС1 + ЦС2 * ЛС2 + ... + ЦСi * ЛБi)) / (ЛБ1 + ЛБ2 + ... + ЛБi) - (ЛС1 + ЛС2 + ... + ЛСi) , где ЦБi - цена открытия i-го длинного ордера, ЛБi - лот открытия i-го длинного ордера, ЦСi и ЛСi - соответственно i-го короткого ордера.

Важно помнить два момента:

1. При нахождении точки безубытка направления СЕЛЛ ниже точки безубытка направления БАЙ общий безубыток имеет место при любых ценах, т.к. это лок. Это соответствует делению на ноль в указанной формуле. Ставьте проверку перед расчётом общего безубытка.

2. Поскольку ордера по разным направлениям открываются по разным типам цен (BID и ASK), полученное значение цены является приблизительным (из-за колебаний спреда), но со вполне достаточной точностью годным для решения прикладных задач.
Ну да, он так и сидел ждал ответа 10 лет )))
 
Andrey Khatimlianskii:
Можно просто OrderProfit() поделить на разницу текущей цены и цены открытия позиции - получится цена пункта (правда, без учета цены в момент возможного закрытия).

Свопы расчитать тоже можно, но с одной оговоркой - в mql4 нет функции, возвращающей день начисления тройного свопа.

Кто будет развивать эту тему, теперь есть функция позволяющая получить день тройного свопа.

//+------------------------------------------------------------------+
//|                                                         test.mq4 |
//|                                                   Sergey Gritsay |
//|                         https://www.mql5.com/ru/users/sergey1294 |
//+------------------------------------------------------------------+
#property copyright "Sergey Gritsay"
#property link      "https://www.mql5.com/ru/users/sergey1294"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   ENUM_DAY_OF_WEEK day_of_week=(ENUM_DAY_OF_WEEK)SymbolInfoInteger(_Symbol,SYMBOL_SWAP_ROLLOVER3DAYS);
   Print("День тройного свопа :",EnumToString(day_of_week));
  }
//+------------------------------------------------------------------+
 
Оссильяновец  а вы можите реализовать эту формулу уже готовым кодом. ?
Оссильяновец
Оссильяновец
  • www.mql5.com
Профиль трейдера
 
Vitalie Postolache:
Ну да, он так и сидел ждал ответа 10 лет )))

А вариант то все равно не верный ведь тут свопы и комиссия не учтены!

 
double tickValue=0, ordersProfit=0, ordersLots=0;

for(int cnt=0; cnt<OrdersTotal(); cnt++)
{
     // .......
     ordersProfit += OrderProfit() + OrderSwap() + OrderCommission();
     ordersLots += OrderLots();
}

SymbolInfoDouble(Symbol(), SYMBOL_TRADE_TICK_VALUE, tickValue);
int pipsProfit = (int)MathFloor( ordersProfit / (tickValue*ordersLots) );

Конечно все обрезано, но думаю смысл виден. Получаем сколько pips/пунктов составляет прибыль.

 
Konstantin Nikitin:

Конечно все обрезано, но думаю смысл виден. Получаем сколько pips/пунктов составляет прибыль.

посмотрите на инструментах, где 

tickValue

будет меньше единицы, например 0.01. Сильно удивитесь.

 
kombat #:

Расчёт уровня БУ для множества по одному инструменту:

// =-=================

Реализация пока на стадии разработки поэтому прошу не пинать...

Существенный недостаток: при отсутствии позиций либо ЛОКе

начинается громкая ругань что зеро девайс (деление на ноль)

ввиду возврата SumLot() нуля и формула КП = ПСП / (СТ * СП) получается КП = ПСП / (СТ * 0)

т.е ПСП / 0

Обманка ввиде подстановы некого минизначения лота... можно, но как-то это неправильно...

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