Расчет TickValue и прибыли - страница 5

 

Игорь, у Вас в скрипте ошибка. Вот здесь нужно умножать на tickvalue, а не делить:

   double profit   = ((bid - orderOpenPrice)/Point) / tvalue * orderLots;

В вашем варианте возвращает правильное значение потому что у Вас правильное tickvalue = 1, и делить на него или умножать, без разницы. У меня даже при правильном варианте расчёта с моими вводными данными получается 5USD. Вопрос почему функция возвращает неправильное значение. И этот вопрос к разработчикам или к брокерам, даже не знаю.

 
Andrey Kaunov:

Игорь, у Вас в скрипте ошибка. Вот здесь нужно умножать на tickvalue, а не делить:

В вашем варианте возвращает правильное значение потому что у Вас правильное tickvalue = 1, и делить на него или умножать, без разницы. У меня даже при правильном варианте расчёта с моими вводными данными получается 5USD. Вопрос почему функция возвращает неправильное значение. И этот вопрос к разработчикам или к брокерам, даже не знаю.

Да странно. Проверил - В МТ4 Золото размер контракта тот же, мин.объем тот же, пойнты те же, выдаёт стоимость тика 1. А в МТ5 0,1.

Сдаётся кто-то где-то что-то забыл поменять..

 
Andrey Kaunov:

Игорь, у Вас в скрипте ошибка. Вот здесь нужно умножать на tickvalue, а не делить:

В вашем варианте возвращает правильное значение потому что у Вас правильное tickvalue = 1, и делить на него или умножать, без разницы. У меня даже при правильном варианте расчёта с моими вводными данными получается 5USD. Вопрос почему функция возвращает неправильное значение. И этот вопрос к разработчикам или к брокерам, даже не знаю.

формула то правильная, как минимум для мажоров и для MQL4 - вспомнил где использовал, расчет БУ для группы ордеров

попробовал под MQL5, что то не то по золоту показывает

#property script_show_inputs
input double orderLots      = 1.0;
input double orderOpenPrice = 1523.34;
input double bid            = 1522.84;
//+------------------------------------------------------------------+
void OnStart()
{
   double tvalue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE) / (SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE) / _Point);
   double profit   = ((bid - orderOpenPrice) / _Point) / tvalue * orderLots;
   Print("profit = ", profit);
   Print("SYMBOL_TRADE_TICK_VALUE = ",SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE));
}

2020.03.14 20:05:11.012 tst (XAUUSD,MN1) profit = -1000.0

2020.03.14 20:05:11.012 tst (XAUUSD,MN1) SYMBOL_TRADE_TICK_VALUE = 0.5

в MT4 этот же код:

2020.03.14 20:07:36.543 tst XAUUSD,H1: SYMBOL_TRADE_TICK_VALUE = 1.0

2020.03.14 20:07:36.543 tst XAUUSD,H1: profit = -50.0

 

Игорь, вдумайтесь в смысл вашей формулы:

double profit   = ((bid - orderOpenPrice) / _Point) / tvalue * orderLots;

Вы количество пунктов - "(bid - orderOpenPrice) / _Point" делите на стоимость одного пункта - "tvalue"  (предположим что лот равен 1). И что Вы хотите получить на выходе?!

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


Aleksey Mavrin:

Да странно. Проверил - В МТ4 Золото размер контракта тот же, мин.объем тот же, пойнты те же, выдаёт стоимость тика 1. А в МТ5 0,1.

Сдаётся кто-то где-то что-то забыл поменять..

Именно! Функция SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE) возвращает неверное значение и это факт.

 
Andrey Kaunov:

Игорь, вдумайтесь в смысл вашей формулы:

Вы количество пунктов - "(bid - orderOpenPrice) / _Point" делите на стоимость одного пункта - "tvalue"  (предположим что лот равен 1). И что Вы хотите получить на выходе?!

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

double tvalue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE) / (SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE) / _Point);

уберите тут пп , тогда получите формулу, где умножение будет - как Вы пишите, я же писал, что дело давнее не помню уже где эту часть расчетов брал

но суть одна, что стоимость пп. "в деньгах" это отношение TICK_VALUE к TICK_SIZE 

не понятно почему в MQL4 и в MQL5  одна и та же формула расчета дает разные результаты - пока даже не знаю что предположить

 

Нет нет нет, Игорь. Эта часть формулы:

double tvalue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE) / (SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE) / _Point);

как правило равна единице (1), т.к. "SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE)" и "_Pointна большинстве символов равны. Смысл этой части формулы заключается только в том, если размер минимального изменения цены больше размера одного пункта. Например если какой то инструмент скачет сразу на 10 пунктов или на 5, бывают и такие.

Отсюда делаем вывод, что если частное в большинстве случаев равно 1, то:

double tvalue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE) / 1;

Или просто:

double tvalue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);

В нашем случае с золотом всё именно так и обстоит. Далее читайте мой предыдущий пост.


P.S. Ваши расчёты спасает только то что на парах которые вы считаете SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE)=1  Запустите скрипт на EURGBP или USDJPY (где tickvalue не равен 1), сравните с реальным профитом открытой сделки, и вы удивитесь результату.

Документация по MQL5: Константы, перечисления и структуры / Состояние окружения / Информация об инструменте
Документация по MQL5: Константы, перечисления и структуры / Состояние окружения / Информация об инструменте
  • www.mql5.com
Для получения текущей рыночной информации служат функции SymbolInfoInteger(), SymbolInfoDouble() и SymbolInfoString(). В качестве второго параметра этих функций допустимо передавать один из идентификаторов из перечислений ENUM_SYMBOL_INFO_INTEGER, ENUM_SYMBOL_INFO_DOUBLE и ENUM_SYMBOL_INFO_STRING соответственно. Некоторые символы (как...
 
Andrey Kaunov:

Нет нет нет, Игорь. Эта часть формулы:

как правило равна единице (1), т.к. "SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE)" и "_Pointна большинстве символов равны. Смысл этой части формулы заключается только в том, если размер минимального изменения цены больше размера одного пункта. Например если какой то инструмент скачет сразу на 10 пунктов или на 5, бывают и такие.

Отсюда делаем вывод, что если частное в большинстве случаев равно 1, то:

Или просто:

В нвшем случае с золотом всё именно так и обстоит. Далее читайте мой предыдущий пост.

ОК, буду иметь ввиду, но кажется деление на _Point в моем примере нужно было для работы на индексах, в общем где то на форумах, нашел, проверил, потом пару раз пользовался при расчете уровня БУ - на валютах нормально работает

 
Andrey Kaunov:

Нет нет нет, Игорь. Эта часть формулы:

как правило равна единице (1), т.к. "SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE)" и "_Pointна большинстве символов равны. Смысл этой части формулы заключается только в том, если размер минимального изменения цены больше размера одного пункта. Например если какой то инструмент скачет сразу на 10 пунктов или на 5, бывают и такие.

Отсюда делаем вывод, что если частное в большинстве случаев равно 1, то:

Или просто:

В нашем случае с золотом всё именно так и обстоит. Далее читайте мой предыдущий пост.


P.S. Ваши расчёты спасает только то что на парах которые вы считаете SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE)=1  Запустите скрипт на EURGBP или USDJPY (где tickvalue не равен 1), сравните с реальной стоимостью тика открытой сделки, и вы удивитесь результату.

Для индексов брал отсюда

С не форекс-инструментами не так просто

Идентификатор

Описание

Формула

SYMBOL_CALC_MODE_FOREX

Forex mode – расчет прибыли и маржи для Форекс

Margin:  Lots * Contract_Size / Leverage * Margin_Rate

 

Profit:   (close_price - open_price) * Contract_Size*Lots

SYMBOL_CALC_MODE_FOREX_NO_LEVERAGE

Forex No Leverage mode – расчет прибыли и маржи для Форекс без учета плеча

Margin:  Lots * Contract_Size * Margin_Rate

 

Profit:   (close_price - open_price) * Contract_Size * Lots

SYMBOL_CALC_MODE_FUTURES

Futures mode – расчет залога и прибыли для фьючерсов

Margin: Lots * InitialMargin * Margin_Rate

 

Profit:  (close_price - open_price) * TickPrice / TickSize*Lots

SYMBOL_CALC_MODE_CFD

CFD mode – расчет залога и прибыли для CFD

Margin: Lots * ContractSize * MarketPrice * Margin_Rate

 

Profit:  (close_price - open_price) * Contract_Size * Lots

Документация по MQL5: Константы, перечисления и структуры / Состояние окружения / Информация об инструменте
Документация по MQL5: Константы, перечисления и структуры / Состояние окружения / Информация об инструменте
  • www.mql5.com
Для получения текущей рыночной информации служат функции SymbolInfoInteger(), SymbolInfoDouble() и SymbolInfoString(). В качестве второго параметра этих функций допустимо передавать один из идентификаторов из перечислений ENUM_SYMBOL_INFO_INTEGER, ENUM_SYMBOL_INFO_DOUBLE и ENUM_SYMBOL_INFO_STRING соответственно. Некоторые символы (как...
 

Да, Виталий, хороший способ расчёта. Но в этом случае прибыль мы получим в единицах котируемой валюты инструмента. А если нужно получить в валюте депозита, необходимо прибегнуть к дополнительным вычислениям или использовать функцию 

SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_VALUE);

Хотелось бы всё таки узнать мнение разработчиков, почему на золоте эта функция возвращает неверное значение.

 
Renat Fatkhullin #:

У Вас неправильное понимание значения MODE_TICKVALUE:

MODE_TICKVALUE 16 Размер минимального изменения цены инструмента в валюте депозита

Мы не используем эту величину в своих расчетах профитов.


О сложных случаях пересчета: при отсутствии прямого курса используется конвертация через доллар.

У многих брокеров цена тика для металлов неправильная установлена и соответственно параметр 

SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);

 выдаёт неверное значение. Это в обновлениях может как-то полечиться или искать обходные пути? 

Причина обращения: