Как рассчитать размер комиссии брокера в пунктах? - страница 3

 
Taras Slobodyanik:

ээ... то есть вы предполагаете, но рассчитывать не пробовали?

а я не предполагаю, а беру конкретные значения:    комиссия 10, лот 0.1,  MODE_TICKVALUE...
и считаю)

...и пока всё совпадает 


Уважаемый! Пробовал рассчитывать, в том то всё и дело! Результаты расчета вверху на скриншотах, смотрите пожалуйста внимательнее.

Алгоритм расчета (скрипт) выше во вставке.

Скажите, пожалуйста, какой расчет ещё Вы хотите чтобы я сделал?

С удовольствием предоставлю! :-)

 
Yury Kirillov:

Уважаемый! Результаты расчета вверху на скриншотах, смотрите пожалуйста внимательнее.


у вас задача какая? проверить MODE_TICKVALUE ?

или рассчитать:  Как рассчитать размер комиссии брокера в пунктах? 

потому как не вижу где вы считаете комиссию и пипсы

 
Alexey Viktorov:

Юрий, всё это гораздо сложней чем на первый взгляд кажется. MODE_TICKVALUE равно как и SYMBOL_TRADE_TICK_VALUE считают стоимость одного пункта в зависимости от направления сделки, текущих котировок кросс валют и, возможно ещё от чего-то. Поэтому правильно посчитать самостоятельно я не берусь не зная всех тонкостей этих расчётов.

Соответственно ответ на

1. Зависит от направления сделки.

2. Я до такого класса не доучился и это ещё одна причина по которой правильно посчитать самостоятельно я не берусь. Не знаю...


Спасибо за ответ!

Я как раз и пытаюсь выяснить алгоритм расчета заложенный в стандартных функциях и почему он выдаёт результаты не всегда адекватные общепринятой методике таких расчетов.

 
Yury Kirillov:

Я как раз и пытаюсь выяснить алгоритм расчета заложенный в стандартных функциях и почему он выдаёт результаты не всегда адекватные общепринятой методике таких расчетов.

тогда вам нужно еще учитывать валюту депозита, если она отличается от USD
 
Taras Slobodyanik:


у вас задача какая? проверить MODE_TICKVALUE ?

или рассчитать:  Как рассчитать размер комиссии брокера в пунктах? 

потому как не вижу где вы считаете комиссию и пипсы


Taras Slobodyanik 2017.04.06 10:13     RU
Yury Kirillov:

Я как раз и пытаюсь выяснить алгоритм расчета заложенный в стандартных функциях и почему он выдаёт результаты не всегда адекватные общепринятой методике таких расчетов.

тогда вам нужно еще учитывать валюту депозита, если она отличается от USD



Да, совершенно верно, задача: Как рассчитать размер комиссии брокера в пунктах?

Для этого необходимо рассчитать стоимость одного пункта минимального изменения цены.

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

Методика реализована в приведенном выше скрипте, различия в расчетах приведены на скриншоте. Скрипт погоняйте и увидите разницу - иногда она весьма существенна (проблемные инструменты указаны выше).

Поэтому вопрос ПРАВИЛЬНОГО расчета комиссии брокера в пунктах остается. Ибо это существенно важно для определения прибыльности закрытия сделок.

С валютой депозита разберёмся позднее. Сейчас валюта депозита пусть будет USD.

Для справки: Объём сделки 1 лот. Комиссия - пока не имеет значения, ибо в расчете стоимости пункта она не участвует никаким боком.

 

Примеры расчета стоимости пункта:

Разница в 1 пункт (для BID)

Пример расчета EURCHF

Разница в 3 пункта (для BID)


Test 2

Для расчета использован скрипт:

//+------------------------------------------------------------------+
//|                                  SymbolData Tick Value Test Mini |
//|                                         KirillovYV (c) 2013-2017 |
//|                         https://www.mql5.com/ru/users/kirillovyv |
//+------------------------------------------------------------------+
#property copyright "KirillovYV (c) 2013-2017"
#property link      "https://www.mql5.com/ru/users/kirillovyv"
#property version   "1.11"
#property strict
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart(){
Comment("=============== Reference data on the instrument "+"EURCHF"+" ============================="
+"\n\n TICKVALUE (MarketInfo(_Symbol,MODE_TICKVALUE))="+DoubleToString(MarketInfo("EURCHF",MODE_TICKVALUE),_Digits)
+"\n\n TICKVALUE (SymbolInfoDouble(_Symbol(),SYMBOL_TRADE_TICK_VALUE))="+DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE),_Digits)
//+"\n\n TICKVALUE (CalcTickValue(_Symbol,Mid))="+DoubleToString(CalcTickValue("EURCHF",0),_Digits)
+"\n\n ================================== ASK ==================================="
+"\n\n SymbolInfoDouble('EURCHF',SYMBOL_ASK)="+DoubleToString(SymbolInfoDouble("EURCHF",SYMBOL_ASK),_Digits)
+"\n\n SymbolInfoDouble('EURUSD',SYMBOL_ASK)="+DoubleToString(SymbolInfoDouble("EURUSD",SYMBOL_ASK),_Digits)
+"\n\n TICKVALUE (CalcTickValue(_Symbol,Ask))="+DoubleToString(CalcTickValue("EURCHF",1),_Digits)
+"\n\n TICKVALUE = объем позиции * размер пункта * текущая котировка базовой валюты по отношению к USD / текущий курс валютной пары (кросс-курс)"
+"\n\n TICKVALUE(ASK)="+DoubleToString(SymbolInfoDouble("EURCHF",SYMBOL_TRADE_CONTRACT_SIZE),2)
                      +"*"
                      +DoubleToString(SymbolInfoDouble("EURCHF",SYMBOL_POINT),_Digits)
                      +"*"
                      +DoubleToString(SymbolInfoDouble("EURUSD",SYMBOL_ASK),_Digits)
                      +"/"
                      +DoubleToString(SymbolInfoDouble("EURCHF",SYMBOL_ASK),_Digits)
+"\n\n TICKVALUE(ASK)="+DoubleToString(SymbolInfoDouble("EURCHF",SYMBOL_TRADE_CONTRACT_SIZE)*SymbolInfoDouble("EURCHF",SYMBOL_POINT)*SymbolInfoDouble("EURUSD",SYMBOL_ASK)/SymbolInfoDouble("EURCHF",SYMBOL_ASK),_Digits)
+"\n\n ================================== BID ==================================="
+"\n\n SymbolInfoDouble('EURCHF',SYMBOL_BID)="+DoubleToString(SymbolInfoDouble("EURCHF",SYMBOL_BID),_Digits)
+"\n\n SymbolInfoDouble('EURUSD',SYMBOL_BID)="+DoubleToString(SymbolInfoDouble("EURUSD",SYMBOL_BID),_Digits)
+"\n\n TICKVALUE (CalcTickValue(_Symbol,Bid))="+DoubleToString(CalcTickValue("EURCHF",2),_Digits)
+"\n\n TICKVALUE = объем позиции * размер пункта * текущая котировка базовой валюты по отношению к USD / текущий курс валютной пары (кросс-курс)"
+"\n\n TICKVALUE(BID)="+DoubleToString(SymbolInfoDouble("EURCHF",SYMBOL_TRADE_CONTRACT_SIZE),2)
                      +"*"
                      +DoubleToString(SymbolInfoDouble("EURCHF",SYMBOL_POINT),_Digits)
                      +"*"
                      +DoubleToString(SymbolInfoDouble("EURUSD",SYMBOL_BID),_Digits)
                      +"/"
                      +DoubleToString(SymbolInfoDouble("EURCHF",SYMBOL_BID),_Digits)
+"\n\n TICKVALUE(BID)="+DoubleToString(SymbolInfoDouble("EURCHF",SYMBOL_TRADE_CONTRACT_SIZE)*SymbolInfoDouble("EURCHF",SYMBOL_POINT)*SymbolInfoDouble("EURUSD",SYMBOL_BID)/SymbolInfoDouble("EURCHF",SYMBOL_BID),_Digits)
+"\n\n ======================================================================="
);
//Comment("=============== Reference data on the instrument "+_Symbol+" ============================="
//+"\n\n TICKVALUE (MarketInfo(_Symbol,MODE_TICKVALUE))="+DoubleToString(MarketInfo(_Symbol,MODE_TICKVALUE),_Digits)
//+"\n\n TICKVALUE (SymbolInfoDouble(_Symbol(),SYMBOL_TRADE_TICK_VALUE))="+DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE),_Digits)
//+"\n\n TICKVALUE (CalcTickValue(_Symbol,Mid))="+DoubleToString(CalcTickValue(_Symbol,0),_Digits)
//+"\n\n TICKVALUE (CalcTickValue(_Symbol,Ask))="+DoubleToString(CalcTickValue(_Symbol,1),_Digits)
//+"\n\n TICKVALUE (CalcTickValue(_Symbol,Bid))="+DoubleToString(CalcTickValue(_Symbol,2),_Digits)
//+"\n\n ======================================================================="
//);
}//OnStart()
//
//======================================================================================================
//    CalcTickValue()  - вычисляет стоимость пункта для указанного инструмента
//    Вход:
//       iSymbol  -  используемый инструмент (валютная пара)
//    Выход:
//       double   -  расчетная стоимость
//======================================================================================================
double CalcTickValue(string iSymbol, int iMode){
//double CalcTickValue(string iSymbol, double iNPoint, double iLots){SYMBOL_TRADE_CONTRACT_SIZE
string
   iPairs=
      //Прямые
      "#AUD"+"%0"//AUDUSD
      "#EUR"+"%0"//EURUSD
      "#GBP"+"%0"//GBPUSD
      "#NZD"+"%0"//NZDUSD

      "#XAU"+"%0"//GBPUSD
      "#XAG"+"%0"//XAGUSD
      "#XPT"+"%0"//XPTUSD
      "#XPD"+"%0"//XPDUSD
      "#GLD"+"%0"//GLDUSD

      "#LTC"+"%0"//LTCUSD
      "#BTC"+"%0"//BTCUSD
      
      "#USOil"+"%0"//USOUSD
      "#UKOil"+"%0"//UKOUSD

      "#USD"+"%0"//
      //Обратные
      "#CAD"+"%1"//USDCAD
      "#CHF"+"%1"//USDCHF
      "#JPY"+"%1"//USDJPY
      "#NOK"+"%1"//USDNOK
      "#SEK"+"%1"//USDSEK
      "#HKD"+"%1"//USDHKD
      "#CNH"+"%1"//USDCNH
      "#MXN"+"%1"//USDMXN
      "#PLN"+"%1"//USDPLN
      "#TRY"+"%1"//USDTRY
      "#ZAR"+"%1"//USDZAR
      "#RUB"+"%1"//USDRUB
      ;
string
   BaseCurrency=StringSubstr(iSymbol,0,3),
   CotirCurrency=StringSubstr(iSymbol,3,3),
   OilCurrency=StringSubstr(iSymbol,2,3);//не доделано
double
   ContractSize=SymbolInfoDouble(iSymbol,SYMBOL_TRADE_CONTRACT_SIZE);
double
   sPoint=SymbolInfoDouble(iSymbol,SYMBOL_POINT);
//-----   
   {if(BaseCurrency=="USD")//USDZZZ - Прямая котировка, Базовая валюта доллар США, стоимость лота $ContractSize
   {
      /*Расчет стоимости пункта в прямых котировках
      В прямых котировках мы совершаем операции с долларом, а «оплачиваем» второй валютой. 
      Для примера возьмем USD/CHF. Предположим, что ее текущее значение 1.20000. Рассчитаем цену пункта для операции объемом 100 000 (1 лот) базовой валюты. 
      Исходя из текущего курса: 100 000 USD = 120 000 CHF.
      Предположим, что цена прошла в нужном нам направлении 1 пункт, и текущий курс составил 1.20001. 100 000 долларов в данном случае уже будет стоить 120 001 франков. 
      Следовательно, мы заработали 1 швейцарский франк. Теперь нужно перевести это значение в американские доллары. 
      Для этого нужно разделить прибыль на текущий курс: 1 / 1.20001 = 0,83 $. Это и есть цена одного пункта по паре USD/CHF.
      Формула расчета: Цена пункта = объем позиции * размер пункта / текущий курс
      Для разобранного выше примера по паре USD/CHF: 100 000 (объем позиции) * 0,00001 (один пункт) / 1,20001 (текущий курс) = 0,83 $.*/
      {switch(iMode)
      {
            case 0://Mid
               {
                  return(ContractSize*sPoint/((SymbolInfoDouble(iSymbol,SYMBOL_ASK)+SymbolInfoDouble(iSymbol,SYMBOL_BID))/2.0));
               }
            case 1://Ask
               {
                  return(ContractSize*sPoint/SymbolInfoDouble(iSymbol,SYMBOL_ASK));
               }
            case 2://Bid
               {
                  return(ContractSize*sPoint/SymbolInfoDouble(iSymbol,SYMBOL_BID));
               }
      }}//switch(iMode)
   }else{//if(BaseCurrency!="USD") Базовая валюта НЕ доллар США
      {if((CotirCurrency=="USD")||(OilCurrency=="Oil"))//XXXUSD или UxOil (фактически USOUSD) Обратная котировка, Валюта котировки доллар США, стоимость лота $ContractSize*PriceXXX
      {
         /*Расчет стоимости пункта в обратной котировке
         В обратных котировках 1 пункт объемом 100 000 всегда равен 1 доллару США, независимо от текущего курса.
         Для примера возьмем пару EUR/USD. Здесь доллар не является базовой валютой, и все операции производятся с евро. 
         Если курс EUR/USD 1.40000, то 100 000 EUR (объем позиции) = 140 000 USD. 
         Если цена прошла в нужном нам направлении 1 пункт, курс будет 1.40001, 100 000 EUR = 140 001 USD, доход составил 1 доллар. 
         Делить полученный результат на текущий курс не нужно, т.к. в обратной котировке стоимость пункта от него не зависит, кроме того, результат мы получили уже в долларах.
         Формула расчета: Цена пункта = объем позиции * размер пункта
         Таким образом, для пары EUR/USD из нашего примера: 100 000 * 0,00001 = 1 $*/
         {if(SymbolSelect(iSymbol,true))//попытка выбрать символ в окне MarketWatch (Обзор рынка)
         {
            return(ContractSize*sPoint);
         }else{
            return(ContractSize*sPoint);
         }}//if(SymbolSelect(iSymbol,true))
      }else{//XXXZZZ //if((CotirCurrency!="USD") Кросс-курс, Базовая валюта НЕ доллар США, Валюта котировки НЕ доллар США, стоимость лота $ContractSize*PriceXXXUSD
         //----- отладка
         //Print("{",iSymbol,"}");
         //Print("{",BaseCurrency,"}");
         //Print("{",CotirCurrency,"}");
         //Print(SymbolInfoDouble(BaseCurrency+"USD",SYMBOL_ASK));
         //Print(SymbolInfoDouble(BaseCurrency+"USD",SYMBOL_BID));
         //Print(ContractSize*(SymbolInfoDouble(BaseCurrency+"USD",SYMBOL_ASK)+SymbolInfoDouble(BaseCurrency+"USD",SYMBOL_BID))/2);
         
         /*Расчет стоимости пункта в кросс-курсах
         В кросс-курсах не присутствует USD. Для примера возьмем GBP/CHF, курс 1.44000.
         Формула расчета: Цена пункта = объем позиции * размер пункта * текущая котировка базовой валюты по отношению к USD / текущий курс валютной пары (кросс-курс)
         Для GBP/CHF: 100 000 * 0.00001 * 1.58000 (курс GBP/USD) / 1.44000 = 1.1 $*/
         {if(!IsTesting())
         {
            //Работаем в реальном режиме
            {if(StringSubstr(iPairs,StringFind(iPairs,"%",StringFind(iPairs,BaseCurrency,1))+1,1)=="0")//Ишем базовую валюту и за ней после % признак перевернутости
            {//Для базовых валют вида XXXUSD для которых есть обратная котировка (например EURUSD) - нормальная не перевёрнутая
               {if(SymbolSelect(BaseCurrency+"USD",true))//попытка выбрать символ в окне MarketWatch (Обзор рынка)
               {
                  //----- отладка
                  //Print("{",iSymbol,"}");
                  //Print(">>",ContractSize*(SymbolInfoDouble(BaseCurrency+"USD",SYMBOL_ASK)+SymbolInfoDouble(BaseCurrency+"USD",SYMBOL_BID))/2);
                  //return(ContractSize*(SymbolInfoDouble(BaseCurrency+"USD",SYMBOL_ASK)));//не работает в тестере
                  {switch(iMode)
                  {
                        case 0://Mid
                           {
                              return(ContractSize*sPoint
                                          *((SymbolInfoDouble(BaseCurrency+"USD",SYMBOL_ASK)+SymbolInfoDouble(BaseCurrency+"USD",SYMBOL_BID))/2.0)
                                          /((SymbolInfoDouble(iSymbol,SYMBOL_ASK)+SymbolInfoDouble(iSymbol,SYMBOL_BID))/2.0)
                                     );
                           }
                        case 1://Ask
                           {
                              return(ContractSize*sPoint
                                          *((SymbolInfoDouble(BaseCurrency+"USD",SYMBOL_ASK)))
                                          /((SymbolInfoDouble(iSymbol,SYMBOL_ASK)))
                                     );
                           }
                        case 2://Bid
                           {
                              return(ContractSize*sPoint
                                          *((SymbolInfoDouble(BaseCurrency+"USD",SYMBOL_BID)))
                                          /((SymbolInfoDouble(iSymbol,SYMBOL_BID)))
                                     );
                           }
                  }}//switch(iMode)
               }else{
                  return(ContractSize*sPoint);
               }}//if(SymbolSelect(BaseCurrency+"USD",true))
            }else{//Для базовых валют вида USDXXX для которых котировка прямая (например USDCAD) в парах XXXYYY (напрмер CADJPY)- перевернутая, так как нет пары CADUSD есть USDCAD 
               //Формула расчета: Цена пункта = объем позиции * размер пункта * (1 / текущая котировка USD по отношению к базовой валюте) / текущий курс валютной пары (кросс-курс)
               {if(SymbolSelect("USD"+BaseCurrency,true))//попытка выбрать символ в окне MarketWatch (Обзор рынка)
               {
                  //Print(ContractSize*(1/SymbolInfoDouble("USD"+BaseCurrency,SYMBOL_ASK)+1/SymbolInfoDouble("USD"+BaseCurrency,SYMBOL_BID))/2);
                  {switch(iMode)
                  {
                        case 0://Mid
                           {
                              return(ContractSize*sPoint
                                          *(1.0/((SymbolInfoDouble("USD"+BaseCurrency,SYMBOL_ASK)+SymbolInfoDouble("USD"+BaseCurrency,SYMBOL_BID))/2.0))
                                          //*((1.0/SymbolInfoDouble("USD"+BaseCurrency,SYMBOL_ASK)+1.0/SymbolInfoDouble("USD"+BaseCurrency,SYMBOL_BID))/2.0)
                                          /((SymbolInfoDouble(iSymbol,SYMBOL_ASK)+SymbolInfoDouble(iSymbol,SYMBOL_BID))/2.0)
                                    );
                           }
                        case 1://Ask
                           {
                              return(ContractSize*sPoint
                                          *(1.0/SymbolInfoDouble("USD"+BaseCurrency,SYMBOL_ASK))
                                          /(SymbolInfoDouble(iSymbol,SYMBOL_ASK))
                                    );
                           }
                        case 2://Bid
                           {
                              return(ContractSize*sPoint
                                          *(1.0/SymbolInfoDouble("USD"+BaseCurrency,SYMBOL_BID))
                                          /(SymbolInfoDouble(iSymbol,SYMBOL_BID))
                                    );
                           }
                  }}//switch(iMode)
               }else{
                  return(ContractSize*sPoint);
               }}//if(SymbolSelect("USD"+BaseCurrency,true))
            }}//if(StringSubstr(iPairs,StringFind(iPairs,"%",StringFind(iPairs,BaseCurrency,1))+1,1)=="0")   
         }else{
            //Работаем в тестере - невозможно получить котировки других валют
            return(ContractSize*sPoint);
         }}//if(!IsTesting())
      }}//if((CotirCurrency=="USD")||(OilCurrency=="Oil"))
   }}//if(BaseCurrency=="USD")
   return(ContractSize*sPoint);
}//CalcTickValue()
 
Yury Kirillov:

Примеры расчета стоимости пункта:

Разница в 1 пункт (для BID)

Разница в 3 пункта (для BID)

Разница в 0.3 пункта, и это нормально при расчёте со всеми округлениями. Так что больше шума, нежели самой проблемы

P.S. проблемы как таковой то и нет. Разница может так-же быть потому, что по одной из пар участвует старая цена при расчётах, котировки то не синхронно приходят в терминал

 
Vitaly Muzichenko:
Разница в 0.3 пункта, и это нормально при расчёте со всеми округлениями. Так что больше шума, нежели самой проблемы


Вы шутите что-ли? С деньгами работаем, округление более 1 пипса младшего знака - это недопустимая роскошь!

При спреде 0-3 пипса и комиссии около 4 пипс ошибка в 3 пипс явно выглядит значимой.

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

То ли стандартные врут, то ли у меня в расчетах косяк.

И, да, желаю Вам всегда округлений только в Вашу пользу!
 
Yury Kirillov:


Вы шутите что-ли? С деньгами работаем, округление более 1 пипса младшего знака - это недопустимая роскошь!

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

То ли стандартные врут, то ли у меня в расчетах косяк.

Я несколько лет работаю со стандартной функцией, и никогда не возникало вопросов - всё работает правильно, и с деньгами, и с демо-деньгами.
 
Vitaly Muzichenko:
Я несколько лет работаю со стандартной функцией, и никогда не возникало вопросов - всё работает правильно, и с деньгами, и с демо-деньгами.

И Вы не хотите повысить точность расчетов на 3 пипса? Для Вас такая погрешность не важна?