Libraries: Virtual - page 4

 

fxsaber,

Thanks for your fast reply.

Your suggestion solved the total number of trades discrepency, I tried to call Stop() using the define VIRTUAL_CLOSEALL_BYEND on top of the code.

I also add a IsNewBar test to have less trades.


// Launching a TS in real and virtual trading environments

//needed to allow tester to trade as a real strategy
#include <MT4Orders.mqh>               // https://www.mql5.com/ru/code/16006
#define VIRTUAL_TESTER                 // Launch in the virtual trading environment
#define VIRTUAL_CLOSEALL_BYEND
#include <fxsaber\Virtual\Virtual.mqh> // Virtual trading environment


input double Lots  = 1;
input int Interval = 100;  // Position lifetime
input bool Example = true; // Which example code to choose

datetime bartime;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool och_NewBar(string _symbol, ENUM_TIMEFRAMES _timeframe, datetime& _lasttime)
{

if(::iTime(_symbol,_timeframe,0) != _lasttime)
  {
   _lasttime=::iTime(_symbol,_timeframe,0);
   return (true);
  }
else
   return (false);
}

// Reversible TC
void System()
{
  
  if (!OrderSelect(OrdersTotal() - 1, SELECT_BY_POS))
    OrderSend(_Symbol, OP_BUY, Lots, SymbolInfoDouble(_Symbol, SYMBOL_ASK), 100, 0, 0); // If there is no position - open
  else if (TimeCurrent() - OrderOpenTime() > Interval) // If the position has lived longer than the specified time
  {
    // Flipped position
    OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100);
    OrderSend(_Symbol, 1 - OrderType(), Lots, OrderClosePrice(), 100, 0, 0);
  }
  //PrintFormat("%s-Line#%d::HistoryOrders.Total() = %d", __FUNCTION__, __LINE__, OrdersHistoryTotal());
}

int handle = VIRTUAL::Create(); // Created a handle for a virtual trading environment. 0 - real trading environment

void OnTick()
{
  //static const int handle = VIRTUAL::Create(); // Created a handle for a virtual trading environment. 0 - real trading environment

  if (!och_NewBar(_Symbol, _Period, bartime)) return;
  
  if (Example)
  {
    if (VIRTUAL::SelectByHandle()) // Chose a real trading environment
      System();                    // Launched the TS on the selected trading environment (real)

    if (VIRTUAL::SelectByHandle(handle)) // Chose a virtual trading environment
    {
      VIRTUAL::NewTick();      // Added a tick to the virtual trading environment
      System();                // Launched the TS on the selected trading environment (virtual)
    }
  }
  else // An alternative recording of the same actions.
    // Going through all available trading environments
    for (int i = 0; i <= VIRTUAL::Total(); i++)
      if (VIRTUAL::SelectByIndex(i)) // Chose the appropriate trading environment
      {
        VIRTUAL::NewTick(); // Added a tick to the selected trading environment

        System(); // Launched the TS on the selected trading environment
      }

  Comment(VIRTUAL::ToString()); // Brought to the chart the state of the virtual trading environment
}

void OnDeinit(const int reason)
{
  VIRTUAL::SelectByHandle();
  PrintFormat("(%s-%s)::%s - Initial deposit=%.2f, Balance=%.2f, Equity=%.2f, Profit=%G, Trades=%d", _Symbol, EnumToString(_Period), "Real", 0,AccountBalance(), AccountEquity(), AccountProfit(), OrdersHistoryTotal());
  VIRTUAL::SelectByHandle(handle);
  VIRTUAL::Stop();
  PrintFormat("(%s-%s)::%s - Initial deposit=%.2f, Balance=%.2f, Equity=%.2f, Profit=%G, Trades=%d", _Symbol, EnumToString(_Period), "Virtual", 0,AccountBalance(), AccountEquity(), AccountProfit(), OrdersHistoryTotal());
                                                                        
  Comment("");
}


But according to me the balance, should be the (initial deposit - profit) and profit should be (initial deposit - tradeloss + tradeprofit), as we can see in the backtester results for the real TS.

So the balance is correct, but the profit can't be (balance - equity) as it is defined in Orders.mqh

 double AccountProfit( void ) const
  {
    return(::NormalizeDouble(this.Equity - this.Balance, 2));
  }

I don't understand neither why AccountInfoDouble(ACCOUNT_PROFIT) return 0 for the real TS.

  static double VirtualAccountProfit( void )
  {
    return(VIRTUAL::SelectOrders ? VIRTUAL::SelectOrders.AccountProfit() : ::AccountInfoDouble(ACCOUNT_PROFIT));
  }

Am I wrong?




 
och:

fxsaber,

Thanks for your fast reply.

Your suggestion solved the total number of trades discrepency, I tried to call Stop() using the define VIRTUAL_CLOSEALL_BYEND on top of the code.

I also add a IsNewBar test to have less trades.



But according to me the balance, should be the (initial deposit - profit) and profit should be (initial deposit - tradeloss + tradeprofit), as we can see in the backtester results for the real TS.

So the balance is correct, but the profit can't be (balance - equity) as it is defined in Orders.mqh

I don't understand neither why AccountInfoDouble(ACCOUNT_PROFIT) return 0 for the real TS.

Am I wrong?





So not a very elegant way of solving the issue, still have to investigate for the Virtual TS :

void OnDeinit(const int reason)
{
  //--- compute real TS figures
  VIRTUAL::SelectByHandle();
  OrderSelect(1, SELECT_BY_TICKET, MODE_HISTORY);
  double deposit = OrderProfit();
  double profit = AccountBalance() - deposit;
  PrintFormat("(%s-%s)::%s - Initial deposit=%.2f, Balance=%.2f, Equity=%.2f, Profit=%G, Trades=%d", _Symbol, EnumToString(_Period), "Real", deposit,AccountBalance(), AccountEquity(), profit, OrdersHistoryTotal());
  
  //--- compute Virtual TS figures
  VIRTUAL::SelectByHandle(handle);
  VIRTUAL::Stop();
  OrderSelect(1, SELECT_BY_TICKET, MODE_HISTORY);
  deposit = OrderProfit();
  profit = AccountBalance() - deposit;
  PrintFormat("(%s-%s)::%s - Initial deposit=%.2f, Balance=%.2f, Equity=%.2f, Profit=%G, Trades=%d", _Symbol, EnumToString(_Period), "Virtual", deposit,AccountBalance(), AccountEquity(), profit, OrdersHistoryTotal());
                                                                        
  Comment("");
}
  
 
och:

But according to me the balance, should be the (initial deposit - profit) and profit should be (initial deposit - tradeloss + tradeprofit), as we can see in the backtester results for the real TS.

So the balance is correct, but the profit can't be (balance - equity) as it is defined in Orders.mqh

I don't understand neither why AccountInfoDouble(ACCOUNT_PROFIT) return 0 for the real TS.

Am I wrong?

ACCOUNT_PROFIT is equal to the sum of the profits of all current open positions.

 
och:

So not a very elegant way of solving the issue, still have to investigate for the Virtual TS :

  double deposit = TesterStatistics(STAT_INITIAL_DEPOSIT);
  double profit = TesterStatistics(STAT_PROFIT);
 

fxsaber,

Once again thanks for your support and your reactivity.

I update a little bit the code agin, and I tried to separate the use of TS environnement.

I understand the result when we are using real or virtual environnement. Results are as expected.

I don't understand the results when we try to use both environnement at the same time.

Would it be possible to extract as a CSV file the list of orders?

Best regards,

och

// Launching a TS in real and virtual trading environments

//needed to allow tester to trade as a real strategy
#include <MT4Orders.mqh>               // https://www.mql5.com/ru/code/16006
#define VIRTUAL_TESTER                 // Launch in the virtual trading environment
//#define VIRTUAL_CLOSEALL_BYEND
#include <fxsaber\Virtual\Virtual.mqh> // Virtual trading environment

enum ENUM_TRADING_TYPE{
   TRADING_TYPE_REAL,         // Use Real Environnement
   TRADING_TYPE_VIRTUAL,      // Use Virtual Environnement
   TRADING_TYPE_BOTH          // Use both
};

input double               Lots  = 1;
input int                  Interval = 100;                     // Position lifetime
//input bool                 Example = true;                     // Which example code to choose
input ENUM_TRADING_TYPE    Trading_type = TRADING_TYPE_REAL;   // Trqding Type

datetime bartime;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool och_NewBar(string _symbol, ENUM_TIMEFRAMES _timeframe, datetime& _lasttime)
{

if(::iTime(_symbol,_timeframe,0) != _lasttime)
  {
   _lasttime=::iTime(_symbol,_timeframe,0);
   return (true);
  }
else
   return (false);
}

// Reversible TC
void System()
{
  
  if (!OrderSelect(OrdersTotal() - 1, SELECT_BY_POS))
    OrderSend(_Symbol, OP_BUY, Lots, SymbolInfoDouble(_Symbol, SYMBOL_ASK), 100, 0, 0); // If there is no position - open
  else if (TimeCurrent() - OrderOpenTime() > Interval) // If the position has lived longer than the specified time
  {
    // Flipped position
    OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100);
    OrderSend(_Symbol, 1 - OrderType(), Lots, OrderClosePrice(), 100, 0, 0);
  }
  //PrintFormat("%s-Line#%d::HistoryOrders.Total() = %d", __FUNCTION__, __LINE__, OrdersHistoryTotal());
}

int handle = VIRTUAL::Create(); // Created a handle for a virtual trading environment. 0 - real trading environment

void OnTick()
{
  //static const int handle = VIRTUAL::Create(); // Created a handle for a virtual trading environment. 0 - real trading environment

  if (!och_NewBar(_Symbol, _Period, bartime)) return;
  
  //if (Example)
  {
    switch(Trading_type){
      case TRADING_TYPE_REAL     :    if (VIRTUAL::SelectByHandle())       // Chose a real trading environment
                                          System();                        // Launched the TS on the selected trading environment (real)
                                      break;
                                        
      case TRADING_TYPE_VIRTUAL  :    if (VIRTUAL::SelectByHandle(handle)) // Chose a virtual trading environment
                                        {
                                          VIRTUAL::NewTick();              // Added a tick to the virtual trading environment
                                          System();                        // Launched the TS on the selected trading environment (virtual)
                                        }
                                      break;
                                      
      case TRADING_TYPE_BOTH     :    if (VIRTUAL::SelectByHandle())       // Chose a real trading environment
                                          System();                        // Launched the TS on the selected trading environment (real)
                                      break;
                                        
                                      if (VIRTUAL::SelectByHandle(handle)) // Chose a virtual trading environment
                                        {
                                          VIRTUAL::NewTick();              // Added a tick to the virtual trading environment
                                          System();                        // Launched the TS on the selected trading environment (virtual)
                                        }
                                      break;
    }
  }
//  else // An alternative recording of the same actions.
//    // Going through all available trading environments
//    for (int i = 0; i <= VIRTUAL::Total(); i++)
//      if (VIRTUAL::SelectByIndex(i)) // Chose the appropriate trading environment
//      {
//        VIRTUAL::NewTick(); // Added a tick to the selected trading environment
//
//        System(); // Launched the TS on the selected trading environment
//      }

  Comment(VIRTUAL::ToString()); // Brought to the chart the state of the virtual trading environment
}

void OnDeinit(const int reason)
{
  double deposit, profit;
  //--- compute real TS figures
  if (Trading_type != TRADING_TYPE_VIRTUAL){
     VIRTUAL::SelectByHandle();
     OrderSelect(1, SELECT_BY_TICKET, MODE_HISTORY);
     deposit = TesterStatistics(STAT_INITIAL_DEPOSIT);
     profit = TesterStatistics(STAT_PROFIT);
     PrintFormat("(%s-%s)::%s - Initial deposit=%.2f, Balance=%.2f, Equity=%.2f, Profit=%G, Trades=%d", _Symbol, EnumToString(_Period), "Real", deposit,AccountBalance(), AccountEquity(), profit, OrdersHistoryTotal());
  }
  
  if (Trading_type != TRADING_TYPE_REAL){
     //--- compute Virtual TS figures
     VIRTUAL::SelectByHandle(handle);
     VIRTUAL::Stop();
     deposit = TesterStatistics(STAT_INITIAL_DEPOSIT);
     profit = TesterStatistics(STAT_PROFIT);
     PrintFormat("(%s-%s)::%s - Initial deposit=%.2f, Balance=%.2f, Equity=%.2f, Profit=%G, Trades=%d", _Symbol, EnumToString(_Period), "Virtual", deposit,AccountBalance(), AccountEquity(), profit, OrdersHistoryTotal());
  }                                                                      
  Comment("");
}
 
och:

I don't understand the results when we try to use both environnement at the same time.

The library has many use cases. You are looking at an example of a general view.

Would it be possible to extract as a CSV file the list of orders?

In the example below, you can change the trading environment in the input parameters: real or virtual.

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

#define VIRTUAL_TESTER                 // Launch in the virtual trading environment
#define VIRTUAL_CLOSEALL_BYEND
#include <fxsaber\Virtual\Virtual.mqh> // Virtual trading environment

input double                inLots  = 1 ;
input int                   inInterval = 100 ;                     // Position lifetime

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool och_NewBar( string _symbol, ENUM_TIMEFRAMES _timeframe )
{
static datetime _lasttime = 0;

if (:: iTime (_symbol,_timeframe, 0 ) != _lasttime)
  {
   _lasttime=:: iTime (_symbol,_timeframe, 0 );
   return ( true );
  }
else
   return ( false );
}

// Reversible TC
void System()
{
  
   if (! OrderSelect ( OrdersTotal () - 1 , SELECT_BY_POS))
     OrderSend ( _Symbol , OP_BUY, inLots, SymbolInfoDouble ( _Symbol , SYMBOL_ASK ), 100 , 0 , 0 ); // If there is no position - open
   else if ( TimeCurrent () - OrderOpenTime() > inInterval) // If the position has lived longer than the specified time
  {
     // Flipped position
    OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 100 );
     OrderSend ( _Symbol , 1 - OrderType(), inLots, OrderClosePrice(), 100 , 0 , 0 );
  }
   //PrintFormat("%s-Line#%d::HistoryOrders.Total() = %d", __FUNCTION__, __LINE__, OrdersHistoryTotal());
}

void OnTick ()
{
   if (!och_NewBar( _Symbol , _Period)) return ;
   
   System();
}

#define REPORT_TESTER             // В тестере будут автоматически записываться отчеты
// #define REPORT_INTERACTIVE_CHARTS // Добавляет в отчет интерактивные графики.
#define REPORT_BROWSER            // Создание отчета с запуском браузера - требует разрешения DLL.
#include <Report.mqh> // https://www.mql5.com/ru/code/22577


The lines at the bottom create an HTML report. If you enable the DLL, then this report will automatically appear in the browser at the end of testing.

 
Automated-Trading :

Virtual :

Author: fxsaber

Hi may I know the library work for mt4?

As while i importing the library, having some compilation error, thanks

Files:
 
You Lin Lee:

Hi may I know the library work for mt4?

As while i importing the library, having some compilation error, thanks

It is MQL4-bug! Base thread is here.

 

Forum on trading, automated trading systems and testing trading strategies

MT5 and speed in combat performance

fxsaber, 2021.03.01 12:19 pm.

// Quick SymbolInfoTick.
bool SymbolInfoTickFast( const string &Symb, MqlTick &Tick )
{
  return((Symb == _Symbol) ? SymbolInfoTick(_Symbol, Tick)
                           : SymbolInfoTick(Symb, Tick));
}

Implementing this fact in Virtual is able to speed it up in a real environment.

 

Dear fxsaber,

Thank you for your kindness.This tool is very useful.

Is version MT4 of this program available?