Ошибка тестера в свопах для CLOSE BY ордеров - страница 5

 
Я этот скрипт выкладывал в статьях , вот его немного модифицированный вариант. Эта статья на данный момент доступна по временному адресу - 23. Своя статистика (команда #include)

//+------------------------------------------------------------------+
//|                                                   Statistika.mq4 |
//|                                                       MetaQuotes |
//|                    http://www.alpari-idc.ru/ru/experts/articles/ |
//+------------------------------------------------------------------+
#property copyright "MetaQuotes"
#property link      "http://www.alpari-idc.ru/ru/experts/articles"
extern string TradesFileName="TradeStat.csv";
 
int StatBars;
int stat_FileHandle;
//+------------------------------------------------------------------+
//| обсчет результатов бектеста                                                          |
//+------------------------------------------------------------------+
void HistoryCalculate()
   {
   int historyTrades;
   int cancelledOrders;
   int cnt,i,znak,res,pos1,pos2;
   string curComment;
   for (cnt=HistoryTotal()-1;cnt>=0;cnt--)
      {
      if(OrderSelect(cnt,SELECT_BY_POS,MODE_HISTORY))
         {
         if (OrderType()>OP_SELL) cancelledOrders++; else historyTrades++;
         } 
      }
   TradesFileName=StringConcatenate(WindowExpertName(),".csv");   
   double trades[][13];// массив трейдов
   // 0 - тикет
   // 1 - прибыль в $
   // 2 - прибыль в пунктах
   // 3 - прибыль в $/лот
   // 4 - час открытия 
   // 5 - час закрытия
   // 6 - день недели открытия
   // 7 - день недели закрытия 
   // 8 - время удержания в мин
   // 9 - серия 
   // 10 баланс 
   // 11 коммент
   // 12 свободная информация
   string commentsTrades[][3];
   double cancells[][6]; // массив отмененных
   // 0 - тикет
   // 1 - час открытия 
   // 2 - час отмены
   // 3 - день открытия
   // 4 - день отмены
   // 5 - время удержания в мин
   ArrayResize(trades,historyTrades);
   ArrayResize(commentsTrades,historyTrades);
   ArrayResize(cancells,cancelledOrders);
   
   stat_FileHandle=FileOpen(TradesFileName,FILE_WRITE | FILE_CSV,";");
   if (stat_FileHandle<1)
      {
      Print("Не удалось открыть файл, ошибка ",GetLastError());
      return;
      }   
   cnt=0;
   // Запишем заголовки столбцов
   if(stat_FileHandle>0) res=FileWrite(stat_FileHandle,"ticket","Profit,$",
      "Profit,point","$/lot","Open Hour","Close Hour","Open Day",
      "Close Day","Hold Time","Comment","TP or SL","Order Type","Swap","Commission");
 
   Print("ордеров в истории ",HistoryTotal());
   for (i=0;i<HistoryTotal();i++)
      {
      if (OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
         {
         Print("Обработка ордера в истории на позиции ",i);
         if (OrderType()<=OP_SELL)
            {
            trades[cnt][0]=OrderTicket();
            trades[cnt][1]=OrderProfit();
            if (OrderType()==OP_BUY) znak=1; else znak=-1;
            //Print("Point=",Point,"  znak=",znak);
            trades[cnt][2]=NormalizeDouble(  (OrderClosePrice()-OrderOpenPrice())/Point*znak,0);
            //Print("Profit in points",trades[cnt][2]);
            //Print("OrderLots=",OrderLots());
            if (OrderLots()!=0) trades[cnt][3]=trades[i][1]/(OrderLots()/0.1); else trades[cnt][3]=0;
            trades[cnt][4]=TimeHour(OrderOpenTime());
            trades[cnt][5]=TimeHour(OrderCloseTime());
            trades[cnt][6]=TimeDayOfWeek(OrderOpenTime());
            trades[cnt][7]=TimeDayOfWeek(OrderCloseTime());
            trades[cnt][8]=(OrderCloseTime()-OrderOpenTime())/60;
            trades[cnt][9]=1;
            trades[cnt][10]=1;
            trades[cnt][12]=OrderSwap();
            trades[cnt][13]=OrderCommission();
            curComment=OrderComment();
            pos1=StringFind(curComment,"[tp]");
            if (pos1!=-1)
               {
               commentsTrades[cnt][0]=StringSubstr(curComment,0,pos1);
               commentsTrades[cnt][1]="[tp]";
               }
            pos2=StringFind(curComment,"[sl]");
            if (pos2!=-1)
               {
               commentsTrades[cnt][0]=StringSubstr(curComment,0,pos2);
               commentsTrades[cnt][1]="[sl]";
               }
            if (pos1==-1&&pos2==-1)
               {
               commentsTrades[cnt][0]=curComment;
               commentsTrades[cnt][1]="";
               }
            //Print("curComment=",curComment,"  pos1=",pos1,"  pos2=",pos2);
            if (OrderType()==OP_BUY) commentsTrades[cnt][2]="buy"; else commentsTrades[cnt][2]="sell";
            //Print("Запишем данные для ордера ",trades[cnt][0]);
            if(stat_FileHandle>0) res=FileWrite(stat_FileHandle,trades[cnt][0],trades[cnt][1],
               trades[cnt][2],trades[cnt][3],trades[cnt][4],trades[cnt][5],trades[cnt][6],
               trades[cnt][7],trades[cnt][8],commentsTrades[cnt][0],commentsTrades[cnt][1],
               commentsTrades[cnt][2],trades[cnt][12],trades[cnt][13]);
            if (res<0) Print("Ошибка записи в файл статистики сделок",GetLastError());  
            cnt++;
            }
         }// if (OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
      }// for (i=0;i<OrdersTotal();i++)
   FileClose(stat_FileHandle);
   return;
   }
 
 
//+------------------------------------------------------------------+
//| пустая функция                                                   |
//+------------------------------------------------------------------+
void Placebo()
   {    
   return;
   }
//+------------------------------------------------------------------+
//| defines                                                          |
//+------------------------------------------------------------------+
// #define MacrosHello   "Hello, world!"
// #define MacrosYear    2005
 
//+------------------------------------------------------------------+
//| DLL imports                                                      |
//+------------------------------------------------------------------+
// #import "user32.dll"
//   int      SendMessageA(int hWnd,int Msg,int wParam,int lParam);
 
// #import "my_expert.dll"
//   int      ExpertRecalculate(int wParam,int lParam);
// #import
 
//+------------------------------------------------------------------+
//| EX4 imports                                                      |
//+------------------------------------------------------------------+
// #import "stdlib.ex4"
//   string ErrorDescription(int error_code);
// #import
//+------------------------------------------------------------------+

Вызывается из советника вставкой в deinit()

//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   if (IsTesting()&&!IsOptimization())
      {
      
      Print("Запишем статистику");
      HistoryCalculate();
      }
//----
   return(0);
  }

В самом советнике функция HistoryCalculate() пристегивается через #include

#property copyright "Rosh"
#property link      "http://forum.viac.ru/viewtopic.php?p=68234#68234"
 
#include <Statistika.mqh>

Этот скрипт не отменяет ручного анализа, просто облегачает выгрузку данных в Excel.
 
solandr:

Rosh, киньте пожалуйста ссылочку, где можно взять скрипт для анализа сделок, которым пользуетесь Вы выше? Полезная вещь особенно для ловли всех нюансов.
Что же получается на основе этого теста? Брокер слишком добрый что ли, что можно зарабатывать только на одних свопах или мы имеем дело просто с абсолютной подгонкой?

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

 
 
Так я сразу попросил значение OrderSwap. Если бы эти данные были вчера, то вчера бы и пофиксили. Без долгих поисков истины.

Качайте исправленный билд 203 от 15 марта
 
 

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

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

Тему топика поправил на более подходящий.
 
bstone:

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


Для других экспертов последствий не будет. В тестере неправильно считались свопы для частично закрытых операцией CloseBy позиций. Теперь считаются правильно.
 
Renat:
Приношу свои извинения за свой непроверенный до конца ответ. Жаль, что эксперт не был выложен изначально.

Тему топика поправил на более подходящий.
Эксперт в виде исходников был выслан изначально в саппорт еще вчера, т.ч. пожалуйста все претензии адресуйте к своим сотрудникам. И лишь после того, как начали катить бочку на меня сегодня, я уже выложил скомпилированную версию эксперта здесь, поскольку только путем независимых исследований можно докопаться до истины.

Лучше бы заодно сменили и номер билда, потому как многие уже скачали 203 с глюками и наверняка форум не читают. А у некоторых ДЦ вообще до сих пор предлагают апдейтится только до 202 билда.
Причина обращения: