2026-04-27 22:49:28 -05:00
//+------------------------------------------------------------------+
//| Run.mqh |
//| Copyright 2026, Niquel Mendoza. |
//| https://www.mql5.com/es/users/nique_372 |
//+------------------------------------------------------------------+
# property copyright " Copyright 2026, Niquel Mendoza. "
# property link " https://www.mql5.com/es/users/nique_372 "
2026-04-28 08:52:21 -05:00
# property strict
2026-04-28 10:48:57 -05:00
# ifndef FULLMT5MCPBYLEO_SRC_COMPLEX_COMPLEX_MQH
# define FULLMT5MCPBYLEO_SRC_COMPLEX_COMPLEX_MQH
2026-04-28 08:52:21 -05:00
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
# include "..\\Def\\Def.mqh"
2026-04-28 13:11:53 -05:00
2026-04-28 08:52:21 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
2026-06-03 20:39:25 -05:00
namespace TSN
{
2026-04-28 08:52:21 -05:00
class CMcpFunctionRunBacktest : public CMcpFunction
{
private :
long m_chart_id_runner ;
const long m_current_chart_id ;
public :
2026-06-30 16:58:14 -05:00
CMcpFunctionRunBacktest ( void ) : CMcpFunction ( 0 , false , " run_mt5_tester " ) ,
m_current_chart_id ( ChartID ( ) ) , m_chart_id_runner ( 0 )
2026-06-30 13:59:02 -05:00
{
m_chart_id_runner = DEFMTTesterGetChartId ( ) ;
}
2026-04-28 08:52:21 -05:00
~ CMcpFunctionRunBacktest ( void ) { }
void Run ( CJsonNode & param , string & res ) override final ;
} ;
//+------------------------------------------------------------------+
void CMcpFunctionRunBacktest : : Run ( CJsonNode & param , string & res )
{
2026-06-30 13:59:02 -05:00
//---
if ( m_chart_id_runner = = 0 )
{
m_chart_id_runner = DEFMTTesterGetChartId ( ) ;
}
2026-04-28 08:52:21 -05:00
//---
static MTTesterTask task ;
task . symbol = param [ " symbol " ] . ToString ( " " ) ;
task . set_file = param [ " set_file_name " ] . ToString ( " " ) ;
task . expert_path = param [ " expert_path " ] . ToString ( " " ) ;
2026-06-30 16:58:14 -05:00
task . chart_id_from = m_current_chart_id ; // Viene de aqui.. (auqneu igual no recibiremos el evento..)
2026-04-28 08:52:21 -05:00
task . start_date = StringToTime ( param [ " start_date " ] . ToString ( " 0 " ) ) ;
task . end_date = StringToTime ( param [ " end_date " ] . ToString ( " 0 " ) ) ;
2026-06-28 22:09:10 -05:00
task . timeframe = CEnumRegBasis : : GetValNoRef < ENUM_TIMEFRAMES > ( param [ " timeframe " ] . ToString ( ) , _Period ) ;
2026-04-28 08:52:21 -05:00
task . leverage = ( uint16_t ) param [ " leverage " ] . ToInt ( 0 ) ;
task . visual_mode = param [ " visual_mode " ] . ToBool ( false ) ;
2026-06-30 16:58:14 -05:00
task . modelado = CEnumRegFullMt5Mcp : : GetValNoRef < int8_t > ( param [ " modelado " ] . ToString ( ) ,
-1 ) ; // usar el que viene por defecto..
task . opt_mode = CEnumRegFullMt5Mcp : : GetValNoRef < int8_t > ( param [ " opt_mode " ] . ToString ( ) ,
-1 ) ; // usar el que viene por defecto..
task . criterio_opt = CEnumRegFullMt5Mcp : : GetValNoRef < int8_t > ( param [ " optimization_criterion " ] . ToString ( ) ,
-1 ) ; // usar el que viene por defecto..
task . forward_mode = CEnumRegFullMt5Mcp : : GetValNoRef < int8_t > ( param [ " forward_mode " ] . ToString ( ) ,
-1 ) ; // usar el que viene por defecto..
task . delay_ms = ( int ) param [ " delay_ms " ] . ToInt ( -2 ) ; // usar el que viene por defecto
task . forward_date = ( datetime ) param [ " forward_date " ] . ToInt ( 0 ) ;
2026-04-28 08:52:21 -05:00
//---
2026-04-28 10:48:57 -05:00
const bool common = param [ " file_in_common " ] . ToBool ( true ) ;
2026-06-30 16:58:14 -05:00
const string fn = param [ " data_file_name " ] . ToString ( " tester_instruction.bin " ) ;
2026-06-30 10:46:22 -05:00
: : ResetLastError ( ) ;
2026-06-30 16:58:14 -05:00
const int fh = FileOpen ( fn , FILE_WRITE | FILE_BIN | ( common ? FILE_COMMON : 0 ) ) ;
2026-06-30 10:46:22 -05:00
if ( fh = = INVALID_HANDLE )
{
res = StringFormat ( " { \" ok \" :false, \" error \" : \" Error write data in file[%s], last mt5 error = %d \" } " , fn , : : GetLastError ( ) ) ;
return ;
}
2026-06-30 16:58:14 -05:00
task . Save ( fh ) ;
2026-04-28 08:52:21 -05:00
FileClose ( fh ) ;
//---
2026-04-28 10:48:57 -05:00
: : ResetLastError ( ) ;
2026-04-28 08:52:21 -05:00
if ( ! : : EventChartCustom ( m_chart_id_runner , DEFMTTESTER_E_ON_TASK , m_current_chart_id , DEFMTTESTER_TO_DBL_ON_TASK ( true ) , fn ) )
{
2026-06-30 13:59:02 -05:00
res = StringFormat ( " { \" ok \" :false, \" error \" : \" Error to send event to run backtest, last err = %d, Ask the user if they have the Runner.ex5 bot running in their terminal, since this bot launches the tester itself; it only gives the command \" } " ,
: : GetLastError ( ) ) ;
2026-04-28 10:48:57 -05:00
}
else
{
2026-06-30 16:58:14 -05:00
res = " { \" ok \" :true, \" result \" : \" Execution command sent to Runner.ex5, this should launch the MT5 strategy tester \" } " ;
2026-04-28 10:48:57 -05:00
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CMcpFunctionRunEA : public CMcpFunction
{
public :
CMcpFunctionRunEA ( void ) : CMcpFunction ( 0 , false , " run_ea " ) { }
~ CMcpFunctionRunEA ( void ) { }
void Run ( CJsonNode & param , string & res ) override final ;
} ;
/*
{
" symbol " : " XAUUSD " ,
" timeframe " : " PERIOD_M1 " ,
" ms_espera " : 1500 ,
" expert_path " : " Experts \\ MiEA.ex5 " ,
" run_flags " : " DLL|AutoTrading "
" params " : [
{
" data_type " : " TYPE_STRING " ,
" value " : " 10.0 "
}
]
}
* /
//+------------------------------------------------------------------+
void CMcpFunctionRunEA : : Run ( CJsonNode & param , string & res )
{
: : ResetLastError ( ) ;
2026-06-28 22:09:10 -05:00
const long chart_id = OpenChartAndDevoler ( ChartID ( ) , param [ " symbol " ] . ToString ( _Symbol ) , CEnumRegBasis : : GetValNoRef < ENUM_TIMEFRAMES > ( param [ " timeframe " ] . ToString ( ) , _Period ) , int ( param [ " ms_espera " ] . ToInt ( 750 ) ) ) ;
2026-04-28 10:48:57 -05:00
if ( chart_id = = -1 )
{
2026-04-29 21:15:35 -05:00
res = StringFormat ( " { \" ok \" :false, \" error \" : \" Error open chart, last mt5 err = %d \" } " , : : GetLastError ( ) ) ;
2026-07-01 11:41:37 -05:00
return ;
2026-04-28 10:48:57 -05:00
}
//---
const int t = param [ " params " ] .Size ( ) ;
//---
MqlParam exp_param [ ] ;
ArrayResize ( exp_param , t + 1 ) ;
exp_param [ 0 ] . type = TYPE_STRING ;
exp_param [ 0 ] . string_value = param [ " expert_path " ] . ToString ( ) ;
//---
2026-07-01 11:41:37 -05:00
if ( t > 0 )
2026-04-28 10:48:57 -05:00
{
2026-07-01 11:41:37 -05:00
CJsonIteratorArray it = param [ " params " ] . BeginArr ( ) ;
int k = 1 ;
while ( it . IsValid ( ) )
2026-04-28 10:48:57 -05:00
{
2026-07-01 11:41:37 -05:00
//---
CJsonNode parametro = it . Val ( ) ;
exp_param [ k ] . type = CEnumRegBasis : : GetValNoRef < ENUM_DATATYPE > ( parametro [ " data_type " ] . ToString ( ) , TYPE_STRING ) ;
//---
switch ( exp_param [ k ] . type )
{
case TYPE_BOOL :
exp_param [ k ] . integer_value = parametro [ " value " ] . ToInt ( 0 ) ;
break ;
case TYPE_CHAR :
exp_param [ k ] . integer_value = parametro [ " value " ] . ToInt ( 0 ) ;
break ;
case TYPE_UCHAR :
exp_param [ k ] . integer_value = parametro [ " value " ] . ToInt ( 0 ) ;
break ;
case TYPE_SHORT :
exp_param [ k ] . integer_value = parametro [ " value " ] . ToInt ( 0 ) ;
break ;
case TYPE_USHORT :
exp_param [ k ] . integer_value = parametro [ " value " ] . ToInt ( 0 ) ;
break ;
case TYPE_COLOR :
exp_param [ k ] . integer_value = long ( color ( parametro [ " value " ] . ToString ( " " ) ) ) ;
break ;
case TYPE_INT :
exp_param [ k ] . integer_value = parametro [ " value " ] . ToInt ( 0 ) ;
break ;
case TYPE_UINT :
exp_param [ k ] . integer_value = parametro [ " value " ] . ToInt ( 0 ) ;
break ;
case TYPE_DATETIME :
exp_param [ k ] . integer_value = long ( datetime ( parametro [ " value " ] . ToString ( " 0 " ) ) ) ;
break ;
case TYPE_LONG :
case TYPE_ULONG :
exp_param [ k ] . integer_value = parametro [ " value " ] . ToInt ( 0 ) ;
break ;
case TYPE_FLOAT :
exp_param [ k ] . double_value = parametro [ " value " ] . ToDouble ( 0.00 ) ;
break ;
case TYPE_DOUBLE :
exp_param [ k ] . double_value = parametro [ " value " ] . ToDouble ( 0.00 ) ;
break ;
case TYPE_STRING :
exp_param [ k ] . string_value = parametro [ " value " ] . ToString ( " " ) ;
break ;
default :
exp_param [ k ] . string_value = parametro [ " value " ] . ToString ( " " ) ;
break ;
}
k + + ;
//---
it . Next ( ) ;
2026-04-28 10:48:57 -05:00
}
}
//---
if ( ! EXPERT : : Run ( chart_id , exp_param , EXPERT : : FlagsPermisosStrToFlags ( param [ " run_flags " ] . ToString ( ) , ' | ' ) ) )
{
2026-04-29 21:15:35 -05:00
res = " { \" ok \" :false, \" error \" : \" Error run EA, view logs.. \" } " ;
2026-04-28 08:52:21 -05:00
}
else
{
2026-04-29 21:15:35 -05:00
res = StringFormat ( " { \" ok \" :true, \" result \" : \" EA successfully launched on chart with chart id = %I64d \" } " , chart_id ) ;
2026-04-28 08:52:21 -05:00
}
}
2026-04-28 10:48:57 -05:00
2026-04-27 22:49:28 -05:00
//+------------------------------------------------------------------+
2026-04-28 10:48:57 -05:00
//| |
//+------------------------------------------------------------------+
class CMcpFunctionCompile : public CMcpFunction
{
public :
CMcpFunctionCompile ( void ) : CMcpFunction ( 0 , false , " compile_mql5 " ) { }
~ CMcpFunctionCompile ( void ) { }
// instruction = [avx, avx2, avx512]
void Run ( CJsonNode & param , string & res ) override final ;
} ;
//+------------------------------------------------------------------+
void CMcpFunctionCompile : : Run ( CJsonNode & param , string & res )
{
string out_log_path = " " ;
2026-04-28 21:48:06 -05:00
if ( ! CompileFileWithLogFile ( param [ " full_path_code " ] . ToString ( " " ) , out_log_path , ( int ) param [ " timeout_ms " ] . ToInt ( 60000 ) , param [ " instruction " ] . ToString ( " " ) , param [ " optimize " ] . ToBool ( true ) ) )
2026-04-28 10:48:57 -05:00
{
2026-04-29 21:15:35 -05:00
res = StringFormat ( " { \" ok \" :false, \" error \" : \" Error compile file, view experts logs, and compile log file = %s \" } " , out_log_path ) ;
2026-04-28 10:48:57 -05:00
}
else
{
2026-05-04 15:23:37 -05:00
res = StringFormat ( " { \" ok \" :true, \" result \" : \" Success compiling file, log file=(%s) \" } " , out_log_path ) ;
2026-04-28 10:48:57 -05:00
}
}
2026-06-30 13:04:20 -05:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CMcpFuncTesterRep : public CMcpFunction
{
private :
SINGLETESTERCACHE m_tst ;
CJsonBuilder m_builder ;
2026-06-30 16:58:14 -05:00
bool m_cached ;
2026-06-30 13:04:20 -05:00
public :
CMcpFuncTesterRep ( void ) : CMcpFunction ( 0 , false , " tester_reports " ) { }
~ CMcpFuncTesterRep ( void ) { }
void Run ( CJsonNode & param , string & res ) override final ;
} ;
//+------------------------------------------------------------------+
void CMcpFuncTesterRep : : Run ( CJsonNode & param , string & res )
{
2026-06-30 16:58:14 -05:00
// En caso no se haya caechado esto se ginora ahora en caso si este checado reivsamos si hay qeu forzar el load
if ( m_cached & & param [ " forze_reload " ] . ToBool ( false ) )
m_cached = false ;
// Solo recargamos si no esta cacheado..
if ( ! m_cached )
2026-06-30 13:04:20 -05:00
{
2026-06-30 16:58:14 -05:00
uchar data [ ] ;
if ( ! MTTESTER : : GetLastTstCache ( data ) )
{
res = " { \" ok \" :false, \" error \" : \" Error getting last tester cache \" } " ;
return ;
}
if ( ! m_tst . Load ( data ) )
{
res = " { \" ok \" :false, \" error \" : \" Error loading tester cache \" } " ;
return ;
}
m_cached = true ;
2026-06-30 13:04:20 -05:00
}
2026-06-30 16:58:14 -05:00
const ENUM_MCPFUNC_TESTER_GET mode = CEnumRegFullMt5Mcp : : GetValNoRef < ENUM_MCPFUNC_TESTER_GET > (
param [ " mode " ] . ToString ( " " ) , WRONG_VALUE ) ;
2026-06-30 13:04:20 -05:00
m_builder . Clear ( ) ;
2026-06-30 16:58:14 -05:00
switch ( mode )
2026-06-30 13:04:20 -05:00
{
2026-06-30 16:58:14 -05:00
case MCPFUNC_TESTER_GET_SUMMARY :
{
m_builder . Obj ( ) ;
m_builder . Key ( " ok " ) . Val ( true ) ;
m_builder . Key ( " result " ) . Obj ( ) ;
2026-07-01 12:07:37 -05:00
//--- Header
m_builder . Key ( " tst_file_name " ) . ValSNoRef ( m_tst . Header . name [ ] ) ;
m_builder . Key ( " expert_name " ) . ValSNoRef ( m_tst . Header . expert_name [ ] ) ;
m_builder . Key ( " expert_path " ) . ValSNoRef ( m_tst . Header . expert_path [ ] ) ;
m_builder . Key ( " server " ) . ValSNoRef ( m_tst . Header . server [ ] ) ;
m_builder . Key ( " version " ) . Val ( ( int ) m_tst . Header . version ) ;
m_builder . Key ( " copyright " ) . ValSNoRef ( m_tst . Header . copyright [ ] ) ;
m_builder . Key ( " msc_execution_time " ) . Val ( ( int ) m_tst . Header . msc_last ) ;
m_builder . Key ( " symbol " ) . ValSNoRef ( m_tst . Header . symbol [ ] ) ;
2026-06-30 16:58:14 -05:00
// --- ExpTradeSummarySingle ---
m_builder . Key ( " bars " ) . Val ( m_tst . Summary . bars ) ;
m_builder . Key ( " ticks " ) . Val ( m_tst . Summary . ticks ) ;
m_builder . Key ( " symbol " ) . ValSNoRef ( m_tst . Summary . symbol [ ] ) ;
m_builder . Key ( " initial_deposit " ) . Val ( m_tst . Summary . initial_deposit ) ;
m_builder . Key ( " withdrawal " ) . Val ( m_tst . Summary . withdrawal ) ;
m_builder . Key ( " profit " ) . Val ( m_tst . Summary . profit ) ;
m_builder . Key ( " grossprofit " ) . Val ( m_tst . Summary . grossprofit ) ;
m_builder . Key ( " grossloss " ) . Val ( m_tst . Summary . grossloss ) ;
m_builder . Key ( " maxprofit " ) . Val ( m_tst . Summary . maxprofit ) ;
m_builder . Key ( " minprofit " ) . Val ( m_tst . Summary . minprofit ) ;
m_builder . Key ( " conprofitmax " ) . Val ( m_tst . Summary . conprofitmax ) ;
m_builder . Key ( " maxconprofit " ) . Val ( m_tst . Summary . maxconprofit ) ;
m_builder . Key ( " conlossmax " ) . Val ( m_tst . Summary . conlossmax ) ;
m_builder . Key ( " maxconloss " ) . Val ( m_tst . Summary . maxconloss ) ;
m_builder . Key ( " balance_min " ) . Val ( m_tst . Summary . balance_min ) ;
m_builder . Key ( " maxdrawdown " ) . Val ( m_tst . Summary . maxdrawdown ) ;
m_builder . Key ( " drawdownpercent " ) . Val ( m_tst . Summary . drawdownpercent ) ;
m_builder . Key ( " reldrawdown " ) . Val ( m_tst . Summary . reldrawdown ) ;
m_builder . Key ( " reldrawdownpercent " ) . Val ( m_tst . Summary . reldrawdownpercent ) ;
m_builder . Key ( " equity_min " ) . Val ( m_tst . Summary . equity_min ) ;
m_builder . Key ( " maxdrawdown_e " ) . Val ( m_tst . Summary . maxdrawdown_e ) ;
m_builder . Key ( " drawdownpercent_e " ) . Val ( m_tst . Summary . drawdownpercent_e ) ;
m_builder . Key ( " reldrawdown_e " ) . Val ( m_tst . Summary . reldrawdown_e ) ;
m_builder . Key ( " reldrawdownpercnt_e " ) . Val ( m_tst . Summary . reldrawdownpercnt_e ) ;
m_builder . Key ( " expected_payoff " ) . Val ( m_tst . Summary . expected_payoff ) ;
m_builder . Key ( " profit_factor " ) . Val ( m_tst . Summary . profit_factor ) ;
m_builder . Key ( " recovery_factor " ) . Val ( m_tst . Summary . recovery_factor ) ;
m_builder . Key ( " sharpe_ratio " ) . Val ( m_tst . Summary . sharpe_ratio ) ;
m_builder . Key ( " margin_level " ) . Val ( m_tst . Summary . margin_level ) ;
m_builder . Key ( " custom_fitness " ) . Val ( m_tst . Summary . custom_fitness ) ;
m_builder . Key ( " deals " ) . Val ( m_tst . Summary . deals ) ;
m_builder . Key ( " trades " ) . Val ( m_tst . Summary . trades ) ;
m_builder . Key ( " profittrades " ) . Val ( m_tst . Summary . profittrades ) ;
m_builder . Key ( " losstrades " ) . Val ( m_tst . Summary . losstrades ) ;
m_builder . Key ( " shorttrades " ) . Val ( m_tst . Summary . shorttrades ) ;
m_builder . Key ( " longtrades " ) . Val ( m_tst . Summary . longtrades ) ;
m_builder . Key ( " winshorttrades " ) . Val ( m_tst . Summary . winshorttrades ) ;
m_builder . Key ( " winlongtrades " ) . Val ( m_tst . Summary . winlongtrades ) ;
m_builder . Key ( " conprofitmax_trades " ) . Val ( m_tst . Summary . conprofitmax_trades ) ;
m_builder . Key ( " maxconprofit_trades " ) . Val ( m_tst . Summary . maxconprofit_trades ) ;
m_builder . Key ( " conlossmax_trades " ) . Val ( m_tst . Summary . conlossmax_trades ) ;
m_builder . Key ( " maxconloss_trades " ) . Val ( m_tst . Summary . maxconloss_trades ) ;
m_builder . Key ( " avgconwinners " ) . Val ( m_tst . Summary . avgconwinners ) ;
m_builder . Key ( " avgconloosers " ) . Val ( m_tst . Summary . avgconloosers ) ;
// --- ExpTradeSummaryExt ---
m_builder . Key ( " ghpr " ) . Val ( m_tst . Summary . ghpr ) ;
m_builder . Key ( " ghprpercent " ) . Val ( m_tst . Summary . ghprpercent ) ;
m_builder . Key ( " ahpr " ) . Val ( m_tst . Summary . ahpr ) ;
m_builder . Key ( " ahprpercent " ) . Val ( m_tst . Summary . ahprpercent ) ;
m_builder . Key ( " zscore " ) . Val ( m_tst . Summary . zscore ) ;
m_builder . Key ( " zscorepercent " ) . Val ( m_tst . Summary . zscorepercent ) ;
m_builder . Key ( " lrcorr " ) . Val ( m_tst . Summary . lrcorr ) ;
m_builder . Key ( " lrstderror " ) . Val ( m_tst . Summary . lrstderror ) ;
m_builder . Key ( " symbols " ) . Val ( ( int ) m_tst . Summary . symbols ) ;
m_builder . Key ( " corr_prf_mfe " ) . Val ( m_tst . Summary . corr_prf_mfe ) ;
m_builder . Key ( " corr_prf_mae " ) . Val ( m_tst . Summary . corr_prf_mae ) ;
m_builder . Key ( " corr_mfe_mae " ) . Val ( m_tst . Summary . corr_mfe_mae ) ;
m_builder . Key ( " mfe_a " ) . Val ( m_tst . Summary . mfe_a ) ;
m_builder . Key ( " mfe_b " ) . Val ( m_tst . Summary . mfe_b ) ;
m_builder . Key ( " mae_a " ) . Val ( m_tst . Summary . mae_a ) ;
m_builder . Key ( " mae_b " ) . Val ( m_tst . Summary . mae_b ) ;
m_builder . Key ( " holding_time_min " ) . Val ( ( long ) m_tst . Summary . holding_time_min ) ;
m_builder . Key ( " holding_time_max " ) . Val ( ( long ) m_tst . Summary . holding_time_max ) ;
m_builder . Key ( " holding_time_avr " ) . Val ( ( long ) m_tst . Summary . holding_time_avr ) ;
m_builder . Key ( " in_commission " ) . Val ( m_tst . Summary . in_commission ) ;
2026-07-01 12:07:37 -05:00
//--- Tiempo
2026-06-30 16:58:14 -05:00
// --- Arrays de distribucion ---
m_builder . Key ( " in_per_hours " ) . Arr ( ) ;
for ( int i = 0 ; i < 24 ; i + + )
m_builder . Val ( ( int ) m_tst . Summary . in_per_hours [ i ] ) ;
m_builder . EndArr ( ) ;
m_builder . Key ( " in_per_week_days " ) . Arr ( ) ;
for ( int i = 0 ; i < 7 ; i + + )
m_builder . Val ( ( int ) m_tst . Summary . in_per_week_days [ i ] ) ;
m_builder . EndArr ( ) ;
m_builder . Key ( " in_per_months " ) . Arr ( ) ;
for ( int i = 0 ; i < 12 ; i + + )
m_builder . Val ( ( int ) m_tst . Summary . in_per_months [ i ] ) ;
m_builder . EndArr ( ) ;
m_builder . Key ( " out_per_hours " ) . Arr ( ) ;
for ( int i = 0 ; i < 24 ; i + + )
{
m_builder . Arr ( ) ;
m_builder . Val ( m_tst . Summary . out_per_hours [ i ] [ 0 ] ) ;
m_builder . Val ( m_tst . Summary . out_per_hours [ i ] [ 1 ] ) ;
m_builder . EndArr ( ) ;
}
m_builder . EndArr ( ) ;
m_builder . Key ( " out_per_week_days " ) . Arr ( ) ;
for ( int i = 0 ; i < 7 ; i + + )
{
m_builder . Arr ( ) ;
m_builder . Val ( m_tst . Summary . out_per_week_days [ i ] [ 0 ] ) ;
m_builder . Val ( m_tst . Summary . out_per_week_days [ i ] [ 1 ] ) ;
m_builder . EndArr ( ) ;
}
m_builder . EndArr ( ) ;
m_builder . Key ( " out_per_months " ) . Arr ( ) ;
for ( int i = 0 ; i < 12 ; i + + )
{
m_builder . Arr ( ) ;
m_builder . Val ( m_tst . Summary . out_per_months [ i ] [ 0 ] ) ;
m_builder . Val ( m_tst . Summary . out_per_months [ i ] [ 1 ] ) ;
m_builder . EndArr ( ) ;
}
m_builder . EndArr ( ) ;
m_builder . EndObj ( ) ;
m_builder . EndObj ( ) ;
break ;
}
2026-06-30 13:04:20 -05:00
2026-06-30 16:58:14 -05:00
case MCPFUNC_TESTER_GET_BALANCE_HISTORY :
{
double balance [ ] ;
const int s = ( int ) param [ " start " ] . ToInt ( 0 ) ;
const int k = m_tst . GetBalance ( balance , param [ " date_start " ] . ToInt ( 0 ) ,
param [ " date_end " ] . ToInt ( 0 ) ,
param [ " incluyed_deposit " ] . ToBool ( true ) ) ;
const int t = fmin ( ( int ) param [ " count " ] . ToInt ( 1 ) , k ) ;
if ( t ! = -1 )
{
m_builder . Obj ( ) ;
m_builder . Key ( " ok " ) . Val ( true ) ;
m_builder . Key ( " result " ) . Arr ( ) ;
for ( int i = s ; i < t ; i + + )
{
m_builder . Val ( balance [ i ] ) ;
}
m_builder . EndArr ( ) . EndObj ( ) ;
}
else
{
m_builder . Obj ( ) ;
m_builder . Key ( " ok " ) . Val ( false ) ;
m_builder . Key ( " result " ) . ValS ( " Failure to obtain balance history. " ) ;
m_builder . EndObj ( ) ;
}
break ;
}
2026-06-30 13:04:20 -05:00
2026-06-30 16:58:14 -05:00
case MCPFUNC_TESTER_GET_EQUITY_HISTORY :
{
double eq [ ] ;
const int s = ( int ) param [ " start " ] . ToInt ( 0 ) ;
const int k = m_tst . GetEquity ( eq , param [ " date_start " ] . ToInt ( 0 ) ,
param [ " date_end " ] . ToInt ( 0 ) ,
param [ " incluyed_deposit " ] . ToBool ( true ) ) ;
const int t = fmin ( ( int ) param [ " count " ] . ToInt ( 1 ) , k ) ;
if ( t ! = -1 )
{
m_builder . Obj ( ) ;
m_builder . Key ( " ok " ) . Val ( true ) ;
m_builder . Key ( " result " ) . Arr ( ) ;
for ( int i = s ; i < t ; i + + )
{
m_builder . Val ( eq [ i ] ) ;
}
m_builder . EndArr ( ) . EndObj ( ) ;
}
else
{
m_builder . Obj ( ) ;
m_builder . Key ( " ok " ) . Val ( false ) ;
m_builder . Key ( " result " ) . ValS ( " Failure to obtain equity history. " ) ;
m_builder . EndObj ( ) ;
}
break ;
}
case MCPFUNC_TESTER_GET_DEALS_HISTORY :
{
2026-06-30 13:04:20 -05:00
2026-06-30 16:58:14 -05:00
const int s = ( int ) param [ " start " ] . ToInt ( 0 ) ;
const int t = fmin ( ( int ) param [ " count " ] . ToInt ( 1 ) , ArraySize ( m_tst . Deals ) ) ;
m_builder . Obj ( ) ;
m_builder . Key ( " ok " ) . Val ( true ) ;
m_builder . Key ( " result " ) . Arr ( ) ;
for ( int i = s ; i < t ; i + + )
{
m_builder . Obj ( ) ;
m_builder . Key ( " deal " ) . Val ( ( long ) m_tst . Deals [ i ] . deal ) ;
m_builder . Key ( " order " ) . Val ( ( long ) m_tst . Deals [ i ] . order ) ;
m_builder . Key ( " position_id " ) . Val ( ( long ) m_tst . Deals [ i ] . position_id ) ;
m_builder . Key ( " time " ) . Val ( ( long ) m_tst . Deals [ i ] . time_create ) ;
m_builder . Key ( " symbol " ) . Val ( ( int ) m_tst . Deals [ i ] . symbol [ ] ) ;
m_builder . Key ( " action " ) . Val ( ( int ) m_tst . Deals [ i ] . action ) ;
m_builder . Key ( " entry " ) . Val ( ( int ) m_tst . Deals [ i ] . entry ) ;
m_builder . Key ( " price_open " ) . Val ( m_tst . Deals [ i ] . price_open ) ;
m_builder . Key ( " price_close " ) . Val ( m_tst . Deals [ i ] . price_close ) ;
m_builder . Key ( " sl " ) . Val ( m_tst . Deals [ i ] . sl ) ;
m_builder . Key ( " tp " ) . Val ( m_tst . Deals [ i ] . tp ) ;
m_builder . Key ( " volume " ) . Val ( ( double ) m_tst . Deals [ i ] . volume / ( m_tst . Deals [ i ] . contract_size > 0 ? m_tst . Deals [ i ] . contract_size * 1000 : 1e8 ) ) ;
m_builder . Key ( " profit " ) . Val ( m_tst . Deals [ i ] . profit ) ;
m_builder . Key ( " commission " ) . Val ( m_tst . Deals [ i ] . commission ) ;
m_builder . Key ( " storage " ) . Val ( m_tst . Deals [ i ] . storage ) ;
m_builder . Key ( " comment " ) . ValSNoRef ( m_tst . Deals [ i ] . comment [ ] ) ;
m_builder . EndObj ( ) ;
}
m_builder . EndArr ( ) . EndObj ( ) ;
break ;
}
default :
{
m_builder . Obj ( ) ;
m_builder . Key ( " ok " ) . Val ( false ) ;
m_builder . Key ( " result " ) . ValS ( " Invalid mode " ) ;
m_builder . EndObj ( ) ;
break ;
}
}
2026-06-30 13:04:20 -05:00
res = m_builder . Build ( ) ;
}
2026-06-03 20:39:25 -05:00
} // namespace TSN
2026-06-30 16:58:14 -05:00
2026-06-30 10:46:22 -05:00
# endif // FULLMT5MCPBYLEO_SRC_COMPLEX_COMPLEX_MQH