Некорректный расчет прибыли на биржевых инструментах в тестере

 

Помимо абсолютно неверной работы на демо  самого терминал или сервера ( см. тему https://www.mql5.com/ru/forum/164578 ), МТ5 тестер так же страдает похожей проблемой.

Ниже лог из тестера,где просто открывается маркетом сделка.

Видно,что спред в данным момент равен 15пунктам. Минимальное изменение цены = 5п.Стоимость мин. изменения цены в валюте = 12.5.

Несложно посчитать, что при открытии сделки мы должны получить 15*12.5/5=37.5 ,т.е. именно столько стоит спред в валюте.

Ниже то,что считает тестер. Это что за цифра такая 143.56???

Принимаются поправки,если я где-то ошибся.

Сервер amp-demo терминал build 1502

2017.01.17 13:50:18.983 2017.01.03 08:48:00   exchange buy 1.00 DDM7 at 11625.5 (11624.0 / 11625.5 / 11620.0)
2017.01.17 13:50:18.983 2017.01.03 08:48:00   deal #2 buy 1.00 DDM7 at 11625.5 done (based on order #2)
2017.01.17 13:50:18.984 2017.01.03 08:48:00   deal performed [#2 buy 1.00 DDM7 at 11625.5]
2017.01.17 13:50:18.984 2017.01.03 08:48:00   order performed buy 1.00 at 11625.5 [#2 buy 1.00 DDM7 at 11625.5]
2017.01.17 13:50:18.994 2017.01.03 08:48:00   CTrade::OrderSend: exchange buy 1.00 DDM7 [done]
2017.01.17 13:50:18.994 2017.01.03 08:48:00   BID  = 11624.0
2017.01.17 13:50:18.994 2017.01.03 08:48:00   ASK  = 11625.5
2017.01.17 13:50:18.995 2017.01.03 08:48:00   Спред  = 15
2017.01.17 13:50:18.995 2017.01.03 08:48:00   Профит сразу после открытия = -143.56
2017.01.17 13:50:18.995 2017.01.03 08:48:00   Профит должен быть = -37.5
//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2012, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
//--- global variable
CPositionInfo  m_position;                   // trade position object
CTrade         m_trade;                      // trading object
input     string symb="DDM7";
input int min=45;
datetime date1;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double x;
   date1=TimeCurrent();
   MqlDateTime str1;
   TimeToStruct(date1,str1);
   if(str1.min>=min)
     {
      if(PositionsTotal()==0 && SymbolInfoInteger(symb,SYMBOL_SPREAD)<=50)
        {
         m_trade.Buy(1.00,symb);
         Print("BID  = ",SymbolInfoDouble(symb,SYMBOL_BID));
         Print("ASK  = ",SymbolInfoDouble(symb,SYMBOL_ASK));
         Print("Спред  = ",SymbolInfoInteger(symb,SYMBOL_SPREAD));
         Print("Профит сразу после открытия = ",AccountInfoDouble(ACCOUNT_PROFIT));
         x=(SymbolInfoInteger(symb,SYMBOL_SPREAD)/(SymbolInfoDouble(symb,SYMBOL_TRADE_TICK_SIZE)*
         MathPow(10,SymbolInfoInteger(symb,SYMBOL_DIGITS))))*SymbolInfoDouble(symb,SYMBOL_TRADE_TICK_VALUE);
         Print("Профит должен быть = ",-x);
        }
     }
     if(PositionsTotal()==1)
     {
     Print("ASK  = ",SymbolInfoDouble(symb,SYMBOL_ASK));
     Print("Профит после открытия = ",AccountInfoDouble(ACCOUNT_PROFIT));
     }
  }
//+------------------------------------------------------------------+
Файлы:
 
Комиссия в MQL-коде не учитывается.
 
fxsaber:
Комиссия в MQL-коде не учитывается.

комиссия на круг на данном инструменте и сервере не превышает 10$,так что не то.

комиссия вообще тестером никак не учитывается в МТ5.

 
ivanivan_11:

комиссия вообще тестером никак не учитывается в МТ5.

На zero-account не учитывается. В тестере с полноценного реала, вроде, все есть.

В примере замените на SYMBOL_TRADE_TICK_VALUE_LOSS. 

 
fxsaber:

На zero-account не учитывается. В тестере с полноценного реала, вроде, все есть.

В примере замените на SYMBOL_TRADE_TICK_VALUE_LOSS. 

ну,где ж его взять,полноценный реал. Работаем пока с тем,что есть. В общем,Как я говорил, 10$ на круг погоды не сделают.

Внес изменения ,Как вы предложили. Я, правда,плохо понимаю,как насправление сделки влияет на стоимость тика. Ниже результат, ожидаемо такой же

2017.01.17 14:51:51.685 2017.01.03 08:48:00   exchange buy 1.00 DDM7 at 11625.5 (11624.0 / 11625.5 / 11620.0)
2017.01.17 14:51:51.685 2017.01.03 08:48:00   deal #2 buy 1.00 DDM7 at 11625.5 done (based on order #2)
2017.01.17 14:51:51.685 2017.01.03 08:48:00   deal performed [#2 buy 1.00 DDM7 at 11625.5]
2017.01.17 14:51:51.685 2017.01.03 08:48:00   order performed buy 1.00 at 11625.5 [#2 buy 1.00 DDM7 at 11625.5]
2017.01.17 14:51:51.693 2017.01.03 08:48:00   CTrade::OrderSend: exchange buy 1.00 DDM7 [done]
2017.01.17 14:51:51.693 2017.01.03 08:48:00   BID  = 11624.0
2017.01.17 14:51:51.693 2017.01.03 08:48:00   ASK  = 11625.5
2017.01.17 14:51:51.693 2017.01.03 08:48:00   Спред  = 15
2017.01.17 14:51:51.693 2017.01.03 08:48:00   Профит сразу после открытия = -143.56
2017.01.17 14:51:51.693 2017.01.03 08:48:00   Профит должен быть = -37.5
2017.01.17 14:51:51.693 2017.01.03 08:48:00   Профит должен быть, добавлено = -37.5


//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2012, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
//--- global variable
CPositionInfo  m_position;                   // trade position object
CTrade         m_trade;                      // trading object
input     string symb="DDM7";
input int min=45;
datetime date1;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double x,x1;
   date1=TimeCurrent();
   MqlDateTime str1;
   TimeToStruct(date1,str1);
   if(str1.min>=min)
     {
      if(PositionsTotal()==0 && SymbolInfoInteger(symb,SYMBOL_SPREAD)<=50)
        {
         m_trade.Buy(1.00,symb);
         Print("BID  = ",SymbolInfoDouble(symb,SYMBOL_BID));
         Print("ASK  = ",SymbolInfoDouble(symb,SYMBOL_ASK));
         Print("Спред  = ",SymbolInfoInteger(symb,SYMBOL_SPREAD));
         Print("Профит сразу после открытия = ",AccountInfoDouble(ACCOUNT_PROFIT));
         x=(SymbolInfoInteger(symb,SYMBOL_SPREAD)/(SymbolInfoDouble(symb,SYMBOL_TRADE_TICK_SIZE)*
         MathPow(10,SymbolInfoInteger(symb,SYMBOL_DIGITS))))*SymbolInfoDouble(symb,SYMBOL_TRADE_TICK_VALUE);
         x1=(SymbolInfoInteger(symb,SYMBOL_SPREAD)/(SymbolInfoDouble(symb,SYMBOL_TRADE_TICK_SIZE)*
         MathPow(10,SymbolInfoInteger(symb,SYMBOL_DIGITS))))*SymbolInfoDouble(symb,SYMBOL_TRADE_TICK_VALUE_LOSS);
         Print("Профит должен быть = ",-x);
         Print("Профит должен быть, добавлено = ",-x1);
        }
     }
     if(PositionsTotal()==1)
     {
     Print("ASK  = ",SymbolInfoDouble(symb,SYMBOL_ASK));
     Print("Профит после открытия = ",AccountInfoDouble(ACCOUNT_PROFIT));
     }
  }
//+------------------------------------------------------------------+
 
ivanivan_11:

ну,где ж его взять,полноценный реал. Работаем пока с тем,что есть. В общем,Как я говорил, 10$ на круг погоды не сделают.

Внес изменения ,Как вы предложили. Я, правда,плохо понимаю,как насправление сделки влияет на стоимость тика. Ниже результат, ожидаемо такой же

2

Попробуйте этот вариант

 

//+------------------------------------------------------------------+
//|                                                       test08.mq5 |
//|                                                   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"

#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
//--- global variable
CPositionInfo  m_position;                   // trade position object
CTrade         m_trade;                      // trading object
input     string symb="DDM7";
input int min=45;
datetime date1;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
double x,x1;
   date1=TimeCurrent();
   MqlDateTime str1;
   TimeToStruct(date1,str1);
   if(str1.min>=min)
     {
    
      if(PositionsTotal()==0 && SymbolInfoInteger(symb,SYMBOL_SPREAD)<=50)
        {
         m_trade.Buy(1.00,symb);
         Print("BID  = ",SymbolInfoDouble(symb,SYMBOL_BID));
         Print("ASK  = ",SymbolInfoDouble(symb,SYMBOL_ASK));
         Print("Спред  = ",SymbolInfoInteger(symb,SYMBOL_SPREAD));
         Print("Профит сразу после открытия = ",AccountInfoDouble(ACCOUNT_PROFIT));
         x=Profit(symb,1.00,SymbolInfoInteger(symb,SYMBOL_SPREAD));
         x1=(SymbolInfoInteger(symb,SYMBOL_SPREAD)/(SymbolInfoDouble(symb,SYMBOL_TRADE_TICK_SIZE)*
         MathPow(10,SymbolInfoInteger(symb,SYMBOL_DIGITS))))*SymbolInfoDouble(symb,SYMBOL_TRADE_TICK_VALUE_LOSS);
         Print("Профит должен быть = ",-x);
         Print("Профит должен быть, добавлено = ",-x1);
        }
     }
     if(PositionsTotal()==1)
     {
     Print("ASK  = ",SymbolInfoDouble(symb,SYMBOL_ASK));
     Print("Профит после открытия = ",AccountInfoDouble(ACCOUNT_PROFIT));
     }
  }
//+------------------------------------------------------------------+
double Profit(string symbol,double lot,double pips)
  {
   double pr=0.0;
   double tc = SymbolInfoDouble(symbol,SYMBOL_TRADE_CONTRACT_SIZE);
   double tv = SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_VALUE);
   double ts=SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE);
   double point=SymbolInfoDouble(symbol,SYMBOL_POINT);

   switch((ENUM_SYMBOL_CALC_MODE)SymbolInfoInteger(symbol,SYMBOL_TRADE_CALC_MODE))
     {
      case SYMBOL_CALC_MODE_FOREX:pr=pips*tv*lot;break;
      case SYMBOL_CALC_MODE_FUTURES:if(ts!=0) pr=pips*point*(tv/ts)*lot;break;
      case SYMBOL_CALC_MODE_CFD:pr=pips*point*tc*lot;break;
      case SYMBOL_CALC_MODE_CFDINDEX:pr=pips*point*tc*lot;break;
      case SYMBOL_CALC_MODE_CFDLEVERAGE:pr=pips*point*tc*lot;break;
      case SYMBOL_CALC_MODE_EXCH_STOCKS:pr=pips*point*tc*lot;break;
      case SYMBOL_CALC_MODE_EXCH_FUTURES:if(ts!=0) pr=pips*point*(tv/ts)*lot;break;
      case SYMBOL_CALC_MODE_EXCH_FUTURES_FORTS:if(ts!=0) pr=pips*point*(tv/ts)*lot;break;
     }
   return(NormalizeDouble(pr,2));
  }
//+------------------------------------------------------------------+

 ....

 

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

2017.01.17 16:04:42.442 2017.01.04 07:45:02   exchange buy 1.00 DDM7 at 11630.5 (11629.0 / 11630.5 / 11634.0)
2017.01.17 16:04:42.442 2017.01.04 07:45:02   deal #2 buy 1.00 DDM7 at 11630.5 done (based on order #2)
2017.01.17 16:04:42.442 2017.01.04 07:45:02   deal performed [#2 buy 1.00 DDM7 at 11630.5]
2017.01.17 16:04:42.442 2017.01.04 07:45:02   order performed buy 1.00 at 11630.5 [#2 buy 1.00 DDM7 at 11630.5]
2017.01.17 16:04:42.451 2017.01.04 07:45:02   CTrade::OrderSend: exchange buy 1.00 DDM7 [done]
2017.01.17 16:04:42.451 2017.01.04 07:45:02   BID  = 11629.0
2017.01.17 16:04:42.451 2017.01.04 07:45:02   ASK  = 11630.5
2017.01.17 16:04:42.451 2017.01.04 07:45:02   LAST  = 11634.0
2017.01.17 16:04:42.452 2017.01.04 07:45:02   Спред  = 15
2017.01.17 16:04:42.452 2017.01.04 07:45:02   Профит сразу после открытия = 91.17
2017.01.17 16:04:42.452 2017.01.04 07:45:02   Профит должен быть = -37.5
2017.01.17 16:04:42.452 2017.01.04 07:45:02   Профит должен быть, добавлено = -37.5
 
Sergey Gritsay:

Попробуйте этот вариант


 ....

Попробовал, результат не отличается

2017.01.17 16:09:18.194 2017.01.04 07:45:02   exchange buy 1.00 DDM7 at 11630.5 (11629.0 / 11630.5 / 11634.0)
2017.01.17 16:09:18.194 2017.01.04 07:45:02   deal #2 buy 1.00 DDM7 at 11630.5 done (based on order #2)
2017.01.17 16:09:18.194 2017.01.04 07:45:02   deal performed [#2 buy 1.00 DDM7 at 11630.5]
2017.01.17 16:09:18.195 2017.01.04 07:45:02   order performed buy 1.00 at 11630.5 [#2 buy 1.00 DDM7 at 11630.5]
2017.01.17 16:09:18.205 2017.01.04 07:45:02   CTrade::OrderSend: exchange buy 1.00 DDM7 [done]
2017.01.17 16:09:18.205 2017.01.04 07:45:02   BID  = 11629.0
2017.01.17 16:09:18.205 2017.01.04 07:45:02   ASK  = 11630.5
2017.01.17 16:09:18.206 2017.01.04 07:45:02   Спред  = 15
2017.01.17 16:09:18.206 2017.01.04 07:45:02   Профит сразу после открытия = 91.17
2017.01.17 16:09:18.206 2017.01.04 07:45:02   Профит должен быть = -37.5
2017.01.17 16:09:18.207 2017.01.04 07:45:02   Профит должен быть, добавлено = -37.5
 

Проверка на том же сервере на форексе

2017.01.17 16:28:04.923 2017.01.04 00:45:00   instant buy 1.00 EURUSD at 1.04105 (1.04075 / 1.04105 / 1.04082)
2017.01.17 16:28:04.923 2017.01.04 00:45:00   deal #2 buy 1.00 EURUSD at 1.04105 done (based on order #2)
2017.01.17 16:28:04.923 2017.01.04 00:45:00   deal performed [#2 buy 1.00 EURUSD at 1.04105]
2017.01.17 16:28:04.923 2017.01.04 00:45:00   order performed buy 1.00 at 1.04105 [#2 buy 1.00 EURUSD at 1.04105]
2017.01.17 16:28:04.949 2017.01.04 00:45:00   CTrade::OrderSend: instant buy 1.00 EURUSD at 1.04105 [done at 1.04105]
2017.01.17 16:28:04.951 2017.01.04 00:45:00   BID  = 1.04075
2017.01.17 16:28:04.951 2017.01.04 00:45:00   ASK  = 1.04105
2017.01.17 16:28:04.955 2017.01.04 00:45:00   LAST  = 1.04082
2017.01.17 16:28:04.955 2017.01.04 00:45:00   Спред  = 30
2017.01.17 16:28:04.955 2017.01.04 00:45:00   Профит сразу после открытия = -30.0
2017.01.17 16:28:04.956 2017.01.04 00:45:00   Профит должен быть = -30.0
2017.01.17 16:28:04.956 2017.01.04 00:45:00   Профит должен быть, добавлено = -30.0

Тут все четко и верно, никаких проблем.

 
ivanivan_11:
Имя сервера?
 
fxsaber:
Имя сервера?
Причина обращения: