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

 
Stanislav Korotky:

Если этого не сделать, то не получится виртуальной торговли -- только из-за этого макроса переопределяется OnTick.

Использование этого макроса нужно для того, чтобы никто не заморачивался в возможностях Virtual и сразу получал нужный результат. Макрос просто делает всю работу за пользователя, чтобы можно было ТС запустить в виртуалке. Вам же не нужно ее там запускать. А требуется сделать автооптимизацию.

Все равно дата "баланса" не должна из-за этого съезжать на конец истории, ИМХО.

Именно из-за этого и съезжает. Плюс еще возникает громоздкость, которую мне даже не хочется объяснять, т.к. текстом очень неудобно.

 
Stanislav Korotky:

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

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

 

с Virtual уже взлетал мой первый тестовый ЕА, 

попробовал посерьезнее проект в Virtual подключить... не взлетел с первого раза, 

проблема оказалась банальной, в моем ЕА тоже есть class ORDERS и соответственно 1000 и 1 ошибка компиляции получилась при совпадении имен

я уже попадал на такую ошибку в своих инклудниках, теперь если инклудник считаю отлаженным и завершенным, то стараюсь глобальные описания переменных (имена ) в инклудниках писать по принципу имен которые сомневаюсь, что буду использовать


в качестве пожелания к библиотеке: хотелось бы примерно как __ORDERS__ 

 

такой еще вопрос по использованию Virtual

код моего ЕА:

CHALF_SYSTEM EA;

void OnTick()
{
   MqlTick  Tick;
   SymbolInfoTick(_Symbol, Tick);
   EA.onTick(Tick);
}

внутри класса не использую другого получения рыночной информации, только передачей переменной Tick в метод onTick

если напишу такой код:

void OnTick()
{
   static const int V_handle = VIRTUAL::Create();
   
   if (VIRTUAL::SelectByHandle(V_handle)) // Выбрали виртуальное торговое окружение
   {
      VIRTUAL::NewTick();      // Добавили тик в виртуальное торговое окружение
   
      MqlTick  Tick;
      SymbolInfoTick(_Symbol, Tick);
      EA.onTick(Tick);
      Comment(VIRTUAL::ToString()); // Вывели на чарт состояние виртуального торгового окружения
   }
}


откуда буду получать данные для Tick  - из виртуального окружения? 

 
Igor Makanu:

откуда буду получать данные для Tick  - из виртуального окружения? 

Да, из виртуального.


SelectByHandle каждый раз, наверное, делать не нужно.

Что касается тика реального окружения, то есть удобный макрос.

_V(Handle, Function()); // Заходит в Handle-окружение, выполняет там Function() и возвращается обратно.

Соответственно, пишите так.

_V(0, SymbolInfoTick(_Symbol, Tick));


ЗЫ Пример.

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

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

fxsaber, 2020.08.29 12:09

bool CreateHistory( const int Amount = 10000 )
{
  const bool Res = VIRTUAL::GetHandle();
  
  if (Res)
  {
    MqlTick Tick;
    
    _V(0, SymbolInfoTick(_Symbol, Tick));
    VIRTUAL::NewTick(Tick);
        
    for (int i = 0; i < Amount; i++)
    {      
      const TICKET_TYPE Ticket = OrderSend(_Symbol, OP_BUY, 1, Tick.ask, 0, 0, 0);
      
      Tick.time_msc += 1000;
      VIRTUAL::NewTick(Tick);
      
      OrderClose(Ticket, 1, Tick.bid, 0);            
    }
  }
  
  return(Res);
}
 
fxsaber:

SelectByHandle каждый раз, наверное, делать не нужно.

проверил опять на предложенном в КБ коде (описание Virtual)

input double Lots = 1;
input int Interval = 100;  // Время жизни позиции

#include <MT4Orders.mqh>
#include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/ru/code/22577

const int handle = VIRTUAL::Create();

//+------------------------------------------------------------------+
void OnTick()
{
   if(VIRTUAL::SelectByHandle(handle)) // работает
//   if(VIRTUAL::GetHandle())            // ничего не происходит
   {
      VIRTUAL::NewTick(); // Добавили тик в выбранное торговое окружение
      
      MqlTick  Tick;
      _V(0, SymbolInfoTick(_Symbol, Tick));
      
      if (!OrderSelect(OrdersTotal() - 1, SELECT_BY_POS))
         OrderSend(_Symbol, OP_BUY, Lots, Tick.ask, 100, 0, 0); // Если нет позиции - открываем
      else if (TimeCurrent() - OrderOpenTime() > Interval) // Если позиция прожила больше заданного времени
      {
         // Перевернули позицию
         OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100);
         OrderSend(_Symbol, 1 - OrderType(), Lots, OrderClosePrice(), 100, 0, 0);
      }
   Comment(VIRTUAL::ToString()); // Вывели на чарт состояние виртуального торгового окружения
   }
}
//+------------------------------------------------------------------+

если использовать  VIRTUAL::GetHandle()  - ничего не работает


опять я  не правильно использую Virtual  ?

 
Igor Makanu:

опять я  не правильно использую Virtual  ?

SelectByHandle сделали один раз - все, теперь постоянно находитесь в соответствующем торговом окружении. Пока не сделаете другой Select. Поэтому логично так.

const bool InitHandle = VIRTUAL::SelectByHandle(VIRTUAL::Create());

//+------------------------------------------------------------------+
void OnTick()
{
//   if(VIRTUAL::SelectByHandle(handle)) // работает
//   if(VIRTUAL::GetHandle())            // ничего не происходит
  if (InitHandle) // Сложно представить ситуацию, чтобы было false, но для формальности можно. Сам и этой проверки не делаю.
 
fxsaber:

SelectByHandle сделали один раз - все, теперь постоянно находитесь в соответствующем торговом окружении. Пока не сделаете другой Select. Поэтому логично так.

OK, немного начинаю представлять как это работает

тогда из КБ пример так работать будет:

//const int h = VIRTUAL::Create();

const bool InitHandle = VIRTUAL::SelectByHandle(VIRTUAL::Create());

//+------------------------------------------------------------------+
int OnInit()
{
  // Print("V handle = ",h);     // 2020.09.02 23:54:10.463     tstVIRTUAL (EURUSD,H1)  V handle = 1
   if(!InitHandle) return(INIT_FAILED);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnTick()
{
   VIRTUAL::NewTick(); // Добавили тик в выбранное торговое окружение

   MqlTick  Tick;
   _V(1, SymbolInfoTick(_Symbol, Tick));

   if (!OrderSelect(OrdersTotal() - 1, SELECT_BY_POS))
      OrderSend(_Symbol, OP_BUY, Lots, Tick.ask, 100, 0, 0); // Если нет позиции - открываем
   else if (TimeCurrent() - OrderOpenTime() > Interval) // Если позиция прожила больше заданного времени
   {
      // Перевернули позицию
      OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100);
      OrderSend(_Symbol, 1 - OrderType(), Lots, OrderClosePrice(), 100, 0, 0);
   }
   Comment(VIRTUAL::ToString()); // Вывели на чарт состояние виртуального торгового окружения
}
//+------------------------------------------------------------------+
 
Igor Makanu:

тогда из КБ пример так работать будет:

_V(1, SymbolInfoTick(_Symbol, Tick)); // Вы уже находитесь в 1-м окружении, поэтому _V-макрос лишний.

VIRTUAL::NewTick() пробросил свежий тик в виртуалку. SymbolInfoTick подхватит его из виртуалки, т.к. виртуалка выбрана в качестве текущего торгового окружения.

 
fxsaber:

VIRTUAL::NewTick() пробросил свежий тик в виртуалку. SymbolInfoTick подхватит его из виртуалки, т.к. виртуалка выбрана в качестве текущего торгового окружения.

ОК, тогда вообще для простого юзера ничего не нужно делать со своим исходным ЕА

достаточно так написать в OnInit()

input double Lots = 1;
input int Interval = 100;  // Время жизни позиции

#include <MT4Orders.mqh>
#include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/ru/code/22577

//+------------------------------------------------------------------+
int OnInit()
{
   if(!VIRTUAL::SelectByHandle(VIRTUAL::Create())) return(INIT_FAILED);
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnTick()
{
   VIRTUAL::NewTick(); // Добавили тик в выбранное торговое окружение

   MqlTick  Tick;
   SymbolInfoTick(_Symbol, Tick);

   if (!OrderSelect(OrdersTotal() - 1, SELECT_BY_POS))
      OrderSend(_Symbol, OP_BUY, Lots, Tick.ask, 100, 0, 0); // Если нет позиции - открываем
   else if (TimeCurrent() - OrderOpenTime() > Interval) // Если позиция прожила больше заданного времени
   {
      // Перевернули позицию
      OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100);
      OrderSend(_Symbol, 1 - OrderType(), Lots, OrderClosePrice(), 100, 0, 0);
   }
   Comment(VIRTUAL::ToString()); // Вывели на чарт состояние виртуального торгового окружения
}
//+------------------------------------------------------------------+