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

 
getch   :

Дело не в том, готов я ждать или нет, а в том, что так происходит на межбанке. А также у некоторых брокеров:

Дело в том, что нам как раз очень важно это знать - "готовы ли простые трейдеры на головную боль с мультивалютным учетом позиций?".

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

Не забывайте, что это спекулятивная торговля ради прибыли без реальной поставки. Да и смешно в век борьбы за миллисекунды исполнения включать режим "дата валютирования +2 дня".

 
getch   :

Дело не в том, готов я ждать или нет, а в том, что так происходит на межбанке. А также у некоторых брокеров:

Сделали 20 сделок (открытие-закрытие) на EURGBP, 30 сделок на USDJPY и 50 сделок на AUDNZD. Соответственно, есть прибыль в GBP, JPY и NZD. Эта прибыль в своих валютах постоянна. Но, конечно, в базовой валюте счета - нет, т.к. курсы плавают. Вся прибыль в разных валютах конвертируется (окончательно) в базовую валюту в момент валютирования (возможно, не правильно использую данный термин).


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

 

Провел исследование правильности расчета прибыли в MT4. Предположение об ошибке подтвердилось на 100%. Как это было:

Скрипт на MQL4:

#property show_inputs

extern string BaseCurrency = "USD";

bool RealSymbol( string Str )
{
  return(MarketInfo(Str, MODE_BID) != 0);
}

double GetTickValue( string Symb )
{
  string Str, ProfitCurrency, SymbolPrefix;
  double Res, PriceExchage;
  
  ProfitCurrency = StringSubstr(Symb, 3, 3);
  SymbolPrefix = StringSubstr(Symb, 6);
  
  if (ProfitCurrency == BaseCurrency)
    Res = MarketInfo(Symb, MODE_LOTSIZE) * MarketInfo(Symb, MODE_TICKSIZE);
  else
  {
    Str = BaseCurrency + ProfitCurrency + SymbolPrefix;
    
    if (RealSymbol(Str))
    {
//      PriceExchage = MarketInfo(Str, MODE_BID); // Так считает MetaTrader4 - неправильно
      PriceExchage = MarketInfo(Str, MODE_ASK); // Правильный вариант
        
      Res = MarketInfo(Symb, MODE_LOTSIZE) * MarketInfo(Symb, MODE_TICKSIZE) / PriceExchage;
    }
    else
    {
      Str = ProfitCurrency + BaseCurrency + SymbolPrefix;

      PriceExchage = MarketInfo(Str, MODE_BID);
        
      Res = MarketInfo(Symb, MODE_LOTSIZE) * MarketInfo(Symb, MODE_TICKSIZE) * PriceExchage;
    }
  }
  
  return(Res);
}

void PrintPosition( int Ticket, double TickValueMT4, double TickValueReal )
{
  double Profit;
  
  OrderSelect(Ticket, SELECT_BY_TICKET, MODE_HISTORY);
  
  Profit = OrderProfit();
  Print("OrderProfit = ", Profit);

  Profit = OrderLots() * (OrderClosePrice() - OrderOpenPrice()) * TickValueMT4 / MarketInfo(OrderSymbol(), MODE_TICKSIZE);
  Print("OrderProfit(TickValueMT4) = ", DoubleToStr(Profit, 2));

  Profit = OrderLots() * (OrderClosePrice() - OrderOpenPrice()) * TickValueReal / MarketInfo(OrderSymbol(), MODE_TICKSIZE);
  Print("OrderProfit(TickValueReal) = ", DoubleToStr(Profit, 2));
  
  return;
}

void Position1( string Symb, double Lots )
{
  double TickValueMT4, TickValueReal;
  int Ticket1, Ticket2;
    
  Print("Call Position1(" + Symb + ") function...");
  
  RefreshRates();
  Ticket1 = OrderSend(Symb, OP_SELL, Lots, MarketInfo(Symb, MODE_BID), 0, 0, 0);

  RefreshRates();
  Ticket2 = OrderSend(Symb, OP_BUY, Lots, MarketInfo(Symb, MODE_ASK), 0, 0, 0);

  RefreshRates();
  
  TickValueMT4 = MarketInfo(Symb, MODE_TICKVALUE);
  TickValueReal = GetTickValue(Symb);
  
  OrderCloseBy(Ticket1, Ticket2); // Если поменять местами тикеты, прибыль будет иной - ошибка!
  
  PrintPosition(Ticket1, TickValueMT4, TickValueReal);
    
  return;
}

void Position2( string Symb, double Lots )
{
  double TickValueMT4, TickValueReal;
  int Ticket;
    
  Print("Call Position2(" + Symb + ") function...");
  
  RefreshRates();
  Ticket = OrderSend(Symb, OP_BUY, Lots, MarketInfo(Symb, MODE_ASK), 0, 0, 0);
  
  RefreshRates();

  TickValueMT4 = MarketInfo(Symb, MODE_TICKVALUE);
  TickValueReal = GetTickValue(Symb);
  
  OrderClose(Ticket, Lots, MarketInfo(Symb, MODE_BID), 0);
  
  PrintPosition(Ticket, TickValueMT4, TickValueReal);
  
  return;
}

void start()
{    
  Position1("EURGBP", 500);
  Position2("USDJPY", 500);

  return;
}

Результат выполнения скрипта:

Position1 проверяет подсчет прибыли при OrderCloseBy. Оказалось, что при перестановке входных параметров этой функции прибыль меняется. Это ошибка.

Также подтверждаются слова разработчиков, что алгоритм расчета прибыли несколько иной (и тоже неверный), чем алгоритм расчета TickValue.

Position2 проверяет подсчет прибыли при OrderClose. Ошибка в расчетах прибыли снова присутствует.

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

MetaTrader5, как серьезная платформа для торговли, не должен содержать столь серьезных ошибок!

 
Renat :

Дело в том, что нам как раз очень важно это знать - "готовы ли простые трейдеры на головную боль с мультивалютным учетом позиций?".

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

Не забывайте, что это спекулятивная торговля ради прибыли без реальной поставки. Да и смешно в век борьбы за миллисекунды исполнения включать режим "дата валютирования +2 дня".

Есть брокеры, где "валютирование" происходит раз в сутки...

Насчет отмены локирования:

странное решения с учетом того , что MetaTrader4 является тоже неттинговой платформой (без учета выявленных выше ошибок в расчетах прибыли и всего сопутствующего).

 

Я вчера, когда смотрел код, неверно выразился по поводу разной стоимость пункта в зависимости от направления.

Точнее сказать, что TickValue при конвертации в целевую валюту зависит от того, убыточна она или нет. То есть, если мы получили убыток в 1 пипс, то нам надо его выкупить по цене Ask, а если прибыль в 1 пипс, то продать по цене Bid. Оценочная функция MODE_TICKVALUE использует только один вариант.


Сегодня после проверок нашли проблему в конвертации кроссов в валюту депозита - спасибо за расследование. В МетаТрейдер 5 такой проблемы нет.

Мы исправим ошибку в крупном обновлении платформы MetaTrader 4 в феврале (нужно многое сделать синхронно).

Мне очень стыдно, извините.

 

Немного теории отсебятины. Прошу, если где-то не прав - поправить.

На рынке FOREX как таковых денег нет. Деньги все лежат на банковских торговых счетах клиентов (включая деньги самих банков) в разных валютах.
На FOREX происходят конверсионные операции. Их объем и есть оборот рынка FOREX.

Рассмотрим ситуацию на EURGBP:

  1. Клиент_X хочет напрямую, (без валют-посредников) купить AmountX EUR (на свой EUR-счет) на свои GBP (со своего GBP-счета). Он хочет это сделать на рынке FOREX по курсу EURGBP_askX, который лучше текущего (EURGBP_askX < EURGBP_ask). Поэтому выставляется заявка (гарантированное намерение) на покупку AmountX EUR по курсу EURGBP_askX (BuyLimit_X).
  2. Клиенту_X везет - наступает момент, когда никто на рынке FOREX не хочет продавать EUR против GBP по цене хуже, чем EURGBP_askX. Т.е. текущая цена EURGBP_bid становится равной EURGBP_bidX (чтобы не было путаницы в дальнейшем, теперь так называю цену Клиента_X EURGBP_askX).
  3. Клиент_Y хочет удовлетвить полностью заявку Клиента_X - продать по текущей цене AmountX EUR и получить за это GBP.
  4. У клиента_Y (спекулянт) немного денег и только USD-счет. Поэтому он решается воспользоваться маржинальной торговлей с залогом Margin (обычно 1% - плечо 100:1). Он берет в краткосрочный кредит у своего брокера-банка AmountX EUR (откуда брокер-банк взял столько EUR - неизвестно (обменял часть от суммы на том же FOREX (конечно, не на GBP) или у него была вся сумма)) под залог Margin * AmountX * EURUSD_ask USD. Где EURUSD_ask - плавающий курс. Т.е. залог будет меняться постоянно с изменением курса EURUSD_ask.
  5. Клиенты_XY обмениваются по цене EURGBP_bidX: Клиент_X получает AmountX EUR от Клиента_Y, а Клиент_Y получает Amount_X * EURGBP_bidX GBP от Клиента_X.
  6. Клиент_Y теперь имеет Amount_X * EURGBP_bidX GBP и долг AmountX EUR.
  7. Проходит время и Клиент_Y решает обменять на рынке FOREX свои GBP на EUR по текущему курсу EURGBP_askY (объема хватает на всю сумму). Осуществляет обмен: отдает AmountX * EURGBP_bidX GBP и получает AmountX * EURGBP_bidX / EURGBP_askY EUR.
  8. Клиент_Y возвращает долг в размере AmountX EUR. Итого прибыль клиента_Y равна AmountX * (EURGBP_bidX / EURGBP_askY - 1) EUR.
  9. Клиент_Y полученную прибыль в EUR обменивает на рынке FOREXклиента_Z) по цене EURUSD_bidZ (если он обменивает сразу после отдачи долга (как в MT4), то EURUSD_bidZ == EURUSD_bidY (в момент Y)).
  10. Итого прибыль Клиента_Y (по схеме валютирования MT4) равна AmountX * EURUSD_bidY * (EURGBP_bidX / EURGBP_askY - 1) USD

Ситуация наоборот:

  1. Клиент_X хочет напрямую, (без валют-посредников) продать свои AmountX EUR (со своего EUR-счета) за GBP (на свой GBP-счет). Он хочет это сделать на рынке FOREX по курсу EURGBP_bidX, который лучше текущего (EURGBP_bidX > EURGBP_bid). Поэтому выставляется заявка (гарантированное намерение) на продажу AmountX EUR по курсу EURGBP_bidX (SellLimit_X).
  2. Клиенту_X везет - наступает момент, когда никто на рынке FOREX не хочет покупать EUR против GBP по цене лучше, чем EURGBP_bidX . Т.е. текущая цена EURGBP_ask становится равной EURGBP_askX (чтобы не было путаницы в дальнейшем, теперь так называю цену Клиента_X EURGBP_bidX).
  3. Клиент_Y хочет удовлетвить полностью заявку Клиента_X - купить по текущей цене AmountX EUR и отдать за это GBP.
  4. У клиента_Y (спекулянт) немного денег и только USD-счет. Поэтому он решается воспользоваться маржинальной торговлей с залогом Margin (обычно 1% - плечо 100:1). Он берет в краткосрочный кредит у своего брокера-банка AmountX * EURGBP_askX GBP (откуда брокер-банк взял столько GBP - неизвестно (обменял часть от суммы на том же FOREX (конечно, не на EUR) или у него была вся сумма)) под залог Margin * AmountX * EURGBP_askX * GBPUSD_ask USD. Где GBPUSD_ask - плавающий курс. Т.е. залог будет меняться постоянно с изменением курса GBPUSD_ask.
  5. Клиенты_XY обмениваются по цене EURGBP_askX: Клиент_X получает AmountX * EURGBP_askX GBP от Клиента_Y, а Клиент_Y получает Amount_X * EUR от Клиента_X.
  6. Клиент_Y теперь имеет AmountX * EUR и долг AmountX * EURGBP_askX GBP.
  7. Проходит время и Клиент_Y решает обменять на рынке FOREX свои EUR на GBP по текущему курсу EURGBP_bidY (объема хватает на всю сумму). Осуществляет обмен: отдает AmountX EUR и получает AmountX * EURGBP_bidY GBP.
  8. Клиент_Y возвращает долг в размере AmountX * EURGBP_askX GBP. Итого прибыль клиента_Y равна AmountX * (EURGBP_bidY - EURGBP_askX) GBP.
  9. Клиент_Y полученную прибыль в GBP обменивает на рынке FOREXклиента_Z) по цене GBPUSD_bidZ (если он обменивает сразу после отдачи долга (как в MT4), то GBPUSD_bidZ == GBPUSD_bidY (в момент Y)).
  10. Итого прибыль Клиента_Y (по схеме валютирования MT4) равна AmountX * GBPUSD_bidY * (EURGBP_bidy - EURGBP_askX)  USD


Получается, при X - открытие, Y - закрытие.

Прибыль от открытия SELL-позиции и ее закрытия равна ProfitSELL = AmountX * EURUSD_bidY * (EURGBP_bidX / EURGBP_askY - 1) USD

Прибыль от открытия BUY-позиции и ее закрытия равна ProfitBUY = AmountX * GBPUSD_bidY * (EURGBP_bidy - EURGBP_askX)  USD

При этом со стороны спекулянта при закрытии SELL-позиции совершается еще одна сделка на FOREX по паре EURUSD, а при BUY - GBPUSD. Обратите внимание, что закрытие маржинальной позиции не одно и тоже, что открытие противоположной маржинальной позиции. Т.е. лок может существовать

Иначе говоря при закрытии сделкок между двумя спекулянтами на EURGBP производится (в случае моментального валютирования, как в MT4) три сделки на рынке FOREX: EURGBP, EURUSD и GBPUSD. Возможно, отсюда, в частности, следует, что "синхронизация" трех пар происходит не только за счет арбитражных игроков.

Если X - открытие в одну сторону, Y - открытие в другую сторону (равнообъемно), Z - текущее состояние

 Profit = Amount * GBPUSD_bidZ * (EURGBP_bidy - EURGBP_askX)  USD

Если же спекулянт не закрывает сделки, а открывает противоположные равные по объему, то при открытии противоположной совершается еще одна сделка по паре GBPUSD. У брокеров-банков для своих клиентов видимая часть торгов так (нет закрытий сделок, есть противоположные) и происходит. Но во внутренней системе брокеров-банков все же нельзя полностью обойтись без реальных закрытий.

Еще замечания:

Может показаться, что ProfitSELL равен по модулю ProfitBUY, т.к. можно записать несколько иначе ProfitBUY = AmountX * EURGBP_bidy * GBPUSD_bidY * (1 - EURGBP_askX / EURGBP_bidy) USD. Но EURGBP_bidy * GBPUSD_bidY вовсе не обязано быть равно EURUSD_bidY (значения особенно сильно отличаются, если валютирование происходит по схеме отличной от MT4).
Залог все время "плавает".

Итого можно точно сказать, что прибыль BUY и SELL сделок считается по разным формулам. И эти формулы не зависят от знака прибыли (положительная или отрицательная). Но из-за практически отсутствия реальных закрытий сделок прибыль считается по формуле закрытия BUY-сделки.

Renat, прошу еще раз изучить данный вопрос (подсчет прибыли и маржи), поскольку я ранее ввел вас в заблуждение своими на тот момент примитивными представлениями. Извините.

 
getch:

Немного теории отсебятины. Прошу, если где-то не прав - поправить.

На рынке FOREX как таковых денег нет. Деньги все лежат на банковских торговых счетах клиентов (включая деньги самих банков) в разных валютах.
На FOREX происходят конверсионные операции. Их объем и есть оборот рынка FOREX.

 

Итого можно точно сказать, что прибыль BUY и SELL сделок считается по разным формулам. И эти формулы не зависят от знака прибыли (положительная или отрицательная).

Renat, прошу еще раз изучить данный вопрос (подсчет прибыли и маржи), поскольку я ранее ввел вас в заблуждение своими на тот момент примитивными представлениями. Извините.

Getch, простите Вы здесь этот пример про что расказали. Про ДЦ и иже с ними, типа  брокеры и маркетмэйкеры,  или может про межбанк?

 В маржинальной торговле валютами все просто до безобразия. И  формулы из трех слагаемых.

 
SProgrammer писал(а)  :

Для логики ДЦ все, действительно, элементарно, т.к. происходит на уровне ИГРЫ в торговлю.

Поскольку MetaTrader5 позиционируется, как серьезная платформа, то и уровень рассуждений соответствующий - межбанк.

 
getch:

Для логики ДЦ все, действительно, элементарно, т.к. происходит на уровне ИГРЫ в торговлю.

Поскольку MetaTrader5 позиционируется, как серьезная платформа, то и уровень рассуждений соответствующий - межбанк.

ОК.

 

Просьба добавить в справку четкие определения TICKVALUE, TICKSIZE, LEVERAGE, ... торговых инструментов с формулами их соотношений друг к другу. Чтобы не было того бардака, что творится в MT4.

Как узнать валюту ордера? - MQL4 форум
  • www.mql5.com
Как узнать валюту ордера? - MQL4 форум