Библиотеки: Virtual - страница 18

 
Ilya Malev:

Дело не в кастомных, они - лишь инструмент

Дело в том, что нужно текущий спред для тестинга по OHLC сделать таким, каким он и должен быть, причем, независимо от "рабочего" ТФ. Пока думаю, что проще всего не заморачиваться с тиками, а скопировать рейты и по очереди в них пересчитать макс спред перебором входящих в них тиков...

Именно такая функция мне и нужна была, собственно, и больше ничего.

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

ТФ в MT5 только один - M1. Так что никакой там зависимости от ТФ быть не может.

 

В общем как-то вот так (вроде работает, и быстро. Хотя не отлаживал - подустал уже ))

#property strict
#property script_show_inputs

input datetime start = D'2018.09.01';
input string posf = "&";

void OnStart()
 {
  MqlTick mt[];
  MqlRates mr[];
  string sym = _Symbol, csym = sym + posf;
  ulong from = start, from_msc = from * 1000;
  double point = SymbolInfoDouble(sym,SYMBOL_POINT);
  int err = 0, i = 0, j = 0;

  ResetLastError();
  while( !_StopFlag && ( ( CopyTicksRange( sym, mt, COPY_TICKS_INFO, from_msc, TimeCurrent()*1000 ) <= 0 ) || ( err = GetLastError() ) == 4403 ) )
   {
    Print((string)datetime(from)+" copy ticks error :("+(string)err+")");
    ResetLastError();
   }
  if(_StopFlag)
   {
    return;
   }

  SymbolSelect( csym, false );
  CustomSymbolDelete( csym );
  
  ResetLastError();
  if( ! CustomSymbolCreate( csym, NULL, sym ) )
   {
    printf("Cannot create custom symbol %s (%i)!", csym, GetLastError() );
    return;
   }

  ResetLastError();
  if( ! SymbolSelect( csym, true ) || ( err = GetLastError() ) != 0 )
   {
    printf("Cannot select custom symbol %s (%i)!", csym, err);
    return;
   }

  ResetLastError();
  if( ! CopyRates( sym, PERIOD_M1, start, TimeCurrent(), mr) || ( err = GetLastError() ) != 0 )
   {
    printf("Cannot copy rates for %s (%i)!", sym, err );
    return;
   }
   
  while(!_StopFlag&&i<ArraySize(mr)&&j<ArraySize(mt))
   {
    if(i%1000==0)Comment(string(datetime(mr[i].time)));
    
    while(mt[j].time<mr[i].time&&j<ArraySize(mt)) j++;
    if(j>=ArraySize(mt)) break;
    if(mt[j].time>=mr[i].time+60){ i++; continue; }

    double max_sp=0;
    while(j<ArraySize(mt)&&mt[j].time<mr[i].time+60)
     {
      max_sp=fmax(max_sp,mt[j].ask-mt[j].bid);
      j++;
     }
    mr[i].spread=int(ceil(max_sp/point));
    mr[i].tick_volume=4;
    i++;
   }
  Comment("");
  ResetLastError();
  if(CustomRatesReplace(csym,from,TimeCurrent(),mr)<=0||(err=GetLastError())!=0)
   {
    printf("Failed replacing rates for %s (%i)!", csym, err );
    return;
   }
  Print("Success!");
 }
 

Из-за того, что в Тестере в большинстве режимов цены могут быть ненормализованы, результаты Virtual могут отличаться от Тестера.

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

 
fxsaber:

Кому нужен в MT5 Тестер ручной торговли, простая идея.

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

Это и есть Визуализатор! На него, как и в MT4, можете вешать индикаторы и.. "торговать" вручную.


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

Virtual все это умеет изначально, только визуализация не сделана.

Реализация этой идеи выложена в КБ.

 
fxsaber:

Реализация этой идеи выложена в КБ.

А картинку с анимацией приложить? ;-)

 
Stanislav Korotky:

А картинку с анимацией приложить? ;-)

Тоже ужаснулся, когда увидел их размер.

Щелкните по изображению, чтобы увидеть анимацию.

 
fxsaber:

Тоже ужаснулся, когда увидел их размер.

Что-то не увидел ручной торговли.

Размер зависит от софта, попробуйте LiceCap.

 
Stanislav Korotky:

Что-то не увидел ручной торговли.

В КБ анимашка.

 

Только сейчас понял, что имелось в виду в этом предложении. Нужно было, чтобы на неттинг-счете работала хеджевая ТС.

Это, конечно, работает без проблем.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Библиотеки: Virtual

fxsaber, 2018.11.15 17:16

На Netting позиция всегда имеет только один TP. Поэтому, в частности, сеточные ТС, у которых каждой ордер в сетке имеет свой TP не будет работать, как задумывалось.

Ниже пример, как это обходится

// Пример Netting с поддержкой множества однонаправленных позиций (у каждой могут быть свои Magic, SL/TP, Comment, OpenTime и т.д.).
// Запустите этот пример на Netting-счете в Тестере с влюченной Визуализацией.

#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006

#define VIRTUAL_LIMITS_TP_SLIPPAGE // Лимитники и TP исполняются по первой цене акцепта - положительные проскальзывания
#include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/ru/code/22577
#include <fxsaber\Virtual\Sync.mqh>    // Синхронизатор

#define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)

input int iAmount = 5;   // Количество ордеров в сетке
input int iOffset = 120; // На каком расстоянии (в пипсах) ставить ордера сетки
input int iTP = 120;     // TakeProfit каждого ордера сетки

// Выставляем один раз сетку из Amount ордеров на Offset-расстоянии друг от друга с заданным TP.
void System( const int Amount, const int Offset, const int TP )
{
  static bool FirstRun = true;
  
  if (FirstRun)  
  {
    for (int i = 1; i <= Amount; i++)
    {
      const double PriceOpen = Ask - i * Offset * _Point;
      const double PriceTP = PriceOpen + TP * _Point;
      
      OrderSend(_Symbol, OP_BUYLIMIT, 1, PriceOpen, 0, 0, PriceTP, (string)i); // Выставляем каждый ордер сетки
    }
    
    FirstRun = false;
  }
}

void OnTick()
{  
  static const bool Init = VIRTUAL::Select(VIRTUAL::Create()); // Система будет работать в этом виртуальном окружении
  static const bool IsVisual = MQLInfoInteger(MQL_VISUAL_MODE);
  static bool FirstRun = true;

  VIRTUAL::NewTick();            // Добавили тик в виртуальное торговое окружение
  System(iAmount, iOffset, iTP); // Запустили ТС на выбранном торговом окружении (виртуальное)
  
  SYNC::Positions<ISTIME>(); // Синхронизировли реальное торговое окружение с виртуальным

  if (IsVisual)
    Comment(VIRTUAL::ToString(true)); // Вывели на чарт состояние виртуального торгового окружения (true - вместе с историей торгов)
}


Идея простейшая. Запустили ТС в виртуальном, а в реальном просто синхронизируем. Исходник ТС менять не нужно (функция System в примере).


ЗЫ Точно так же на той же Бирже можно уменьшить количество реальных торговых приказов, чтобы не превышать лимит на них.

 
fxsaber:

Только сейчас понял, что имелось в виду в этом предложении. Нужно было, чтобы на неттинг-счете работала хеджевая ТС.

Это, конечно, работает без проблем.

На Netting позиция всегда имеет только один TP. Поэтому, в частности, сеточные ТС, у которых каждой ордер в сетке имеет свой TP не будет работать, как задумывалось.

Вы очень близки к правильному решению. 

Но пробовать скачивать и запускать пример второй раз не хочется.

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

По моему одного инклуда достаточно, чтобы оставаться в рамках вашей МТ4 логики и работать на МТ5.

Про индикаторы вообще уже не говорю, знаю вы их не любите.

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