Libraries: Virtual - page 2

 

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.

 

Dear fxsaber,

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

Is version MT4 of this program available?
 
Aliakbar Kavosi #:

Is version MT4 of this program available?

Never take files from a zip archive in the codebase.

 
fxsaber #:

Never take files from a zip archive in the codebase.

I download zip archive in the codebase and compile source. It is work correctly.
 
Aliakbar Kavosi #:
I download zip archive in the codebase and compile source. It is work correctly.

All zip archives contain old versions of the libraries. To get a new one, you need to download each file manually.